From 6b9c5348f3dcee99be004b592fe912ec397da605 Mon Sep 17 00:00:00 2001 From: Dialpuri Date: Sat, 15 Jun 2024 09:10:39 +0100 Subject: [PATCH 01/24] Updated gemmi and clipper-gemmi versions --- CMakeLists.txt | 11 +- build.sh | 8 +- clipper/gemmi/CMakeLists.txt | 18 +- clipper/minimol/CMakeLists.txt | 19 +- src/privateer/cpp/clipper-glyco.h | 2 +- src/privateer/cpp/privateer-bind.cpp | 7 +- src/privateer/cpp/privateer-interactions.cpp | 140 +- src/privateer/cpp/privateer-interactions.h | 2 +- src/privateer/cpp/privateer-json.h | 623 +- .../third-party/gemmi_compilation_unit.cpp | 26 +- .../cpp/third-party/simdjson/simdjson.cpp | 43387 ++++++++ .../cpp/third-party/simdjson/simdjson.h | 88545 ++++++++++++++++ webapp/src/wasm/privateer.js | 2 +- webapp/src/wasm/privateer.wasm | Bin 1875795 -> 1947360 bytes 14 files changed, 132415 insertions(+), 375 deletions(-) create mode 100644 src/privateer/cpp/third-party/simdjson/simdjson.cpp create mode 100644 src/privateer/cpp/third-party/simdjson/simdjson.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 08efa8e1d..bd9df6cf8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.12) project(privateer VERSION 0.5 LANGUAGES C CXX) SET(PRIVATEER_CC_FLAGS "-O2 -w") -SET(PRIVATEER_CXX_FLAGS "-O2 -w -fwasm-exceptions -I${CMAKE_INSTALL_PREFIX}/include") +SET(PRIVATEER_CXX_FLAGS "-O2 -w -fwasm-exceptions -I${CMAKE_INSTALL_PREFIX}/include") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PRIVATEER_CC_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PRIVATEER_CXX_FLAGS} ") @@ -25,7 +25,8 @@ set(CLIBDENV $ENV{CLIBD}) # add_subdirectory(checkout/zlib) if (MODE STREQUAL "TESTING") -else() +else() + add_subdirectory(gemmi) add_subdirectory(ccp4) add_subdirectory(rfftw) add_subdirectory(fftw) @@ -57,6 +58,8 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} checkout/zlib ${PRIVATEER_SOURCE_DIR}/cpp ${PRIVATEER_SOURCE_DIR}/cpp/pybind11 + ${PRIVATEER_SOURCE_DIR}/cpp/third-party/simdjson/ + # checkout/ccp4srs ) @@ -113,6 +116,7 @@ add_library(privateer_lib # ${PRIVATEER_SOURCE_DIR}/cpp/pybind11/privateer-pymodelling.cpp ${PRIVATEER_SOURCE_DIR}/cpp/clipper-glyco_data.cpp ${PRIVATEER_SOURCE_DIR}/cpp/privateer-bind.cpp + ${PRIVATEER_SOURCE_DIR}/cpp/third-party/simdjson/simdjson.cpp ) @@ -122,7 +126,7 @@ add_executable(privateer_exec ${PRIVATEER_SOURCE_DIR}/cpp/privateer-bind.cpp) set_target_properties (privateer_exec PROPERTIES OUTPUT_NAME privateer ) -target_link_options(privateer_exec PRIVATE --preload-file data/linkage_torsions@/ -sDEMANGLE_SUPPORT=1 -sASSERTIONS=2 -fexceptions -sALLOW_MEMORY_GROWTH=1 --bind -sFORCE_FILESYSTEM=1 -sMODULARIZE=1 -sEXPORT_NAME=privateer_module -sEXPORTED_RUNTIME_METHODS=['FS'] -sMODULARIZE=1 -sEXPORT_ES6=1 ) +target_link_options(privateer_exec PRIVATE --preload-file data/linkage_torsions@/ -sDEMANGLE_SUPPORT=0 -sEXIT_RUNTIME=1 -sASSERTIONS=2 -fexceptions -sALLOW_MEMORY_GROWTH=1 --bind -sFORCE_FILESYSTEM=1 -sMODULARIZE=1 -sEXPORT_NAME=privateer_module -sEXPORTED_RUNTIME_METHODS=['FS'] -sMODULARIZE=1 -sEXPORT_ES6=1 ) target_link_directories(privateer_exec PUBLIC @@ -176,6 +180,7 @@ ${PRIVATEER_SOURCE_DIR}/cpp/privateer-json.h ${PRIVATEER_SOURCE_DIR}/cpp/clipper-glyco.h ${PRIVATEER_SOURCE_DIR}/cpp/privateer-parallelism.h ${PRIVATEER_SOURCE_DIR}/cpp/privateer-cryo_em.h +${PRIVATEER_SOURCE_DIR}/cpp/third-party/simdjson/simdjson.h ) set_target_properties(privateer_exec PROPERTIES PUBLIC_HEADER "${privateer_HEADERS}") diff --git a/build.sh b/build.sh index bc00d9f41..3202bf72e 100755 --- a/build.sh +++ b/build.sh @@ -1,7 +1,7 @@ -source /Applications/ccp4-8.0/bin/ccp4.setup-sh -source ~/Development/privateer/emsdk/emsdk_env.sh -# source /opt/xtal/ccp4-8.0/bin/ccp4.setup-sh -# source ~/dev/privateer_wasm/emsdk/emsdk_env.sh +#source /Applications/ccp4-8.0/bin/ccp4.setup-sh +#source ~/Development/privateer/emsdk/emsdk_env.sh + source /opt/xtal/ccp4-8.0/bin/ccp4.setup-sh + source ~/dev/privateer_wasm/emsdk/emsdk_env.sh emcmake cmake . emmake make -j diff --git a/clipper/gemmi/CMakeLists.txt b/clipper/gemmi/CMakeLists.txt index 3d30ca439..434de0ced 100644 --- a/clipper/gemmi/CMakeLists.txt +++ b/clipper/gemmi/CMakeLists.txt @@ -1,15 +1,27 @@ project(clipper-gemmi) -add_library(clipper-gemmi STATIC -../../checkout/clipper/clipper/gemmi/clipper_gemmi.cpp) +add_library(clipper-gemmi STATIC +../../checkout/clipper/clipper/gemmi/clipper_gemmi.cpp +../../checkout/clipper/clipper/gemmi/clipper_gemmi_model.cpp +) +#../../checkout/clipper/clipper/gemmi/clipper_gemmi_map.cpp + target_include_directories(clipper-gemmi PRIVATE ../../checkout/clipper/clipper ../../checkout/clipper/ ../../checkout/gemmi/include) +target_link_directories(clipper-gemmi PRIVATE + ../../gemmi + ) + + target_link_libraries(clipper-gemmi PRIVATE gemmi_cpp) + set(clipper-gemmi_HEADERS ${CMAKE_SOURCE_DIR}/checkout/clipper/clipper/gemmi/clipper_gemmi.h +# ${CMAKE_SOURCE_DIR}/checkout/clipper/clipper/gemmi/clipper_gemmi_map.h +${CMAKE_SOURCE_DIR}/checkout/clipper/clipper/gemmi/clipper_gemmi_model.h ) target_compile_options(clipper-gemmi PUBLIC "-DFFTW_ENABLE_FLOAT") @@ -18,4 +30,4 @@ set_target_properties(clipper-gemmi PROPERTIES PUBLIC_HEADER "${clipper-gemmi_HE install(TARGETS clipper-gemmi LIBRARY DESTINATION lib PUBLIC_HEADER DESTINATION include/clipper/gemmi -) +) \ No newline at end of file diff --git a/clipper/minimol/CMakeLists.txt b/clipper/minimol/CMakeLists.txt index b8a6e0bbd..3614aa444 100644 --- a/clipper/minimol/CMakeLists.txt +++ b/clipper/minimol/CMakeLists.txt @@ -4,18 +4,29 @@ add_library(clipper-minimol STATIC ../../checkout/clipper/clipper/minimol/container_minimol.cpp ../../checkout/clipper/clipper/minimol/minimol.cpp ../../checkout/clipper/clipper/minimol/minimol_data.cpp -../../checkout/clipper/clipper/minimol/minimol_io.cpp +../../checkout/clipper/clipper/minimol/minimol_io_gemmi.cpp +../../checkout/clipper/clipper/minimol/minimol_io_mmdb.cpp ../../checkout/clipper/clipper/minimol/minimol_seq.cpp ../../checkout/clipper/clipper/minimol/minimol_utils.cpp ) -target_include_directories(clipper-minimol PRIVATE ../../checkout/mmdb2/ ../../checkout/clipper ../../checkout/clipper/clipper ../../checkout/fftw-2.1.5/fftw ../../checkout/fftw-2.1.5/rfftw ../../checkout/gemmi/include ../../dependencies/gemmi/include/gemmi) +target_include_directories(clipper-minimol PRIVATE + ${CMAKE_SOURCE_DIR}/install/include/ + ${CMAKE_SOURCE_DIR}/install/include/gemmi + ../../checkout/mmdb2/ . + ./../checkout/clipper + ../../checkout/fftw-2.1.5/fftw + ../../checkout/fftw-2.1.5/rfftw + ../../checkout/gemmi/include + + ) set(clipper-minimol_HEADERS ${CMAKE_SOURCE_DIR}/checkout/clipper//clipper/minimol/minimol_data.h ${CMAKE_SOURCE_DIR}/checkout/clipper//clipper/minimol/minimol.h ${CMAKE_SOURCE_DIR}/checkout/clipper//clipper/minimol/container_minimol.h -${CMAKE_SOURCE_DIR}/checkout/clipper//clipper/minimol/minimol_io.h +${CMAKE_SOURCE_DIR}/checkout/clipper//clipper/minimol/minimol_io_gemmi.h +${CMAKE_SOURCE_DIR}/checkout/clipper//clipper/minimol/minimol_io_mmdb.h ${CMAKE_SOURCE_DIR}/checkout/clipper//clipper/minimol/minimol_seq.h ${CMAKE_SOURCE_DIR}/checkout/clipper//clipper/minimol/minimol_utils.h ${CMAKE_SOURCE_DIR}/checkout/clipper//clipper/clipper-minimol.h @@ -27,4 +38,4 @@ set_target_properties(clipper-minimol PROPERTIES PUBLIC_HEADER "${clipper-minimo install(TARGETS clipper-minimol LIBRARY DESTINATION lib PUBLIC_HEADER DESTINATION include/clipper/minimol -) +) \ No newline at end of file diff --git a/src/privateer/cpp/clipper-glyco.h b/src/privateer/cpp/clipper-glyco.h index 5e50851cd..54392bda5 100644 --- a/src/privateer/cpp/clipper-glyco.h +++ b/src/privateer/cpp/clipper-glyco.h @@ -39,7 +39,7 @@ inline bool altconf_compatible ( char m1, char m2 ) // else // return true; // would cause an endless while loop in is_stereocentre() when there would be altconfs like 'C' - if(( m1 == m2)) + if( m1 == m2) return true; else if((m1 == ' ' && m2 != ' ') || (m1 != ' ' && m2 == ' ')) return true; diff --git a/src/privateer/cpp/privateer-bind.cpp b/src/privateer/cpp/privateer-bind.cpp index 2da8699e4..d1ea03abe 100644 --- a/src/privateer/cpp/privateer-bind.cpp +++ b/src/privateer/cpp/privateer-bind.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "clipper-glyco.h" @@ -56,9 +57,9 @@ clipper::MiniMol read_molecule(const std::string &file, const std::string &name) structure.spacegroup_hm = "P 1"; } - clipper::GEMMIFile gemmi_file; - clipper::GemmiStructure *gemmi_structure = &gemmi_file; - gemmi_structure->structure_ = structure; + clipper::GEMMIfile gemmi_file; + clipper::GemmiStructure gemmi_structure(structure); + gemmi_file.set_gemmi_structure(gemmi_structure); clipper::MiniMol mol; gemmi_file.import_minimol(mol); diff --git a/src/privateer/cpp/privateer-interactions.cpp b/src/privateer/cpp/privateer-interactions.cpp index 4835d0a5d..3ec5b7bf0 100644 --- a/src/privateer/cpp/privateer-interactions.cpp +++ b/src/privateer/cpp/privateer-interactions.cpp @@ -16,76 +16,76 @@ namespace privateer void hydrogenate_input_model(std::string input_model, std::string output_path) { - std::cout << "Hydrogenating '" << input_model << "' using project-gemmi/gemmi third party library." << std::endl; - try - { - std::string output; - if (output == "undefined") - output = "hydrogenated_input_model.pdb"; - else - output = output_path; - gemmi::HydrogenChange h_change = gemmi::HydrogenChange::ReAdd; - std::string monomer_dir = privateer::restraints::check_monlib_access(); - if (monomer_dir.empty()) - throw std::runtime_error("Failed to locate $CLIBD_MON. Have ccp4 env variables been sourced?"); - - gemmi::Structure st = gemmi::read_structure_file(input_model); - - if (st.models.empty() || st.models[0].chains.empty()) - throw std::runtime_error("No atoms in the input file."); - - gemmi::setup_entities(st); - size_t initial_h = 0; - initial_h = gemmi::count_hydrogen_sites(st); - - std::vector res_names = st.models[0].get_all_residue_names(); - - std::printf("Reading %zu monomers and all links from %s\n", - res_names.size(), input_model.c_str()); - - gemmi::MonLib monlib = gemmi::read_monomer_lib(monomer_dir, res_names, - gemmi::cif::read_file); - - for (size_t i = 0; i != st.models.size(); ++i) - gemmi::prepare_topology(st, monlib, i, h_change, false); - - std::printf("Hydrogen site count: %zu in input, %zu in output.\n", - initial_h, gemmi::count_hydrogen_sites(st)); - - // Clean up the H atoms that were placed at (0.00, 0.00, 0.00) - for (gemmi::Model &model : st.models) - for (gemmi::Chain &chain : model.chains) - for (gemmi::Residue &res : chain.residues) - { - std::vector modified_atoms; - for (gemmi::Atom &atom : res.atoms) - { - if (atom.is_hydrogen()) - { - if (atom.pos.x == 0 && atom.pos.y == 0 && atom.pos.z == 0 && atom.occ == 0) - continue; - else - modified_atoms.push_back(atom); - } - else - { - modified_atoms.push_back(atom); - } - } - res.atoms = modified_atoms; - } - - std::printf("Writing coordinates to %s\n", output.c_str()); - gemmi::Ofstream os(output, &std::cout); - gemmi::write_pdb(st, os.ref()); - - std::cout << input_model << " was successfully hydrogenated!" << std::endl; - } - catch (std::exception &e) - { - std::fprintf(stderr, "ERROR: %s\n", e.what()); - // throw stderr; - } + // std::cout << "Hydrogenating '" << input_model << "' using project-gemmi/gemmi third party library." << std::endl; + // try + // { + // std::string output; + // if (output == "undefined") + // output = "hydrogenated_input_model.pdb"; + // else + // output = output_path; + // gemmi::HydrogenChange h_change = gemmi::HydrogenChange::ReAdd; + // std::string monomer_dir = privateer::restraints::check_monlib_access(); + // if (monomer_dir.empty()) + // throw std::runtime_error("Failed to locate $CLIBD_MON. Have ccp4 env variables been sourced?"); + + // gemmi::Structure st = gemmi::read_structure_file(input_model); + + // if (st.models.empty() || st.models[0].chains.empty()) + // throw std::runtime_error("No atoms in the input file."); + + // gemmi::setup_entities(st); + // size_t initial_h = 0; + // initial_h = gemmi::count_hydrogen_sites(st); + + // std::vector res_names = st.models[0].get_all_residue_names(); + + // std::printf("Reading %zu monomers and all links from %s\n", + // res_names.size(), input_model.c_str()); + + // gemmi::MonLib monlib = gemmi::read_monomer_lib(monomer_dir, res_names, + // gemmi::cif::read_file); + + // for (size_t i = 0; i != st.models.size(); ++i) + // gemmi::prepare_topology(st, monlib, i, h_change, false); + + // std::printf("Hydrogen site count: %zu in input, %zu in output.\n", + // initial_h, gemmi::count_hydrogen_sites(st)); + + // // Clean up the H atoms that were placed at (0.00, 0.00, 0.00) + // for (gemmi::Model &model : st.models) + // for (gemmi::Chain &chain : model.chains) + // for (gemmi::Residue &res : chain.residues) + // { + // std::vector modified_atoms; + // for (gemmi::Atom &atom : res.atoms) + // { + // if (atom.is_hydrogen()) + // { + // if (atom.pos.x == 0 && atom.pos.y == 0 && atom.pos.z == 0 && atom.occ == 0) + // continue; + // else + // modified_atoms.push_back(atom); + // } + // else + // { + // modified_atoms.push_back(atom); + // } + // } + // res.atoms = modified_atoms; + // } + + // std::printf("Writing coordinates to %s\n", output.c_str()); + // gemmi::Ofstream os(output, &std::cout); + // gemmi::write_pdb(st, os.ref()); + + // std::cout << input_model << " was successfully hydrogenated!" << std::endl; + // } + // catch (std::exception &e) + // { + // std::fprintf(stderr, "ERROR: %s\n", e.what()); + // // throw stderr; + // } } privateer::interactions::CHPiBondsParser::CHPiBondsParser(std::string &input_model, std::string output_path, std::string algorithm) diff --git a/src/privateer/cpp/privateer-interactions.h b/src/privateer/cpp/privateer-interactions.h index 7f052ffe9..0a6cc54b8 100644 --- a/src/privateer/cpp/privateer-interactions.h +++ b/src/privateer/cpp/privateer-interactions.h @@ -18,7 +18,7 @@ #include "gemmi/mmread.hpp" #include "gemmi/monlib.hpp" -#include "gemmi/placeh.hpp" +// #include "gemmi/placeh.hpp" #include "gemmi/fstream.hpp" #include "gemmi/cif.hpp" #include "gemmi/to_pdb.hpp" diff --git a/src/privateer/cpp/privateer-json.h b/src/privateer/cpp/privateer-json.h index ad84a26c2..05245eb5a 100644 --- a/src/privateer/cpp/privateer-json.h +++ b/src/privateer/cpp/privateer-json.h @@ -25,6 +25,9 @@ #include "utf.hpp" #endif +#include "simdjson.h" + + namespace privateer { namespace json @@ -191,7 +194,7 @@ namespace privateer else { env = std::getenv("CLIBD"); - path_copy = env + "/privateer_glycomics_database.json"; + path_copy = env + "/privateer_data/glycomics/privateer_glycomics_database.json"; } } @@ -219,7 +222,8 @@ namespace privateer std::vector> torsions; // .first = Phi, .second = Psi }; - inline void generate_torsions_database(std::vector& torsions_database, const sajson::document& jsonObject) + + inline void generate_torsions_database(std::vector& torsions_database, const sajson::document& jsonObject) { sajson::value root = jsonObject.get_root(); if (root.get_type() != sajson::TYPE_OBJECT) @@ -316,26 +320,26 @@ namespace privateer if(individual_torsions.get_type() != sajson::TYPE_OBJECT) fail("Expected TYPE_OBJECT, got " + json_type_as_string(individual_torsions.get_type())); - float Psi = -42069, Phi = -42069; - for(size_t n = 0; n != individual_torsions.get_length(); n++) - { - if(individual_torsions.get_object_key(n).as_string() == "Phi") - { - if (individual_torsions.get_object_value(n).get_type() != sajson::TYPE_DOUBLE) - fail("Expected TYPE_STRING, got " + json_type_as_string(individual_torsions.get_object_value(n).get_type())); - - Phi = individual_torsions.get_object_value(n).get_number_value(); - } - else if(individual_torsions.get_object_key(n).as_string() == "Psi") - { - if (individual_torsions.get_object_value(n).get_type() != sajson::TYPE_DOUBLE) - fail("Expected TYPE_STRING, got " + json_type_as_string(individual_torsions.get_object_value(j).get_type())); - - Psi = individual_torsions.get_object_value(n).get_number_value(); - } - } - - torsion_container.push_back(std::make_pair(Phi, Psi)); +// float Psi = -42069, Phi = -42069; +// for(size_t n = 0; n != individual_torsions.get_length(); n++) +// { +// if(individual_torsions.get_object_key(n).as_string() == "Phi") +// { +// if (individual_torsions.get_object_value(n).get_type() != sajson::TYPE_DOUBLE) +// fail("Expected TYPE_STRING, got " + json_type_as_string(individual_torsions.get_object_value(n).get_type())); +// +// Phi = individual_torsions.get_object_value(n).get_number_value(); +// } +// else if(individual_torsions.get_object_key(n).as_string() == "Psi") +// { +// if (individual_torsions.get_object_value(n).get_type() != sajson::TYPE_DOUBLE) +// fail("Expected TYPE_STRING, got " + json_type_as_string(individual_torsions.get_object_value(j).get_type())); +// +// Psi = individual_torsions.get_object_value(n).get_number_value(); +// } +// } + +// torsion_container.push_back(std::make_pair(Phi, Psi)); } temp.torsions = torsion_container; @@ -376,7 +380,7 @@ namespace privateer else { env = std::getenv("CLIBD"); - path_copy = env + "/privateer_torsion_database.json"; + path_copy = env + "/privateer_data/linkage_torsions/privateer_torsion_database.json"; } } @@ -416,269 +420,342 @@ namespace privateer TorsionsZScoreStatistics statistics; }; - inline void generate_torsions_zscore_database(GlobalTorsionZScore& global_torsion_z_score, const sajson::document& jsonObject) - { - - std::vector torsions_zscore_database; - TorsionsZScoreStatistics temp_statistics; - - sajson::value root = jsonObject.get_root(); - if (root.get_type() != sajson::TYPE_OBJECT) - fail("not Privateer Torsions Z-Score Database JSON file"); - std::string database_name_key = root.get_object_key(1).as_string(); - std::string database_name_value = root.get_object_value(1).as_string(); - if (database_name_key != "database_name" || database_name_value != "torsions_z_score_database") - fail("not Torsions Database JSON file - should be \"database_name\": \"torsions_z_score_database\", instead received \"" + database_name_key + "\": \"" + database_name_value + "\"\n"); - - std::string database_last_update = root.get_object_value(2).as_string(); - - sajson::value entries_array = root.get_object_value(0); - std::string entries_name = root.get_object_key(0).as_string(); - if (entries_array.get_type() != sajson::TYPE_OBJECT || entries_name != "data") - fail("Expected TYPE_OBJECT, got " + json_type_as_string(entries_array.get_type()) + " with key value equal to \"data\", instead !!!got: \"" + entries_name + "\""); - - for (size_t data_index = 0; data_index != entries_array.get_length(); data_index++) { - - sajson::value data_array = entries_array.get_object_value(data_index); - std::string data_key = entries_array.get_object_key(data_index).as_string(); - - if (data_key == "linkage_data") { - - for (size_t linkage_data_index = 0; linkage_data_index != data_array.get_length(); ++linkage_data_index) - { - sajson::value entry = data_array.get_array_element(linkage_data_index); - if (entry.get_type() != sajson::TYPE_OBJECT) - fail("Expected TYPE_OBJECT, got " + json_type_as_string(entry.get_type())); - - TorsionsZScoreDatabase temp; - for(size_t donor_index = 0; donor_index != entry.get_length(); donor_index++) - { - if(entry.get_object_key(donor_index).as_string() == "donor") - { - if (entry.get_object_value(donor_index).get_type() != sajson::TYPE_STRING) - fail("Expected TYPE_STRING, got " + json_type_as_string(entry.get_object_value(donor_index).get_type())); - temp.donor_sugar = entry.get_object_value(donor_index).as_string(); - } - else if(entry.get_object_key(donor_index).as_string() == "acceptor") - { - sajson::value acceptor_array = entry.get_object_value(donor_index); - if (acceptor_array.get_type() != sajson::TYPE_ARRAY) - fail("Expected TYPE_ARRAY, got " + json_type_as_string(acceptor_array.get_type())); - - for(size_t acceptor_index = 0; acceptor_index != acceptor_array.get_length(); acceptor_index++) - { - sajson::value acceptor_object = acceptor_array.get_array_element(acceptor_index); - - if (acceptor_object.get_type() != sajson::TYPE_OBJECT) - fail("Expected TYPE_OBJECT, got " + json_type_as_string(acceptor_object.get_type())); + inline void generate_torsions_zscore_database_simd(GlobalTorsionZScore& torsions_database, const simdjson::ondemand::document) { - for(size_t acceptor_object_index = 0; acceptor_object_index != acceptor_object.get_length(); acceptor_object_index++) - { - if(acceptor_object.get_object_key(acceptor_object_index).as_string() == "sugar") - { - if (acceptor_object.get_object_value(acceptor_object_index).get_type() != sajson::TYPE_STRING) - fail("Expected TYPE_STRING, got " + json_type_as_string(acceptor_object.get_object_value(acceptor_object_index).get_type())); - - temp.acceptor_sugar = acceptor_object.get_object_value(acceptor_object_index).as_string(); - } - else if(acceptor_object.get_object_key(acceptor_object_index).as_string() == "Linkage") - { - if (acceptor_object.get_object_value(acceptor_object_index).get_type() != sajson::TYPE_ARRAY) - fail("Expected TYPE_ARRAY, got " + json_type_as_string(acceptor_object.get_object_value(acceptor_object_index).get_type())); - - sajson::value Linkage_array = acceptor_object.get_object_value(acceptor_object_index); - - for(size_t Linkage_index = 0; Linkage_index != Linkage_array.get_length(); Linkage_index++) - { - sajson::value Linkage_object = Linkage_array.get_array_element(Linkage_index); - - if(Linkage_object.get_type() != sajson::TYPE_OBJECT) - fail("Expected TYPE_OBJECT, got " + json_type_as_string(Linkage_object.get_type())); - - for(size_t Linkage_object_index = 0; Linkage_object_index != Linkage_object.get_length(); Linkage_object_index++) - { - if(Linkage_object.get_object_key(Linkage_object_index).as_string() == "donor_end") - { - if (Linkage_object.get_object_value(Linkage_object_index).get_type() != sajson::TYPE_STRING) - fail("Expected TYPE_STRING, got " + json_type_as_string(Linkage_object.get_object_value(Linkage_object_index).get_type())); - - temp.donor_end = Linkage_object.get_object_value(Linkage_object_index).as_string(); - } - - else if(Linkage_object.get_object_key(Linkage_object_index).as_string() == "acceptor_end") - { - if (Linkage_object.get_object_value(Linkage_object_index).get_type() != sajson::TYPE_STRING) - fail("Expected TYPE_STRING, got " + json_type_as_string(Linkage_object.get_object_value(Linkage_object_index).get_type())); - - temp.acceptor_end = Linkage_object.get_object_value(Linkage_object_index).as_string(); - } - - else if(Linkage_object.get_object_key(Linkage_object_index).as_string() == "Linkage_data") - { - sajson::value Linkage_data_object = Linkage_object.get_object_value(Linkage_object_index); - if(Linkage_data_object.get_type() != sajson::TYPE_OBJECT) - fail("Expected TYPE_OBJECT, got " + json_type_as_string(Linkage_data_object.get_type())); - - - std::vector> tmp_bins_for_linkage; - for(size_t Linkage_data_object_index = 0; Linkage_data_object_index != Linkage_data_object.get_length(); Linkage_data_object_index++) - { - // std::cout << "KEY : " << Linkage_data_object.get_object_key(Linkage_data_object_index).as_string() << std::endl; - if (Linkage_data_object.get_object_key(Linkage_data_object_index).as_string() == "summary") - { - sajson::value Linkage_data_summary_object = Linkage_data_object.get_object_value(Linkage_data_object_index); - if(Linkage_data_summary_object.get_type() != sajson::TYPE_OBJECT) - fail("Expected TYPE_OBJECT, got " + json_type_as_string(Linkage_data_summary_object.get_type())); - - for(size_t Linkage_data_object_summary_index = 0; Linkage_data_object_summary_index != Linkage_data_summary_object.get_length(); Linkage_data_object_summary_index++) - { - if(Linkage_data_summary_object.get_object_key(Linkage_data_object_summary_index).as_string() == "count_mean") - { - if (Linkage_data_summary_object.get_object_value(Linkage_data_object_summary_index).get_type() != sajson::TYPE_DOUBLE) - fail("Expected TYPE_DOUBLE, got " + json_type_as_string(Linkage_data_summary_object.get_object_value(Linkage_data_object_summary_index).get_type())); - - temp.summary.first = Linkage_data_summary_object.get_object_value(Linkage_data_object_summary_index).get_double_value(); - } - else if(Linkage_data_summary_object.get_object_key(Linkage_data_object_summary_index).as_string() == "count_stdev") - { - if (Linkage_data_summary_object.get_object_value(Linkage_data_object_summary_index).get_type() != sajson::TYPE_DOUBLE) - fail("Expected TYPE_DOUBLE, got " + json_type_as_string(Linkage_data_summary_object.get_object_value(Linkage_data_object_summary_index).get_type())); - - temp.summary.second = Linkage_data_summary_object.get_object_value(Linkage_data_object_summary_index).get_double_value(); - } - } - } - else if(Linkage_data_object.get_object_key(Linkage_data_object_index).as_string() == "bin_data") - { - sajson::value bin_data_array = Linkage_data_object.get_object_value(Linkage_data_object_index); - if(bin_data_array.get_type() != sajson::TYPE_ARRAY) - fail("Expected TYPE_ARRAY, got " + json_type_as_string(bin_data_array.get_type())); - - for(size_t bin_data_index = 0; bin_data_index != bin_data_array.get_length(); bin_data_index++) - { - std::unordered_map current_bin; - - sajson::value current_bin_data_entry = bin_data_array.get_array_element(bin_data_index); - if(current_bin_data_entry.get_type() != sajson::TYPE_OBJECT) - fail("Expected TYPE_OBJECT, got " + json_type_as_string(current_bin_data_entry.get_type())); - for(size_t current_bin_data_entry_index = 0; current_bin_data_entry_index != current_bin_data_entry.get_length(); current_bin_data_entry_index++) - { - if(current_bin_data_entry.get_object_key(current_bin_data_entry_index).as_string() == "lower_phi") - { - if (current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type() != sajson::TYPE_DOUBLE) - fail("Expected TYPE_DOUBLE, got " + json_type_as_string(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type())); - - current_bin["lower_phi"] = int(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_double_value()); - } - else if(current_bin_data_entry.get_object_key(current_bin_data_entry_index).as_string() == "higher_phi") - { - if (current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type() != sajson::TYPE_DOUBLE) - fail("Expected TYPE_DOUBLE, got " + json_type_as_string(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type())); - - current_bin["higher_phi"] = int(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_double_value()); - } - else if(current_bin_data_entry.get_object_key(current_bin_data_entry_index).as_string() == "lower_psi") - { - if (current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type() != sajson::TYPE_DOUBLE) - fail("Expected TYPE_DOUBLE, got " + json_type_as_string(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type())); - - current_bin["lower_psi"] = int(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_double_value()); - } - else if(current_bin_data_entry.get_object_key(current_bin_data_entry_index).as_string() == "higher_psi") - { - if (current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type() != sajson::TYPE_DOUBLE) - fail("Expected TYPE_DOUBLE, got " + json_type_as_string(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type())); - - current_bin["higher_psi"] = int(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_double_value()); - } - else if(current_bin_data_entry.get_object_key(current_bin_data_entry_index).as_string() == "count") - { - if (current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type() != sajson::TYPE_DOUBLE) - fail("Expected TYPE_DOUBLE, got " + json_type_as_string(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type())); - - current_bin["count"] = int(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_double_value()); - } - } - tmp_bins_for_linkage.push_back(current_bin); - } - } - else if(Linkage_data_object.get_object_key(Linkage_data_object_index).as_string() == "pdb_list") { - - sajson::value pdb_list_array = Linkage_data_object.get_object_value(Linkage_data_object_index); - - if(pdb_list_array.get_type() != sajson::TYPE_ARRAY) - fail("Expected TYPE_ARRAY, got " + json_type_as_string(pdb_list_array.get_type())); - - std::vector temp_pdb_list; - - for(size_t pdb_list_array_index = 0; pdb_list_array_index != pdb_list_array.get_length(); pdb_list_array_index++) { - std::string pdb_code = pdb_list_array.get_array_element(pdb_list_array_index).as_string(); - temp_pdb_list.push_back(pdb_code); - - } - temp.pdb_list = temp_pdb_list; - } - } - temp.bin_data = tmp_bins_for_linkage; - } - } - torsions_zscore_database.push_back(temp); - } - } - } - } - } - } - } - } - - if (data_key == "statistics") { + } - for (size_t statistics_data_index = 0; statistics_data_index != data_array.get_length(); statistics_data_index++) { + inline void generate_torsions_zscore_database(GlobalTorsionZScore& global_torsion_z_score, const sajson::document& jsonObject) + { +// +// std::vector torsions_zscore_database; +// TorsionsZScoreStatistics temp_statistics; +// +// sajson::value root = jsonObject.get_root(); +// if (root.get_type() != sajson::TYPE_OBJECT) +// fail("not Privateer Torsions Z-Score Database JSON file"); +// std::string database_name_key = root.get_object_key(1).as_string(); +// std::string database_name_value = root.get_object_value(1).as_string(); +// if (database_name_key != "database_name" || database_name_value != "torsions_z_score_database") +// fail("not Torsions Database JSON file - should be \"database_name\": \"torsions_z_score_database\", instead received \"" + database_name_key + "\": \"" + database_name_value + "\"\n"); +// +// std::string database_last_update = root.get_object_value(2).as_string(); +// +// sajson::value entries_array = root.get_object_value(0); +// std::string entries_name = root.get_object_key(0).as_string(); +// if (entries_array.get_type() != sajson::TYPE_OBJECT || entries_name != "data") +// fail("Expected TYPE_OBJECT, got " + json_type_as_string(entries_array.get_type()) + " with key value equal to \"data\", instead !!!got: \"" + entries_name + "\""); +// +// for (size_t data_index = 0; data_index != entries_array.get_length(); data_index++) { +// +// sajson::value data_array = entries_array.get_object_value(data_index); +// std::string data_key = entries_array.get_object_key(data_index).as_string(); +// +// if (data_key == "linkage_data") { +// +// for (size_t linkage_data_index = 0; linkage_data_index != data_array.get_length(); ++linkage_data_index) +// { +// sajson::value entry = data_array.get_array_element(linkage_data_index); +// if (entry.get_type() != sajson::TYPE_OBJECT) +// fail("Expected TYPE_OBJECT, got " + json_type_as_string(entry.get_type())); +// +// TorsionsZScoreDatabase temp; +// for(size_t donor_index = 0; donor_index != entry.get_length(); donor_index++) +// { +// if(entry.get_object_key(donor_index).as_string() == "donor") +// { +// if (entry.get_object_value(donor_index).get_type() != sajson::TYPE_STRING) +// fail("Expected TYPE_STRING, got " + json_type_as_string(entry.get_object_value(donor_index).get_type())); +// temp.donor_sugar = entry.get_object_value(donor_index).as_string(); +// } +// else if(entry.get_object_key(donor_index).as_string() == "acceptor") +// { +// sajson::value acceptor_array = entry.get_object_value(donor_index); +// if (acceptor_array.get_type() != sajson::TYPE_ARRAY) +// fail("Expected TYPE_ARRAY, got " + json_type_as_string(acceptor_array.get_type())); +// +// for(size_t acceptor_index = 0; acceptor_index != acceptor_array.get_length(); acceptor_index++) +// { +// sajson::value acceptor_object = acceptor_array.get_array_element(acceptor_index); +// +// if (acceptor_object.get_type() != sajson::TYPE_OBJECT) +// fail("Expected TYPE_OBJECT, got " + json_type_as_string(acceptor_object.get_type())); +// +// for(size_t acceptor_object_index = 0; acceptor_object_index != acceptor_object.get_length(); acceptor_object_index++) +// { +// if(acceptor_object.get_object_key(acceptor_object_index).as_string() == "sugar") +// { +// if (acceptor_object.get_object_value(acceptor_object_index).get_type() != sajson::TYPE_STRING) +// fail("Expected TYPE_STRING, got " + json_type_as_string(acceptor_object.get_object_value(acceptor_object_index).get_type())); +// +// temp.acceptor_sugar = acceptor_object.get_object_value(acceptor_object_index).as_string(); +// } +// else if(acceptor_object.get_object_key(acceptor_object_index).as_string() == "Linkage") +// { +// if (acceptor_object.get_object_value(acceptor_object_index).get_type() != sajson::TYPE_ARRAY) +// fail("Expected TYPE_ARRAY, got " + json_type_as_string(acceptor_object.get_object_value(acceptor_object_index).get_type())); +// +// sajson::value Linkage_array = acceptor_object.get_object_value(acceptor_object_index); +// +// for(size_t Linkage_index = 0; Linkage_index != Linkage_array.get_length(); Linkage_index++) +// { +// sajson::value Linkage_object = Linkage_array.get_array_element(Linkage_index); +// +// if(Linkage_object.get_type() != sajson::TYPE_OBJECT) +// fail("Expected TYPE_OBJECT, got " + json_type_as_string(Linkage_object.get_type())); +// +// for(size_t Linkage_object_index = 0; Linkage_object_index != Linkage_object.get_length(); Linkage_object_index++) +// { +// if(Linkage_object.get_object_key(Linkage_object_index).as_string() == "donor_end") +// { +// if (Linkage_object.get_object_value(Linkage_object_index).get_type() != sajson::TYPE_STRING) +// fail("Expected TYPE_STRING, got " + json_type_as_string(Linkage_object.get_object_value(Linkage_object_index).get_type())); +// +// temp.donor_end = Linkage_object.get_object_value(Linkage_object_index).as_string(); +// } +// +// else if(Linkage_object.get_object_key(Linkage_object_index).as_string() == "acceptor_end") +// { +// if (Linkage_object.get_object_value(Linkage_object_index).get_type() != sajson::TYPE_STRING) +// fail("Expected TYPE_STRING, got " + json_type_as_string(Linkage_object.get_object_value(Linkage_object_index).get_type())); +// +// temp.acceptor_end = Linkage_object.get_object_value(Linkage_object_index).as_string(); +// } +// +// else if(Linkage_object.get_object_key(Linkage_object_index).as_string() == "Linkage_data") +// { +// sajson::value Linkage_data_object = Linkage_object.get_object_value(Linkage_object_index); +// if(Linkage_data_object.get_type() != sajson::TYPE_OBJECT) +// fail("Expected TYPE_OBJECT, got " + json_type_as_string(Linkage_data_object.get_type())); +// +// +// std::vector> tmp_bins_for_linkage; +// for(size_t Linkage_data_object_index = 0; Linkage_data_object_index != Linkage_data_object.get_length(); Linkage_data_object_index++) +// { +// // std::cout << "KEY : " << Linkage_data_object.get_object_key(Linkage_data_object_index).as_string() << std::endl; +// if (Linkage_data_object.get_object_key(Linkage_data_object_index).as_string() == "summary") +// { +// sajson::value Linkage_data_summary_object = Linkage_data_object.get_object_value(Linkage_data_object_index); +// if(Linkage_data_summary_object.get_type() != sajson::TYPE_OBJECT) +// fail("Expected TYPE_OBJECT, got " + json_type_as_string(Linkage_data_summary_object.get_type())); +// +// for(size_t Linkage_data_object_summary_index = 0; Linkage_data_object_summary_index != Linkage_data_summary_object.get_length(); Linkage_data_object_summary_index++) +// { +// if(Linkage_data_summary_object.get_object_key(Linkage_data_object_summary_index).as_string() == "count_mean") +// { +// if (Linkage_data_summary_object.get_object_value(Linkage_data_object_summary_index).get_type() != sajson::TYPE_DOUBLE) +// fail("Expected TYPE_DOUBLE, got " + json_type_as_string(Linkage_data_summary_object.get_object_value(Linkage_data_object_summary_index).get_type())); +// +// temp.summary.first = Linkage_data_summary_object.get_object_value(Linkage_data_object_summary_index).get_double_value(); +// } +// else if(Linkage_data_summary_object.get_object_key(Linkage_data_object_summary_index).as_string() == "count_stdev") +// { +// if (Linkage_data_summary_object.get_object_value(Linkage_data_object_summary_index).get_type() != sajson::TYPE_DOUBLE) +// fail("Expected TYPE_DOUBLE, got " + json_type_as_string(Linkage_data_summary_object.get_object_value(Linkage_data_object_summary_index).get_type())); +// +// temp.summary.second = Linkage_data_summary_object.get_object_value(Linkage_data_object_summary_index).get_double_value(); +// } +// } +// } +// else if(Linkage_data_object.get_object_key(Linkage_data_object_index).as_string() == "bin_data") +// { +// sajson::value bin_data_array = Linkage_data_object.get_object_value(Linkage_data_object_index); +// if(bin_data_array.get_type() != sajson::TYPE_ARRAY) +// fail("Expected TYPE_ARRAY, got " + json_type_as_string(bin_data_array.get_type())); +// +// for(size_t bin_data_index = 0; bin_data_index != bin_data_array.get_length(); bin_data_index++) +// { +// std::unordered_map current_bin; +// +// sajson::value current_bin_data_entry = bin_data_array.get_array_element(bin_data_index); +// if(current_bin_data_entry.get_type() != sajson::TYPE_OBJECT) +// fail("Expected TYPE_OBJECT, got " + json_type_as_string(current_bin_data_entry.get_type())); +// for(size_t current_bin_data_entry_index = 0; current_bin_data_entry_index != current_bin_data_entry.get_length(); current_bin_data_entry_index++) +// { +// if(current_bin_data_entry.get_object_key(current_bin_data_entry_index).as_string() == "lower_phi") +// { +// if (current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type() != sajson::TYPE_DOUBLE) +// fail("Expected TYPE_DOUBLE, got " + json_type_as_string(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type())); +// +// current_bin["lower_phi"] = int(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_double_value()); +// } +// else if(current_bin_data_entry.get_object_key(current_bin_data_entry_index).as_string() == "higher_phi") +// { +// if (current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type() != sajson::TYPE_DOUBLE) +// fail("Expected TYPE_DOUBLE, got " + json_type_as_string(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type())); +// +// current_bin["higher_phi"] = int(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_double_value()); +// } +// else if(current_bin_data_entry.get_object_key(current_bin_data_entry_index).as_string() == "lower_psi") +// { +// if (current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type() != sajson::TYPE_DOUBLE) +// fail("Expected TYPE_DOUBLE, got " + json_type_as_string(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type())); +// +// current_bin["lower_psi"] = int(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_double_value()); +// } +// else if(current_bin_data_entry.get_object_key(current_bin_data_entry_index).as_string() == "higher_psi") +// { +// if (current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type() != sajson::TYPE_DOUBLE) +// fail("Expected TYPE_DOUBLE, got " + json_type_as_string(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type())); +// +// current_bin["higher_psi"] = int(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_double_value()); +// } +// else if(current_bin_data_entry.get_object_key(current_bin_data_entry_index).as_string() == "count") +// { +// if (current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type() != sajson::TYPE_DOUBLE) +// fail("Expected TYPE_DOUBLE, got " + json_type_as_string(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_type())); +// +// current_bin["count"] = int(current_bin_data_entry.get_object_value(current_bin_data_entry_index).get_double_value()); +// } +// } +// tmp_bins_for_linkage.push_back(current_bin); +// } +// } +// else if(Linkage_data_object.get_object_key(Linkage_data_object_index).as_string() == "pdb_list") { +// +// sajson::value pdb_list_array = Linkage_data_object.get_object_value(Linkage_data_object_index); +// +// if(pdb_list_array.get_type() != sajson::TYPE_ARRAY) +// fail("Expected TYPE_ARRAY, got " + json_type_as_string(pdb_list_array.get_type())); +// +// std::vector temp_pdb_list; +// +// for(size_t pdb_list_array_index = 0; pdb_list_array_index != pdb_list_array.get_length(); pdb_list_array_index++) { +// std::string pdb_code = pdb_list_array.get_array_element(pdb_list_array_index).as_string(); +// temp_pdb_list.push_back(pdb_code); +// +// } +// temp.pdb_list = temp_pdb_list; +// } +// } +// temp.bin_data = tmp_bins_for_linkage; +// } +// } +// torsions_zscore_database.push_back(temp); +// } +// } +// } +// } +// } +// } +// } +// } +// +// if (data_key == "statistics") { +// +// for (size_t statistics_data_index = 0; statistics_data_index != data_array.get_length(); statistics_data_index++) { +// +// std::string statistics_key = data_array.get_object_key(statistics_data_index).as_string(); +// float statistics_value = static_cast(data_array.get_object_value(statistics_data_index).get_double_value()); +// +// +// if (statistics_key != "Database Z Score Average" && statistics_key != "Database Z Score StdDev") { +// fail("Key not defined in statistics obeject"); +// } +// +// if (statistics_key == "Database Z Score Average") { +// temp_statistics.average_z_score_for_database = statistics_value; +// } +// +// if (statistics_key == "Database Z Score StdDev") { +// temp_statistics.stddev_z_score_for_database = statistics_value; +// } +// +// } +// +// } +// } +// +// global_torsion_z_score.database_array = torsions_zscore_database; +// global_torsion_z_score.statistics = temp_statistics; +// // std::cout << std::endl << "Successfully imported Privateer's Torsions Z-score database.\nLast database update: " << database_last_update << std::endl << std::endl; + } - std::string statistics_key = data_array.get_object_key(statistics_data_index).as_string(); - float statistics_value = static_cast(data_array.get_object_value(statistics_data_index).get_double_value()); + inline GlobalTorsionZScore read_json_zscore_torsions_insitu(char* buffer, size_t size, const std::string& name) + { + GlobalTorsionZScore global_torsion_z_score; + sajson::document json = sajson::parse(sajson::dynamic_allocation(), + sajson::mutable_string_view(size, buffer)); + if (!json.is_valid()) + fail(name, ":", std::to_string(json.get_error_line()), " error: ", + json.get_error_message_as_string()); + generate_torsions_zscore_database(global_torsion_z_score, json); + // std::cout << "___Length of torsions_zscore_database = " << global_torsion_z_score.database_array.size() << std::endl; + return global_torsion_z_score; + } + inline GlobalTorsionZScore read_json_zscore_db(const std::string& path) { + simdjson::ondemand::parser parser; + auto json = simdjson::padded_string::load(path); + simdjson::ondemand::document doc = parser.iterate(json); - if (statistics_key != "Database Z Score Average" && statistics_key != "Database Z Score StdDev") { - fail("Key not defined in statistics obeject"); + std::vector torsions_zscore_database; + TorsionsZScoreStatistics temp_statistics; + auto data = doc["data"]; + + auto stats = data["statistics"]; + temp_statistics.average_z_score_for_database = stats["Database Z Score Average"].get_double(); + temp_statistics.stddev_z_score_for_database = stats["Database Z Score StdDev"].get_double(); + + auto linkage_data = data["linkage_data"]; + for (auto l: linkage_data) { + auto donor = l["donor"]; + auto acceptors = l["acceptor"]; + for (auto a: acceptors) { + auto sugar = a["sugar"]; + auto linkage = a["Linkage"]; + for (auto lk: linkage) { + + TorsionsZScoreDatabase tmp_db; + tmp_db.acceptor_sugar = std::string(sugar.get_string().value()); + tmp_db.donor_sugar = std::string(donor.get_string().value()); + tmp_db.acceptor_end = std::string(lk["acceptor_end"].get_string().value()); + tmp_db.donor_end = std::string(lk["donor_end"].get_string().value()); + + auto linkage_data = lk["Linkage_data"]; + auto summary = linkage_data["summary"]; + tmp_db.summary = std::make_pair( + summary["count_mean"].get_double().value(), + summary["count_stdev"].get_double().value() + ); + + std::vector> tmp_bins_for_linkage; + + auto bin_data = linkage_data["bin_data"]; + for (auto bin: bin_data) { + std::unordered_map bin_map; + bin_map["lower_phi"] = int(bin["lower_phi"].get_double().value()); + bin_map["higher_phi"] = int(bin["higher_phi"].get_double().value()); + bin_map["lower_psi"] = int(bin["lower_psi"].get_double().value()); + bin_map["higher_psi"] = int(bin["higher_psi"].get_double().value()); + bin_map["count"] = int(bin["count"].get_double()); + tmp_bins_for_linkage.push_back(bin_map); } + tmp_db.bin_data = tmp_bins_for_linkage; - if (statistics_key == "Database Z Score Average") { - temp_statistics.average_z_score_for_database = statistics_value; - } + auto pdb_list = linkage_data["pdb_list"]; + std::vector temp_pdb_list; - if (statistics_key == "Database Z Score StdDev") { - temp_statistics.stddev_z_score_for_database = statistics_value; + for (auto pdb: pdb_list) { + temp_pdb_list.push_back(std::string(pdb.get_string().value())); } + tmp_db.pdb_list = temp_pdb_list; + torsions_zscore_database.push_back(tmp_db); } - } - } + } - global_torsion_z_score.database_array = torsions_zscore_database; + GlobalTorsionZScore global_torsion_z_score; global_torsion_z_score.statistics = temp_statistics; - // std::cout << std::endl << "Successfully imported Privateer's Torsions Z-score database.\nLast database update: " << database_last_update << std::endl << std::endl; - } + global_torsion_z_score.database_array = torsions_zscore_database; - inline GlobalTorsionZScore read_json_zscore_torsions_insitu(char* buffer, size_t size, const std::string& name) - { - GlobalTorsionZScore global_torsion_z_score; - sajson::document json = sajson::parse(sajson::dynamic_allocation(), - sajson::mutable_string_view(size, buffer)); - if (!json.is_valid()) - fail(name, ":", std::to_string(json.get_error_line()), " error: ", - json.get_error_message_as_string()); - generate_torsions_zscore_database(global_torsion_z_score, json); - // std::cout << "___Length of torsions_zscore_database = " << global_torsion_z_score.database_array.size() << std::endl; return global_torsion_z_score; } inline GlobalTorsionZScore read_json_file_for_torsions_zscore_database(const std::string& path) { std::string path_copy = path; - if(path_copy == "nopath" || path_copy.empty()) + if(path_copy == "nopath" || path_copy.empty()) { std::string env; if(std::getenv("PRIVATEERDATA")) @@ -689,17 +766,19 @@ namespace privateer else { env = std::getenv("CLIBD"); - path_copy = env + "/privateer_torsions_z_score_database.json"; + path_copy = env + "/privateer_data/linkage_torsions/privateer_torsions_z_score_database.json"; } } - fileptr_t f = file_open(path_copy.c_str(), "rb"); - size_t buf_size = file_size(f.get(), path_copy); - std::vector buffer(buf_size); - if (std::fread(buffer.data(), buffer.size(), 1, f.get()) != 1) - fail(path_copy + ": fread failed"); + return read_json_zscore_db(path_copy); + + // fileptr_t f = file_open(path_copy.c_str(), "rb"); + // size_t buf_size = file_size(f.get(), path_copy); + // std::vector buffer(buf_size); + // if (std::fread(buffer.data(), buffer.size(), 1, f.get()) != 1) + // fail(path_copy + ": fread failed"); - return read_json_zscore_torsions_insitu(buffer.data(), buffer.size(), path_copy); + // return read_json_zscore_torsions_insitu(buffer.data(), buffer.size(), path_copy); } // ____________________________________TORSIONS Z SCORE DATABASE END_________________________________________ // diff --git a/src/privateer/cpp/third-party/gemmi_compilation_unit.cpp b/src/privateer/cpp/third-party/gemmi_compilation_unit.cpp index ee9fe1c90..971bba1fa 100644 --- a/src/privateer/cpp/third-party/gemmi_compilation_unit.cpp +++ b/src/privateer/cpp/third-party/gemmi_compilation_unit.cpp @@ -7,19 +7,19 @@ // privateer-interactions.h -#include "gemmi/mmread.hpp" -#include "gemmi/monlib.hpp" -#include "gemmi/placeh.hpp" -#include "gemmi/fstream.hpp" -#include "gemmi/cif.hpp" +// #include "gemmi/mmread.hpp" +// #include "gemmi/monlib.hpp" +// #include "gemmi/placeh.hpp" +// #include "gemmi/fstream.hpp" +// #include "gemmi/cif.hpp" #define GEMMI_WRITE_IMPLEMENTATION -// #define USE_STD_SNPRINTF -#include "gemmi/to_pdb.hpp" - +#define USE_STD_SNPRINTF +// #include "gemmi/to_pdb.hpp" +// // privateer-json.h -#include "gemmi/third_party/sajson.h" - +// #include "gemmi/third_party/sajson.h" +// // privateer-restraints.h -#include "gemmi/chemcomp.hpp" -#include "gemmi/calculate.hpp" -#include "gemmi/to_cif.hpp" // for write_cif_to_stream \ No newline at end of file +// #include "gemmi/chemcomp.hpp" +// #include "gemmi/calculate.hpp" +// #include "gemmi/to_cif.hpp" // for write_cif_to_stream \ No newline at end of file diff --git a/src/privateer/cpp/third-party/simdjson/simdjson.cpp b/src/privateer/cpp/third-party/simdjson/simdjson.cpp new file mode 100644 index 000000000..bafa74af8 --- /dev/null +++ b/src/privateer/cpp/third-party/simdjson/simdjson.cpp @@ -0,0 +1,43387 @@ +/* auto-generated on . Do not edit! */ +/* including simdjson.cpp: */ +/* begin file simdjson.cpp */ +#define SIMDJSON_SRC_SIMDJSON_CPP + +/* including base.h: #include */ +/* begin file base.h */ +#ifndef SIMDJSON_SRC_BASE_H +#define SIMDJSON_SRC_BASE_H + +/* including simdjson/base.h: #include */ +/* begin file simdjson/base.h */ +/** + * @file Base declarations for all simdjson headers + * @private + */ +#ifndef SIMDJSON_BASE_H +#define SIMDJSON_BASE_H + +/* including simdjson/common_defs.h: #include "simdjson/common_defs.h" */ +/* begin file simdjson/common_defs.h */ +#ifndef SIMDJSON_COMMON_DEFS_H +#define SIMDJSON_COMMON_DEFS_H + +#include +/* including simdjson/compiler_check.h: #include "simdjson/compiler_check.h" */ +/* begin file simdjson/compiler_check.h */ +#ifndef SIMDJSON_COMPILER_CHECK_H +#define SIMDJSON_COMPILER_CHECK_H + +#ifndef __cplusplus +#error simdjson requires a C++ compiler +#endif + +#ifndef SIMDJSON_CPLUSPLUS +#if defined(_MSVC_LANG) && !defined(__clang__) +#define SIMDJSON_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG) +#else +#define SIMDJSON_CPLUSPLUS __cplusplus +#endif +#endif + +// C++ 17 +#if !defined(SIMDJSON_CPLUSPLUS17) && (SIMDJSON_CPLUSPLUS >= 201703L) +#define SIMDJSON_CPLUSPLUS17 1 +#endif + +// C++ 14 +#if !defined(SIMDJSON_CPLUSPLUS14) && (SIMDJSON_CPLUSPLUS >= 201402L) +#define SIMDJSON_CPLUSPLUS14 1 +#endif + +// C++ 11 +#if !defined(SIMDJSON_CPLUSPLUS11) && (SIMDJSON_CPLUSPLUS >= 201103L) +#define SIMDJSON_CPLUSPLUS11 1 +#endif + +#ifndef SIMDJSON_CPLUSPLUS11 +#error simdjson requires a compiler compliant with the C++11 standard +#endif + +#ifndef SIMDJSON_IF_CONSTEXPR +#if SIMDJSON_CPLUSPLUS17 +#define SIMDJSON_IF_CONSTEXPR if constexpr +#else +#define SIMDJSON_IF_CONSTEXPR if +#endif +#endif + +#endif // SIMDJSON_COMPILER_CHECK_H +/* end file simdjson/compiler_check.h */ +/* including simdjson/portability.h: #include "simdjson/portability.h" */ +/* begin file simdjson/portability.h */ +#ifndef SIMDJSON_PORTABILITY_H +#define SIMDJSON_PORTABILITY_H + +#include +#include +#include +#include +#include +#ifndef _WIN32 +// strcasecmp, strncasecmp +#include +#endif + +#ifdef _MSC_VER +#define SIMDJSON_VISUAL_STUDIO 1 +/** + * We want to differentiate carefully between + * clang under visual studio and regular visual + * studio. + * + * Under clang for Windows, we enable: + * * target pragmas so that part and only part of the + * code gets compiled for advanced instructions. + * + */ +#ifdef __clang__ +// clang under visual studio +#define SIMDJSON_CLANG_VISUAL_STUDIO 1 +#else +// just regular visual studio (best guess) +#define SIMDJSON_REGULAR_VISUAL_STUDIO 1 +#endif // __clang__ +#endif // _MSC_VER + +#if defined(__x86_64__) || defined(_M_AMD64) +#define SIMDJSON_IS_X86_64 1 +#elif defined(__aarch64__) || defined(_M_ARM64) +#define SIMDJSON_IS_ARM64 1 +#elif defined(__riscv) && __riscv_xlen == 64 +#define SIMDJSON_IS_RISCV64 1 +#elif defined(__PPC64__) || defined(_M_PPC64) +#if defined(__ALTIVEC__) +#define SIMDJSON_IS_PPC64_VMX 1 +#endif // defined(__ALTIVEC__) +#else +#define SIMDJSON_IS_32BITS 1 + +#if defined(_M_IX86) || defined(__i386__) +#define SIMDJSON_IS_X86_32BITS 1 +#elif defined(__arm__) || defined(_M_ARM) +#define SIMDJSON_IS_ARM_32BITS 1 +#elif defined(__PPC__) || defined(_M_PPC) +#define SIMDJSON_IS_PPC_32BITS 1 +#endif + +#endif // defined(__x86_64__) || defined(_M_AMD64) +#ifndef SIMDJSON_IS_32BITS +#define SIMDJSON_IS_32BITS 0 +#endif + +#if SIMDJSON_IS_32BITS +#ifndef SIMDJSON_NO_PORTABILITY_WARNING +// In the future, we should allow programmers +// to get warning. +#endif // SIMDJSON_NO_PORTABILITY_WARNING +#endif // SIMDJSON_IS_32BITS + +#define SIMDJSON_CAT_IMPLEMENTATION_(a,...) a ## __VA_ARGS__ +#define SIMDJSON_CAT(a,...) SIMDJSON_CAT_IMPLEMENTATION_(a, __VA_ARGS__) + +#define SIMDJSON_STRINGIFY_IMPLEMENTATION_(a,...) #a SIMDJSON_STRINGIFY(__VA_ARGS__) +#define SIMDJSON_STRINGIFY(a,...) SIMDJSON_CAT_IMPLEMENTATION_(a, __VA_ARGS__) + +// this is almost standard? +#undef SIMDJSON_STRINGIFY_IMPLEMENTATION_ +#undef SIMDJSON_STRINGIFY +#define SIMDJSON_STRINGIFY_IMPLEMENTATION_(a) #a +#define SIMDJSON_STRINGIFY(a) SIMDJSON_STRINGIFY_IMPLEMENTATION_(a) + +// Our fast kernels require 64-bit systems. +// +// On 32-bit x86, we lack 64-bit popcnt, lzcnt, blsr instructions. +// Furthermore, the number of SIMD registers is reduced. +// +// On 32-bit ARM, we would have smaller registers. +// +// The simdjson users should still have the fallback kernel. It is +// slower, but it should run everywhere. + +// +// Enable valid runtime implementations, and select SIMDJSON_BUILTIN_IMPLEMENTATION +// + +// We are going to use runtime dispatch. +#if SIMDJSON_IS_X86_64 +#ifdef __clang__ +// clang does not have GCC push pop +// warning: clang attribute push can't be used within a namespace in clang up +// til 8.0 so SIMDJSON_TARGET_REGION and SIMDJSON_UNTARGET_REGION must be *outside* of a +// namespace. +#define SIMDJSON_TARGET_REGION(T) \ + _Pragma(SIMDJSON_STRINGIFY( \ + clang attribute push(__attribute__((target(T))), apply_to = function))) +#define SIMDJSON_UNTARGET_REGION _Pragma("clang attribute pop") +#elif defined(__GNUC__) +// GCC is easier +#define SIMDJSON_TARGET_REGION(T) \ + _Pragma("GCC push_options") _Pragma(SIMDJSON_STRINGIFY(GCC target(T))) +#define SIMDJSON_UNTARGET_REGION _Pragma("GCC pop_options") +#endif // clang then gcc + +#endif // x86 + +// Default target region macros don't do anything. +#ifndef SIMDJSON_TARGET_REGION +#define SIMDJSON_TARGET_REGION(T) +#define SIMDJSON_UNTARGET_REGION +#endif + +// Is threading enabled? +#if defined(_REENTRANT) || defined(_MT) +#ifndef SIMDJSON_THREADS_ENABLED +#define SIMDJSON_THREADS_ENABLED +#endif +#endif + +// workaround for large stack sizes under -O0. +// https://github.com/simdjson/simdjson/issues/691 +#ifdef __APPLE__ +#ifndef __OPTIMIZE__ +// Apple systems have small stack sizes in secondary threads. +// Lack of compiler optimization may generate high stack usage. +// Users may want to disable threads for safety, but only when +// in debug mode which we detect by the fact that the __OPTIMIZE__ +// macro is not defined. +#undef SIMDJSON_THREADS_ENABLED +#endif +#endif + + +#if defined(__clang__) +#define SIMDJSON_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"))) +#elif defined(__GNUC__) +#define SIMDJSON_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined)) +#else +#define SIMDJSON_NO_SANITIZE_UNDEFINED +#endif + + +#if defined(__clang__) || defined(__GNUC__) +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) +#define SIMDJSON_NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory"))) +# endif // if __has_feature(memory_sanitizer) +#endif // defined(__has_feature) +#endif +// make sure it is defined as 'nothing' if it is unapplicable. +#ifndef SIMDJSON_NO_SANITIZE_MEMORY +#define SIMDJSON_NO_SANITIZE_MEMORY +#endif + +#if SIMDJSON_VISUAL_STUDIO +// This is one case where we do not distinguish between +// regular visual studio and clang under visual studio. +// clang under Windows has _stricmp (like visual studio) but not strcasecmp (as clang normally has) +#define simdjson_strcasecmp _stricmp +#define simdjson_strncasecmp _strnicmp +#else +// The strcasecmp, strncasecmp, and strcasestr functions do not work with multibyte strings (e.g. UTF-8). +// So they are only useful for ASCII in our context. +// https://www.gnu.org/software/libunistring/manual/libunistring.html#char-_002a-strings +#define simdjson_strcasecmp strcasecmp +#define simdjson_strncasecmp strncasecmp +#endif + +#if defined(NDEBUG) || defined(__OPTIMIZE__) || (defined(_MSC_VER) && !defined(_DEBUG)) +// If NDEBUG is set, or __OPTIMIZE__ is set, or we are under MSVC in release mode, +// then do away with asserts and use __assume. +#if SIMDJSON_VISUAL_STUDIO +#define SIMDJSON_UNREACHABLE() __assume(0) +#define SIMDJSON_ASSUME(COND) __assume(COND) +#else +#define SIMDJSON_UNREACHABLE() __builtin_unreachable(); +#define SIMDJSON_ASSUME(COND) do { if (!(COND)) __builtin_unreachable(); } while (0) +#endif + +#else // defined(NDEBUG) || defined(__OPTIMIZE__) || (defined(_MSC_VER) && !defined(_DEBUG)) +// This should only ever be enabled in debug mode. +#define SIMDJSON_UNREACHABLE() assert(0); +#define SIMDJSON_ASSUME(COND) assert(COND) + +#endif + +#endif // SIMDJSON_PORTABILITY_H +/* end file simdjson/portability.h */ + +namespace simdjson { +namespace internal { +/** + * @private + * Our own implementation of the C++17 to_chars function. + * Defined in src/to_chars + */ +char *to_chars(char *first, const char *last, double value); +/** + * @private + * A number parsing routine. + * Defined in src/from_chars + */ +double from_chars(const char *first) noexcept; +double from_chars(const char *first, const char* end) noexcept; +} + +#ifndef SIMDJSON_EXCEPTIONS +#if __cpp_exceptions +#define SIMDJSON_EXCEPTIONS 1 +#else +#define SIMDJSON_EXCEPTIONS 0 +#endif +#endif + +} // namespace simdjson + +#if defined(__GNUC__) + // Marks a block with a name so that MCA analysis can see it. + #define SIMDJSON_BEGIN_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-BEGIN " #name); + #define SIMDJSON_END_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-END " #name); + #define SIMDJSON_DEBUG_BLOCK(name, block) BEGIN_DEBUG_BLOCK(name); block; END_DEBUG_BLOCK(name); +#else + #define SIMDJSON_BEGIN_DEBUG_BLOCK(name) + #define SIMDJSON_END_DEBUG_BLOCK(name) + #define SIMDJSON_DEBUG_BLOCK(name, block) +#endif + +// Align to N-byte boundary +#define SIMDJSON_ROUNDUP_N(a, n) (((a) + ((n)-1)) & ~((n)-1)) +#define SIMDJSON_ROUNDDOWN_N(a, n) ((a) & ~((n)-1)) + +#define SIMDJSON_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0) + +#if SIMDJSON_REGULAR_VISUAL_STUDIO + + #define simdjson_really_inline __forceinline + #define simdjson_never_inline __declspec(noinline) + + #define simdjson_unused + #define simdjson_warn_unused + + #ifndef simdjson_likely + #define simdjson_likely(x) x + #endif + #ifndef simdjson_unlikely + #define simdjson_unlikely(x) x + #endif + + #define SIMDJSON_PUSH_DISABLE_WARNINGS __pragma(warning( push )) + #define SIMDJSON_PUSH_DISABLE_ALL_WARNINGS __pragma(warning( push, 0 )) + #define SIMDJSON_DISABLE_VS_WARNING(WARNING_NUMBER) __pragma(warning( disable : WARNING_NUMBER )) + // Get rid of Intellisense-only warnings (Code Analysis) + // Though __has_include is C++17, it is supported in Visual Studio 2017 or better (_MSC_VER>=1910). + #ifdef __has_include + #if __has_include() + #include + #define SIMDJSON_DISABLE_UNDESIRED_WARNINGS SIMDJSON_DISABLE_VS_WARNING(ALL_CPPCORECHECK_WARNINGS) + #endif + #endif + + #ifndef SIMDJSON_DISABLE_UNDESIRED_WARNINGS + #define SIMDJSON_DISABLE_UNDESIRED_WARNINGS + #endif + + #define SIMDJSON_DISABLE_DEPRECATED_WARNING SIMDJSON_DISABLE_VS_WARNING(4996) + #define SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING + #define SIMDJSON_POP_DISABLE_WARNINGS __pragma(warning( pop )) + + #define SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS + #define SIMDJSON_POP_DISABLE_UNUSED_WARNINGS + +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + + #define simdjson_really_inline inline __attribute__((always_inline)) + #define simdjson_never_inline inline __attribute__((noinline)) + + #define simdjson_unused __attribute__((unused)) + #define simdjson_warn_unused __attribute__((warn_unused_result)) + + #ifndef simdjson_likely + #define simdjson_likely(x) __builtin_expect(!!(x), 1) + #endif + #ifndef simdjson_unlikely + #define simdjson_unlikely(x) __builtin_expect(!!(x), 0) + #endif + + #define SIMDJSON_PUSH_DISABLE_WARNINGS _Pragma("GCC diagnostic push") + // gcc doesn't seem to disable all warnings with all and extra, add warnings here as necessary + // We do it separately for clang since it has different warnings. + #ifdef __clang__ + // clang is missing -Wmaybe-uninitialized. + #define SIMDJSON_PUSH_DISABLE_ALL_WARNINGS SIMDJSON_PUSH_DISABLE_WARNINGS \ + SIMDJSON_DISABLE_GCC_WARNING(-Weffc++) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wall) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wconversion) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wextra) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wattributes) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wimplicit-fallthrough) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wnon-virtual-dtor) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wreturn-type) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wshadow) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wunused-parameter) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wunused-variable) + #else // __clang__ + #define SIMDJSON_PUSH_DISABLE_ALL_WARNINGS SIMDJSON_PUSH_DISABLE_WARNINGS \ + SIMDJSON_DISABLE_GCC_WARNING(-Weffc++) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wall) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wconversion) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wextra) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wattributes) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wimplicit-fallthrough) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wnon-virtual-dtor) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wreturn-type) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wshadow) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wunused-parameter) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wunused-variable) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wmaybe-uninitialized) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wformat-security) + #endif // __clang__ + + #define SIMDJSON_PRAGMA(P) _Pragma(#P) + #define SIMDJSON_DISABLE_GCC_WARNING(WARNING) SIMDJSON_PRAGMA(GCC diagnostic ignored #WARNING) + #if SIMDJSON_CLANG_VISUAL_STUDIO + #define SIMDJSON_DISABLE_UNDESIRED_WARNINGS SIMDJSON_DISABLE_GCC_WARNING(-Wmicrosoft-include) + #else + #define SIMDJSON_DISABLE_UNDESIRED_WARNINGS + #endif + #define SIMDJSON_DISABLE_DEPRECATED_WARNING SIMDJSON_DISABLE_GCC_WARNING(-Wdeprecated-declarations) + #define SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING SIMDJSON_DISABLE_GCC_WARNING(-Wstrict-overflow) + #define SIMDJSON_POP_DISABLE_WARNINGS _Pragma("GCC diagnostic pop") + + #define SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS SIMDJSON_PUSH_DISABLE_WARNINGS \ + SIMDJSON_DISABLE_GCC_WARNING(-Wunused) + #define SIMDJSON_POP_DISABLE_UNUSED_WARNINGS SIMDJSON_POP_DISABLE_WARNINGS + + + +#endif // MSC_VER + +#if defined(simdjson_inline) + // Prefer the user's definition of simdjson_inline; don't define it ourselves. +#elif defined(__GNUC__) && !defined(__OPTIMIZE__) + // If optimizations are disabled, forcing inlining can lead to significant + // code bloat and high compile times. Don't use simdjson_really_inline for + // unoptimized builds. + #define simdjson_inline inline +#else + // Force inlining for most simdjson functions. + #define simdjson_inline simdjson_really_inline +#endif + +#if SIMDJSON_VISUAL_STUDIO + /** + * Windows users need to do some extra work when building + * or using a dynamic library (DLL). When building, we need + * to set SIMDJSON_DLLIMPORTEXPORT to __declspec(dllexport). + * When *using* the DLL, the user needs to set + * SIMDJSON_DLLIMPORTEXPORT __declspec(dllimport). + * + * Static libraries not need require such work. + * + * It does not matter here whether you are using + * the regular visual studio or clang under visual + * studio, you still need to handle these issues. + * + * Non-Windows systems do not have this complexity. + */ + #if SIMDJSON_BUILDING_WINDOWS_DYNAMIC_LIBRARY + // We set SIMDJSON_BUILDING_WINDOWS_DYNAMIC_LIBRARY when we build a DLL under Windows. + // It should never happen that both SIMDJSON_BUILDING_WINDOWS_DYNAMIC_LIBRARY and + // SIMDJSON_USING_WINDOWS_DYNAMIC_LIBRARY are set. + #define SIMDJSON_DLLIMPORTEXPORT __declspec(dllexport) + #elif SIMDJSON_USING_WINDOWS_DYNAMIC_LIBRARY + // Windows user who call a dynamic library should set SIMDJSON_USING_WINDOWS_DYNAMIC_LIBRARY to 1. + #define SIMDJSON_DLLIMPORTEXPORT __declspec(dllimport) + #else + // We assume by default static linkage + #define SIMDJSON_DLLIMPORTEXPORT + #endif + +/** + * Workaround for the vcpkg package manager. Only vcpkg should + * ever touch the next line. The SIMDJSON_USING_LIBRARY macro is otherwise unused. + */ +#if SIMDJSON_USING_LIBRARY +#define SIMDJSON_DLLIMPORTEXPORT __declspec(dllimport) +#endif +/** + * End of workaround for the vcpkg package manager. + */ +#else + #define SIMDJSON_DLLIMPORTEXPORT +#endif + +// C++17 requires string_view. +#if SIMDJSON_CPLUSPLUS17 +#define SIMDJSON_HAS_STRING_VIEW +#include // by the standard, this has to be safe. +#endif + +// This macro (__cpp_lib_string_view) has to be defined +// for C++17 and better, but if it is otherwise defined, +// we are going to assume that string_view is available +// even if we do not have C++17 support. +#ifdef __cpp_lib_string_view +#define SIMDJSON_HAS_STRING_VIEW +#endif + +// Some systems have string_view even if we do not have C++17 support, +// and even if __cpp_lib_string_view is undefined, it is the case +// with Apple clang version 11. +// We must handle it. *This is important.* +#ifndef SIMDJSON_HAS_STRING_VIEW +#if defined __has_include +// do not combine the next #if with the previous one (unsafe) +#if __has_include () +// now it is safe to trigger the include +#include // though the file is there, it does not follow that we got the implementation +#if defined(_LIBCPP_STRING_VIEW) +// Ah! So we under libc++ which under its Library Fundamentals Technical Specification, which preceded C++17, +// included string_view. +// This means that we have string_view *even though* we may not have C++17. +#define SIMDJSON_HAS_STRING_VIEW +#endif // _LIBCPP_STRING_VIEW +#endif // __has_include () +#endif // defined __has_include +#endif // def SIMDJSON_HAS_STRING_VIEW +// end of complicated but important routine to try to detect string_view. + +// +// Backfill std::string_view using nonstd::string_view on systems where +// we expect that string_view is missing. Important: if we get this wrong, +// we will end up with two string_view definitions and potential trouble. +// That is why we work so hard above to avoid it. +// +#ifndef SIMDJSON_HAS_STRING_VIEW +SIMDJSON_PUSH_DISABLE_ALL_WARNINGS +/* including simdjson/nonstd/string_view.hpp: #include "simdjson/nonstd/string_view.hpp" */ +/* begin file simdjson/nonstd/string_view.hpp */ +// Copyright 2017-2020 by Martin Moene +// +// string-view lite, a C++17-like string_view for C++98 and later. +// For more information see https://github.com/martinmoene/string-view-lite +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// #pragma once // We remove #pragma once here as it generates a warning in some cases. We rely on the include guard. + +#ifndef NONSTD_SV_LITE_H_INCLUDED +#define NONSTD_SV_LITE_H_INCLUDED + +#define string_view_lite_MAJOR 1 +#define string_view_lite_MINOR 7 +#define string_view_lite_PATCH 0 + +#define string_view_lite_VERSION nssv_STRINGIFY(string_view_lite_MAJOR) "." nssv_STRINGIFY(string_view_lite_MINOR) "." nssv_STRINGIFY(string_view_lite_PATCH) + +#define nssv_STRINGIFY( x ) nssv_STRINGIFY_( x ) +#define nssv_STRINGIFY_( x ) #x + +// string-view lite configuration: + +#define nssv_STRING_VIEW_DEFAULT 0 +#define nssv_STRING_VIEW_NONSTD 1 +#define nssv_STRING_VIEW_STD 2 + +// tweak header support: + +#ifdef __has_include +# if __has_include() +# include +# endif +#define nssv_HAVE_TWEAK_HEADER 1 +#else +#define nssv_HAVE_TWEAK_HEADER 0 +//# pragma message("string_view.hpp: Note: Tweak header not supported.") +#endif + +// string_view selection and configuration: + +#if !defined( nssv_CONFIG_SELECT_STRING_VIEW ) +# define nssv_CONFIG_SELECT_STRING_VIEW ( nssv_HAVE_STD_STRING_VIEW ? nssv_STRING_VIEW_STD : nssv_STRING_VIEW_NONSTD ) +#endif + +#ifndef nssv_CONFIG_STD_SV_OPERATOR +# define nssv_CONFIG_STD_SV_OPERATOR 0 +#endif + +#ifndef nssv_CONFIG_USR_SV_OPERATOR +# define nssv_CONFIG_USR_SV_OPERATOR 1 +#endif + +#ifdef nssv_CONFIG_CONVERSION_STD_STRING +# define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS nssv_CONFIG_CONVERSION_STD_STRING +# define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS nssv_CONFIG_CONVERSION_STD_STRING +#endif + +#ifndef nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS +# define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS 1 +#endif + +#ifndef nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS +# define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS 1 +#endif + +#ifndef nssv_CONFIG_NO_STREAM_INSERTION +# define nssv_CONFIG_NO_STREAM_INSERTION 0 +#endif + +#ifndef nssv_CONFIG_CONSTEXPR11_STD_SEARCH +# define nssv_CONFIG_CONSTEXPR11_STD_SEARCH 1 +#endif + +// Control presence of exception handling (try and auto discover): + +#ifndef nssv_CONFIG_NO_EXCEPTIONS +# if defined(_MSC_VER) +# include // for _HAS_EXCEPTIONS +# endif +# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS) +# define nssv_CONFIG_NO_EXCEPTIONS 0 +# else +# define nssv_CONFIG_NO_EXCEPTIONS 1 +# endif +#endif + +// C++ language version detection (C++23 is speculative): +// Note: VC14.0/1900 (VS2015) lacks too much from C++14. + +#ifndef nssv_CPLUSPLUS +# if defined(_MSVC_LANG ) && !defined(__clang__) +# define nssv_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG ) +# else +# define nssv_CPLUSPLUS __cplusplus +# endif +#endif + +#define nssv_CPP98_OR_GREATER ( nssv_CPLUSPLUS >= 199711L ) +#define nssv_CPP11_OR_GREATER ( nssv_CPLUSPLUS >= 201103L ) +#define nssv_CPP11_OR_GREATER_ ( nssv_CPLUSPLUS >= 201103L ) +#define nssv_CPP14_OR_GREATER ( nssv_CPLUSPLUS >= 201402L ) +#define nssv_CPP17_OR_GREATER ( nssv_CPLUSPLUS >= 201703L ) +#define nssv_CPP20_OR_GREATER ( nssv_CPLUSPLUS >= 202002L ) +#define nssv_CPP23_OR_GREATER ( nssv_CPLUSPLUS >= 202300L ) + +// use C++17 std::string_view if available and requested: + +#if nssv_CPP17_OR_GREATER && defined(__has_include ) +# if __has_include( ) +# define nssv_HAVE_STD_STRING_VIEW 1 +# else +# define nssv_HAVE_STD_STRING_VIEW 0 +# endif +#else +# define nssv_HAVE_STD_STRING_VIEW 0 +#endif + +#define nssv_USES_STD_STRING_VIEW ( (nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_STD) || ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_DEFAULT) && nssv_HAVE_STD_STRING_VIEW) ) + +#define nssv_HAVE_STARTS_WITH ( nssv_CPP20_OR_GREATER || !nssv_USES_STD_STRING_VIEW ) +#define nssv_HAVE_ENDS_WITH nssv_HAVE_STARTS_WITH + +// +// Use C++17 std::string_view: +// + +#if nssv_USES_STD_STRING_VIEW + +#include + +// Extensions for std::string: + +#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS + +namespace nonstd { + +template< class CharT, class Traits, class Allocator = std::allocator > +std::basic_string +to_string( std::basic_string_view v, Allocator const & a = Allocator() ) +{ + return std::basic_string( v.begin(), v.end(), a ); +} + +template< class CharT, class Traits, class Allocator > +std::basic_string_view +to_string_view( std::basic_string const & s ) +{ + return std::basic_string_view( s.data(), s.size() ); +} + +// Literal operators sv and _sv: + +#if nssv_CONFIG_STD_SV_OPERATOR + +using namespace std::literals::string_view_literals; + +#endif + +#if nssv_CONFIG_USR_SV_OPERATOR + +inline namespace literals { +inline namespace string_view_literals { + + +constexpr std::string_view operator "" _sv( const char* str, size_t len ) noexcept // (1) +{ + return std::string_view{ str, len }; +} + +constexpr std::u16string_view operator "" _sv( const char16_t* str, size_t len ) noexcept // (2) +{ + return std::u16string_view{ str, len }; +} + +constexpr std::u32string_view operator "" _sv( const char32_t* str, size_t len ) noexcept // (3) +{ + return std::u32string_view{ str, len }; +} + +constexpr std::wstring_view operator "" _sv( const wchar_t* str, size_t len ) noexcept // (4) +{ + return std::wstring_view{ str, len }; +} + +}} // namespace literals::string_view_literals + +#endif // nssv_CONFIG_USR_SV_OPERATOR + +} // namespace nonstd + +#endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS + +namespace nonstd { + +using std::string_view; +using std::wstring_view; +using std::u16string_view; +using std::u32string_view; +using std::basic_string_view; + +// literal "sv" and "_sv", see above + +using std::operator==; +using std::operator!=; +using std::operator<; +using std::operator<=; +using std::operator>; +using std::operator>=; + +using std::operator<<; + +} // namespace nonstd + +#else // nssv_HAVE_STD_STRING_VIEW + +// +// Before C++17: use string_view lite: +// + +// Compiler versions: +// +// MSVC++ 6.0 _MSC_VER == 1200 nssv_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0) +// MSVC++ 7.0 _MSC_VER == 1300 nssv_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002) +// MSVC++ 7.1 _MSC_VER == 1310 nssv_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003) +// MSVC++ 8.0 _MSC_VER == 1400 nssv_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005) +// MSVC++ 9.0 _MSC_VER == 1500 nssv_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008) +// MSVC++ 10.0 _MSC_VER == 1600 nssv_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010) +// MSVC++ 11.0 _MSC_VER == 1700 nssv_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012) +// MSVC++ 12.0 _MSC_VER == 1800 nssv_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013) +// MSVC++ 14.0 _MSC_VER == 1900 nssv_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015) +// MSVC++ 14.1 _MSC_VER >= 1910 nssv_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017) +// MSVC++ 14.2 _MSC_VER >= 1920 nssv_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019) + +#if defined(_MSC_VER ) && !defined(__clang__) +# define nssv_COMPILER_MSVC_VER (_MSC_VER ) +# define nssv_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) ) +#else +# define nssv_COMPILER_MSVC_VER 0 +# define nssv_COMPILER_MSVC_VERSION 0 +#endif + +#define nssv_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) ) + +#if defined( __apple_build_version__ ) +# define nssv_COMPILER_APPLECLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) +# define nssv_COMPILER_CLANG_VERSION 0 +#elif defined( __clang__ ) +# define nssv_COMPILER_APPLECLANG_VERSION 0 +# define nssv_COMPILER_CLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) +#else +# define nssv_COMPILER_APPLECLANG_VERSION 0 +# define nssv_COMPILER_CLANG_VERSION 0 +#endif + +#if defined(__GNUC__) && !defined(__clang__) +# define nssv_COMPILER_GNUC_VERSION nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +#else +# define nssv_COMPILER_GNUC_VERSION 0 +#endif + +// half-open range [lo..hi): +#define nssv_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) ) + +// Presence of language and library features: + +#ifdef _HAS_CPP0X +# define nssv_HAS_CPP0X _HAS_CPP0X +#else +# define nssv_HAS_CPP0X 0 +#endif + +// Unless defined otherwise below, consider VC14 as C++11 for string-view-lite: + +#if nssv_COMPILER_MSVC_VER >= 1900 +# undef nssv_CPP11_OR_GREATER +# define nssv_CPP11_OR_GREATER 1 +#endif + +#define nssv_CPP11_90 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1500) +#define nssv_CPP11_100 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1600) +#define nssv_CPP11_110 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1700) +#define nssv_CPP11_120 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1800) +#define nssv_CPP11_140 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1900) +#define nssv_CPP11_141 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1910) + +#define nssv_CPP14_000 (nssv_CPP14_OR_GREATER) +#define nssv_CPP17_000 (nssv_CPP17_OR_GREATER) + +// Presence of C++11 language features: + +#define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140 +#define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140 +#define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140 +#define nssv_HAVE_IS_DEFAULT nssv_CPP11_140 +#define nssv_HAVE_IS_DELETE nssv_CPP11_140 +#define nssv_HAVE_NOEXCEPT nssv_CPP11_140 +#define nssv_HAVE_NULLPTR nssv_CPP11_100 +#define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140 +#define nssv_HAVE_UNICODE_LITERALS nssv_CPP11_140 +#define nssv_HAVE_USER_DEFINED_LITERALS nssv_CPP11_140 +#define nssv_HAVE_WCHAR16_T nssv_CPP11_100 +#define nssv_HAVE_WCHAR32_T nssv_CPP11_100 + +#if ! ( ( nssv_CPP11_OR_GREATER && nssv_COMPILER_CLANG_VERSION ) || nssv_BETWEEN( nssv_COMPILER_CLANG_VERSION, 300, 400 ) ) +# define nssv_HAVE_STD_DEFINED_LITERALS nssv_CPP11_140 +#else +# define nssv_HAVE_STD_DEFINED_LITERALS 0 +#endif + +// Presence of C++14 language features: + +#define nssv_HAVE_CONSTEXPR_14 nssv_CPP14_000 + +// Presence of C++17 language features: + +#define nssv_HAVE_NODISCARD nssv_CPP17_000 + +// Presence of C++ library features: + +#define nssv_HAVE_STD_HASH nssv_CPP11_120 + +// Presence of compiler intrinsics: + +// Providing char-type specializations for compare() and length() that +// use compiler intrinsics can improve compile- and run-time performance. +// +// The challenge is in using the right combinations of builtin availability +// and its constexpr-ness. +// +// | compiler | __builtin_memcmp (constexpr) | memcmp (constexpr) | +// |----------|------------------------------|---------------------| +// | clang | 4.0 (>= 4.0 ) | any (? ) | +// | clang-a | 9.0 (>= 9.0 ) | any (? ) | +// | gcc | any (constexpr) | any (? ) | +// | msvc | >= 14.2 C++17 (>= 14.2 ) | any (? ) | + +#define nssv_HAVE_BUILTIN_VER ( (nssv_CPP17_000 && nssv_COMPILER_MSVC_VERSION >= 142) || nssv_COMPILER_GNUC_VERSION > 0 || nssv_COMPILER_CLANG_VERSION >= 400 || nssv_COMPILER_APPLECLANG_VERSION >= 900 ) +#define nssv_HAVE_BUILTIN_CE ( nssv_HAVE_BUILTIN_VER ) + +#define nssv_HAVE_BUILTIN_MEMCMP ( (nssv_HAVE_CONSTEXPR_14 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_14 ) +#define nssv_HAVE_BUILTIN_STRLEN ( (nssv_HAVE_CONSTEXPR_11 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_11 ) + +#ifdef __has_builtin +# define nssv_HAVE_BUILTIN( x ) __has_builtin( x ) +#else +# define nssv_HAVE_BUILTIN( x ) 0 +#endif + +#if nssv_HAVE_BUILTIN(__builtin_memcmp) || nssv_HAVE_BUILTIN_VER +# define nssv_BUILTIN_MEMCMP __builtin_memcmp +#else +# define nssv_BUILTIN_MEMCMP memcmp +#endif + +#if nssv_HAVE_BUILTIN(__builtin_strlen) || nssv_HAVE_BUILTIN_VER +# define nssv_BUILTIN_STRLEN __builtin_strlen +#else +# define nssv_BUILTIN_STRLEN strlen +#endif + +// C++ feature usage: + +#if nssv_HAVE_CONSTEXPR_11 +# define nssv_constexpr constexpr +#else +# define nssv_constexpr /*constexpr*/ +#endif + +#if nssv_HAVE_CONSTEXPR_14 +# define nssv_constexpr14 constexpr +#else +# define nssv_constexpr14 /*constexpr*/ +#endif + +#if nssv_HAVE_EXPLICIT_CONVERSION +# define nssv_explicit explicit +#else +# define nssv_explicit /*explicit*/ +#endif + +#if nssv_HAVE_INLINE_NAMESPACE +# define nssv_inline_ns inline +#else +# define nssv_inline_ns /*inline*/ +#endif + +#if nssv_HAVE_NOEXCEPT +# define nssv_noexcept noexcept +#else +# define nssv_noexcept /*noexcept*/ +#endif + +//#if nssv_HAVE_REF_QUALIFIER +//# define nssv_ref_qual & +//# define nssv_refref_qual && +//#else +//# define nssv_ref_qual /*&*/ +//# define nssv_refref_qual /*&&*/ +//#endif + +#if nssv_HAVE_NULLPTR +# define nssv_nullptr nullptr +#else +# define nssv_nullptr NULL +#endif + +#if nssv_HAVE_NODISCARD +# define nssv_nodiscard [[nodiscard]] +#else +# define nssv_nodiscard /*[[nodiscard]]*/ +#endif + +// Additional includes: + +#include +#include +#include +#include +#include // std::char_traits<> + +#if ! nssv_CONFIG_NO_STREAM_INSERTION +# include +#endif + +#if ! nssv_CONFIG_NO_EXCEPTIONS +# include +#endif + +#if nssv_CPP11_OR_GREATER +# include +#endif + +// Clang, GNUC, MSVC warning suppression macros: + +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wreserved-user-defined-literal" +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wuser-defined-literals" +#elif nssv_COMPILER_GNUC_VERSION >= 480 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wliteral-suffix" +#endif // __clang__ + +#if nssv_COMPILER_MSVC_VERSION >= 140 +# define nssv_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]] +# define nssv_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress: code) ) +# define nssv_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable: codes)) +#else +# define nssv_SUPPRESS_MSGSL_WARNING(expr) +# define nssv_SUPPRESS_MSVC_WARNING(code, descr) +# define nssv_DISABLE_MSVC_WARNINGS(codes) +#endif + +#if defined(__clang__) +# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop") +#elif nssv_COMPILER_GNUC_VERSION >= 480 +# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop") +#elif nssv_COMPILER_MSVC_VERSION >= 140 +# define nssv_RESTORE_WARNINGS() __pragma(warning(pop )) +#else +# define nssv_RESTORE_WARNINGS() +#endif + +// Suppress the following MSVC (GSL) warnings: +// - C4455, non-gsl : 'operator ""sv': literal suffix identifiers that do not +// start with an underscore are reserved +// - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions; +// use brace initialization, gsl::narrow_cast or gsl::narow +// - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead + +nssv_DISABLE_MSVC_WARNINGS( 4455 26481 26472 ) +//nssv_DISABLE_CLANG_WARNINGS( "-Wuser-defined-literals" ) +//nssv_DISABLE_GNUC_WARNINGS( -Wliteral-suffix ) + +namespace nonstd { namespace sv_lite { + +// +// basic_string_view declaration: +// + +template +< + class CharT, + class Traits = std::char_traits +> +class basic_string_view; + +namespace detail { + +// support constexpr comparison in C++14; +// for C++17 and later, use provided traits: + +template< typename CharT > +inline nssv_constexpr14 int compare( CharT const * s1, CharT const * s2, std::size_t count ) +{ + while ( count-- != 0 ) + { + if ( *s1 < *s2 ) return -1; + if ( *s1 > *s2 ) return +1; + ++s1; ++s2; + } + return 0; +} + +#if nssv_HAVE_BUILTIN_MEMCMP + +// specialization of compare() for char, see also generic compare() above: + +inline nssv_constexpr14 int compare( char const * s1, char const * s2, std::size_t count ) +{ + return nssv_BUILTIN_MEMCMP( s1, s2, count ); +} + +#endif + +#if nssv_HAVE_BUILTIN_STRLEN + +// specialization of length() for char, see also generic length() further below: + +inline nssv_constexpr std::size_t length( char const * s ) +{ + return nssv_BUILTIN_STRLEN( s ); +} + +#endif + +#if defined(__OPTIMIZE__) + +// gcc, clang provide __OPTIMIZE__ +// Expect tail call optimization to make length() non-recursive: + +template< typename CharT > +inline nssv_constexpr std::size_t length( CharT * s, std::size_t result = 0 ) +{ + return *s == '\0' ? result : length( s + 1, result + 1 ); +} + +#else // OPTIMIZE + +// non-recursive: + +template< typename CharT > +inline nssv_constexpr14 std::size_t length( CharT * s ) +{ + std::size_t result = 0; + while ( *s++ != '\0' ) + { + ++result; + } + return result; +} + +#endif // OPTIMIZE + +#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER +#if defined(__OPTIMIZE__) + +// gcc, clang provide __OPTIMIZE__ +// Expect tail call optimization to make search() non-recursive: + +template< class CharT, class Traits = std::char_traits > +constexpr const CharT* search( basic_string_view haystack, basic_string_view needle ) +{ + return haystack.starts_with( needle ) ? haystack.begin() : + haystack.empty() ? haystack.end() : search( haystack.substr(1), needle ); +} + +#else // OPTIMIZE + +// non-recursive: + +#if nssv_CONFIG_CONSTEXPR11_STD_SEARCH + +template< class CharT, class Traits = std::char_traits > +constexpr const CharT* search( basic_string_view haystack, basic_string_view needle ) +{ + return std::search( haystack.begin(), haystack.end(), needle.begin(), needle.end() ); +} + +#else // nssv_CONFIG_CONSTEXPR11_STD_SEARCH + +template< class CharT, class Traits = std::char_traits > +nssv_constexpr14 const CharT* search( basic_string_view haystack, basic_string_view needle ) +{ + while ( needle.size() <= haystack.size() ) + { + if ( haystack.starts_with(needle) ) + { + return haystack.cbegin(); + } + haystack = basic_string_view{ haystack.begin() + 1, haystack.size() - 1U }; + } + return haystack.cend(); +} +#endif // nssv_CONFIG_CONSTEXPR11_STD_SEARCH + +#endif // OPTIMIZE +#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER + +} // namespace detail + +// +// basic_string_view: +// + +template +< + class CharT, + class Traits /* = std::char_traits */ +> +class basic_string_view +{ +public: + // Member types: + + typedef Traits traits_type; + typedef CharT value_type; + + typedef CharT * pointer; + typedef CharT const * const_pointer; + typedef CharT & reference; + typedef CharT const & const_reference; + + typedef const_pointer iterator; + typedef const_pointer const_iterator; + typedef std::reverse_iterator< const_iterator > reverse_iterator; + typedef std::reverse_iterator< const_iterator > const_reverse_iterator; + + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + // 24.4.2.1 Construction and assignment: + + nssv_constexpr basic_string_view() nssv_noexcept + : data_( nssv_nullptr ) + , size_( 0 ) + {} + +#if nssv_CPP11_OR_GREATER + nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept = default; +#else + nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept + : data_( other.data_) + , size_( other.size_) + {} +#endif + + nssv_constexpr basic_string_view( CharT const * s, size_type count ) nssv_noexcept // non-standard noexcept + : data_( s ) + , size_( count ) + {} + + nssv_constexpr basic_string_view( CharT const * s) nssv_noexcept // non-standard noexcept + : data_( s ) +#if nssv_CPP17_OR_GREATER + , size_( Traits::length(s) ) +#elif nssv_CPP11_OR_GREATER + , size_( detail::length(s) ) +#else + , size_( Traits::length(s) ) +#endif + {} + +#if nssv_HAVE_NULLPTR +# if nssv_HAVE_IS_DELETE + nssv_constexpr basic_string_view( std::nullptr_t ) nssv_noexcept = delete; +# else + private: nssv_constexpr basic_string_view( std::nullptr_t ) nssv_noexcept; public: +# endif +#endif + + // Assignment: + +#if nssv_CPP11_OR_GREATER + nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept = default; +#else + nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept + { + data_ = other.data_; + size_ = other.size_; + return *this; + } +#endif + + // 24.4.2.2 Iterator support: + + nssv_constexpr const_iterator begin() const nssv_noexcept { return data_; } + nssv_constexpr const_iterator end() const nssv_noexcept { return data_ + size_; } + + nssv_constexpr const_iterator cbegin() const nssv_noexcept { return begin(); } + nssv_constexpr const_iterator cend() const nssv_noexcept { return end(); } + + nssv_constexpr const_reverse_iterator rbegin() const nssv_noexcept { return const_reverse_iterator( end() ); } + nssv_constexpr const_reverse_iterator rend() const nssv_noexcept { return const_reverse_iterator( begin() ); } + + nssv_constexpr const_reverse_iterator crbegin() const nssv_noexcept { return rbegin(); } + nssv_constexpr const_reverse_iterator crend() const nssv_noexcept { return rend(); } + + // 24.4.2.3 Capacity: + + nssv_constexpr size_type size() const nssv_noexcept { return size_; } + nssv_constexpr size_type length() const nssv_noexcept { return size_; } + nssv_constexpr size_type max_size() const nssv_noexcept { return (std::numeric_limits< size_type >::max)(); } + + // since C++20 + nssv_nodiscard nssv_constexpr bool empty() const nssv_noexcept + { + return 0 == size_; + } + + // 24.4.2.4 Element access: + + nssv_constexpr const_reference operator[]( size_type pos ) const + { + return data_at( pos ); + } + + nssv_constexpr14 const_reference at( size_type pos ) const + { +#if nssv_CONFIG_NO_EXCEPTIONS + assert( pos < size() ); +#else + if ( pos >= size() ) + { + throw std::out_of_range("nonstd::string_view::at()"); + } +#endif + return data_at( pos ); + } + + nssv_constexpr const_reference front() const { return data_at( 0 ); } + nssv_constexpr const_reference back() const { return data_at( size() - 1 ); } + + nssv_constexpr const_pointer data() const nssv_noexcept { return data_; } + + // 24.4.2.5 Modifiers: + + nssv_constexpr14 void remove_prefix( size_type n ) + { + assert( n <= size() ); + data_ += n; + size_ -= n; + } + + nssv_constexpr14 void remove_suffix( size_type n ) + { + assert( n <= size() ); + size_ -= n; + } + + nssv_constexpr14 void swap( basic_string_view & other ) nssv_noexcept + { + const basic_string_view tmp(other); + other = *this; + *this = tmp; + } + + // 24.4.2.6 String operations: + + size_type copy( CharT * dest, size_type n, size_type pos = 0 ) const + { +#if nssv_CONFIG_NO_EXCEPTIONS + assert( pos <= size() ); +#else + if ( pos > size() ) + { + throw std::out_of_range("nonstd::string_view::copy()"); + } +#endif + const size_type rlen = (std::min)( n, size() - pos ); + + (void) Traits::copy( dest, data() + pos, rlen ); + + return rlen; + } + + nssv_constexpr14 basic_string_view substr( size_type pos = 0, size_type n = npos ) const + { +#if nssv_CONFIG_NO_EXCEPTIONS + assert( pos <= size() ); +#else + if ( pos > size() ) + { + throw std::out_of_range("nonstd::string_view::substr()"); + } +#endif + return basic_string_view( data() + pos, (std::min)( n, size() - pos ) ); + } + + // compare(), 6x: + + nssv_constexpr14 int compare( basic_string_view other ) const nssv_noexcept // (1) + { +#if nssv_CPP17_OR_GREATER + if ( const int result = Traits::compare( data(), other.data(), (std::min)( size(), other.size() ) ) ) +#else + if ( const int result = detail::compare( data(), other.data(), (std::min)( size(), other.size() ) ) ) +#endif + { + return result; + } + + return size() == other.size() ? 0 : size() < other.size() ? -1 : 1; + } + + nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other ) const // (2) + { + return substr( pos1, n1 ).compare( other ); + } + + nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other, size_type pos2, size_type n2 ) const // (3) + { + return substr( pos1, n1 ).compare( other.substr( pos2, n2 ) ); + } + + nssv_constexpr int compare( CharT const * s ) const // (4) + { + return compare( basic_string_view( s ) ); + } + + nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s ) const // (5) + { + return substr( pos1, n1 ).compare( basic_string_view( s ) ); + } + + nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s, size_type n2 ) const // (6) + { + return substr( pos1, n1 ).compare( basic_string_view( s, n2 ) ); + } + + // 24.4.2.7 Searching: + + // starts_with(), 3x, since C++20: + + nssv_constexpr bool starts_with( basic_string_view v ) const nssv_noexcept // (1) + { + return size() >= v.size() && compare( 0, v.size(), v ) == 0; + } + + nssv_constexpr bool starts_with( CharT c ) const nssv_noexcept // (2) + { + return starts_with( basic_string_view( &c, 1 ) ); + } + + nssv_constexpr bool starts_with( CharT const * s ) const // (3) + { + return starts_with( basic_string_view( s ) ); + } + + // ends_with(), 3x, since C++20: + + nssv_constexpr bool ends_with( basic_string_view v ) const nssv_noexcept // (1) + { + return size() >= v.size() && compare( size() - v.size(), npos, v ) == 0; + } + + nssv_constexpr bool ends_with( CharT c ) const nssv_noexcept // (2) + { + return ends_with( basic_string_view( &c, 1 ) ); + } + + nssv_constexpr bool ends_with( CharT const * s ) const // (3) + { + return ends_with( basic_string_view( s ) ); + } + + // find(), 4x: + + nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1) + { + return assert( v.size() == 0 || v.data() != nssv_nullptr ) + , pos >= size() + ? npos : to_pos( +#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER + detail::search( substr(pos), v ) +#else + std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) +#endif + ); + } + + nssv_constexpr size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept // (2) + { + return find( basic_string_view( &c, 1 ), pos ); + } + + nssv_constexpr size_type find( CharT const * s, size_type pos, size_type n ) const // (3) + { + return find( basic_string_view( s, n ), pos ); + } + + nssv_constexpr size_type find( CharT const * s, size_type pos = 0 ) const // (4) + { + return find( basic_string_view( s ), pos ); + } + + // rfind(), 4x: + + nssv_constexpr14 size_type rfind( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1) + { + if ( size() < v.size() ) + { + return npos; + } + + if ( v.empty() ) + { + return (std::min)( size(), pos ); + } + + const_iterator last = cbegin() + (std::min)( size() - v.size(), pos ) + v.size(); + const_iterator result = std::find_end( cbegin(), last, v.cbegin(), v.cend(), Traits::eq ); + + return result != last ? size_type( result - cbegin() ) : npos; + } + + nssv_constexpr14 size_type rfind( CharT c, size_type pos = npos ) const nssv_noexcept // (2) + { + return rfind( basic_string_view( &c, 1 ), pos ); + } + + nssv_constexpr14 size_type rfind( CharT const * s, size_type pos, size_type n ) const // (3) + { + return rfind( basic_string_view( s, n ), pos ); + } + + nssv_constexpr14 size_type rfind( CharT const * s, size_type pos = npos ) const // (4) + { + return rfind( basic_string_view( s ), pos ); + } + + // find_first_of(), 4x: + + nssv_constexpr size_type find_first_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1) + { + return pos >= size() + ? npos + : to_pos( std::find_first_of( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) ); + } + + nssv_constexpr size_type find_first_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2) + { + return find_first_of( basic_string_view( &c, 1 ), pos ); + } + + nssv_constexpr size_type find_first_of( CharT const * s, size_type pos, size_type n ) const // (3) + { + return find_first_of( basic_string_view( s, n ), pos ); + } + + nssv_constexpr size_type find_first_of( CharT const * s, size_type pos = 0 ) const // (4) + { + return find_first_of( basic_string_view( s ), pos ); + } + + // find_last_of(), 4x: + + nssv_constexpr size_type find_last_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1) + { + return empty() + ? npos + : pos >= size() + ? find_last_of( v, size() - 1 ) + : to_pos( std::find_first_of( const_reverse_iterator( cbegin() + pos + 1 ), crend(), v.cbegin(), v.cend(), Traits::eq ) ); + } + + nssv_constexpr size_type find_last_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2) + { + return find_last_of( basic_string_view( &c, 1 ), pos ); + } + + nssv_constexpr size_type find_last_of( CharT const * s, size_type pos, size_type count ) const // (3) + { + return find_last_of( basic_string_view( s, count ), pos ); + } + + nssv_constexpr size_type find_last_of( CharT const * s, size_type pos = npos ) const // (4) + { + return find_last_of( basic_string_view( s ), pos ); + } + + // find_first_not_of(), 4x: + + nssv_constexpr size_type find_first_not_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1) + { + return pos >= size() + ? npos + : to_pos( std::find_if( cbegin() + pos, cend(), not_in_view( v ) ) ); + } + + nssv_constexpr size_type find_first_not_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2) + { + return find_first_not_of( basic_string_view( &c, 1 ), pos ); + } + + nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos, size_type count ) const // (3) + { + return find_first_not_of( basic_string_view( s, count ), pos ); + } + + nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos = 0 ) const // (4) + { + return find_first_not_of( basic_string_view( s ), pos ); + } + + // find_last_not_of(), 4x: + + nssv_constexpr size_type find_last_not_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1) + { + return empty() + ? npos + : pos >= size() + ? find_last_not_of( v, size() - 1 ) + : to_pos( std::find_if( const_reverse_iterator( cbegin() + pos + 1 ), crend(), not_in_view( v ) ) ); + } + + nssv_constexpr size_type find_last_not_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2) + { + return find_last_not_of( basic_string_view( &c, 1 ), pos ); + } + + nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos, size_type count ) const // (3) + { + return find_last_not_of( basic_string_view( s, count ), pos ); + } + + nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos = npos ) const // (4) + { + return find_last_not_of( basic_string_view( s ), pos ); + } + + // Constants: + +#if nssv_CPP17_OR_GREATER + static nssv_constexpr size_type npos = size_type(-1); +#elif nssv_CPP11_OR_GREATER + enum : size_type { npos = size_type(-1) }; +#else + enum { npos = size_type(-1) }; +#endif + +private: + struct not_in_view + { + const basic_string_view v; + + nssv_constexpr explicit not_in_view( basic_string_view v_ ) : v( v_ ) {} + + nssv_constexpr bool operator()( CharT c ) const + { + return npos == v.find_first_of( c ); + } + }; + + nssv_constexpr size_type to_pos( const_iterator it ) const + { + return it == cend() ? npos : size_type( it - cbegin() ); + } + + nssv_constexpr size_type to_pos( const_reverse_iterator it ) const + { + return it == crend() ? npos : size_type( crend() - it - 1 ); + } + + nssv_constexpr const_reference data_at( size_type pos ) const + { +#if nssv_BETWEEN( nssv_COMPILER_GNUC_VERSION, 1, 500 ) + return data_[pos]; +#else + return assert( pos < size() ), data_[pos]; +#endif + } + +private: + const_pointer data_; + size_type size_; + +public: +#if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS + + template< class Allocator > + basic_string_view( std::basic_string const & s ) nssv_noexcept + : data_( s.data() ) + , size_( s.size() ) + {} + +#if nssv_HAVE_EXPLICIT_CONVERSION + + template< class Allocator > + explicit operator std::basic_string() const + { + return to_string( Allocator() ); + } + +#endif // nssv_HAVE_EXPLICIT_CONVERSION + +#if nssv_CPP11_OR_GREATER + + template< class Allocator = std::allocator > + std::basic_string + to_string( Allocator const & a = Allocator() ) const + { + return std::basic_string( begin(), end(), a ); + } + +#else + + std::basic_string + to_string() const + { + return std::basic_string( begin(), end() ); + } + + template< class Allocator > + std::basic_string + to_string( Allocator const & a ) const + { + return std::basic_string( begin(), end(), a ); + } + +#endif // nssv_CPP11_OR_GREATER + +#endif // nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS +}; + +// +// Non-member functions: +// + +// 24.4.3 Non-member comparison functions: +// lexicographically compare two string views (function template): + +template< class CharT, class Traits > +nssv_constexpr bool operator== ( + basic_string_view lhs, + basic_string_view rhs ) nssv_noexcept +{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } + +template< class CharT, class Traits > +nssv_constexpr bool operator!= ( + basic_string_view lhs, + basic_string_view rhs ) nssv_noexcept +{ return !( lhs == rhs ); } + +template< class CharT, class Traits > +nssv_constexpr bool operator< ( + basic_string_view lhs, + basic_string_view rhs ) nssv_noexcept +{ return lhs.compare( rhs ) < 0; } + +template< class CharT, class Traits > +nssv_constexpr bool operator<= ( + basic_string_view lhs, + basic_string_view rhs ) nssv_noexcept +{ return lhs.compare( rhs ) <= 0; } + +template< class CharT, class Traits > +nssv_constexpr bool operator> ( + basic_string_view lhs, + basic_string_view rhs ) nssv_noexcept +{ return lhs.compare( rhs ) > 0; } + +template< class CharT, class Traits > +nssv_constexpr bool operator>= ( + basic_string_view lhs, + basic_string_view rhs ) nssv_noexcept +{ return lhs.compare( rhs ) >= 0; } + +// Let S be basic_string_view, and sv be an instance of S. +// Implementations shall provide sufficient additional overloads marked +// constexpr and noexcept so that an object t with an implicit conversion +// to S can be compared according to Table 67. + +#if ! nssv_CPP11_OR_GREATER || nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 100, 141 ) + +// accommodate for older compilers: + +// == + +template< class CharT, class Traits> +nssv_constexpr bool operator==( + basic_string_view lhs, + CharT const * rhs ) nssv_noexcept +{ return lhs.size() == detail::length( rhs ) && lhs.compare( rhs ) == 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator==( + CharT const * lhs, + basic_string_view rhs ) nssv_noexcept +{ return detail::length( lhs ) == rhs.size() && rhs.compare( lhs ) == 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator==( + basic_string_view lhs, + std::basic_string rhs ) nssv_noexcept +{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator==( + std::basic_string rhs, + basic_string_view lhs ) nssv_noexcept +{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } + +// != + +template< class CharT, class Traits> +nssv_constexpr bool operator!=( + basic_string_view lhs, + CharT const * rhs ) nssv_noexcept +{ return !( lhs == rhs ); } + +template< class CharT, class Traits> +nssv_constexpr bool operator!=( + CharT const * lhs, + basic_string_view rhs ) nssv_noexcept +{ return !( lhs == rhs ); } + +template< class CharT, class Traits> +nssv_constexpr bool operator!=( + basic_string_view lhs, + std::basic_string rhs ) nssv_noexcept +{ return !( lhs == rhs ); } + +template< class CharT, class Traits> +nssv_constexpr bool operator!=( + std::basic_string rhs, + basic_string_view lhs ) nssv_noexcept +{ return !( lhs == rhs ); } + +// < + +template< class CharT, class Traits> +nssv_constexpr bool operator<( + basic_string_view lhs, + CharT const * rhs ) nssv_noexcept +{ return lhs.compare( rhs ) < 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator<( + CharT const * lhs, + basic_string_view rhs ) nssv_noexcept +{ return rhs.compare( lhs ) > 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator<( + basic_string_view lhs, + std::basic_string rhs ) nssv_noexcept +{ return lhs.compare( rhs ) < 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator<( + std::basic_string rhs, + basic_string_view lhs ) nssv_noexcept +{ return rhs.compare( lhs ) > 0; } + +// <= + +template< class CharT, class Traits> +nssv_constexpr bool operator<=( + basic_string_view lhs, + CharT const * rhs ) nssv_noexcept +{ return lhs.compare( rhs ) <= 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator<=( + CharT const * lhs, + basic_string_view rhs ) nssv_noexcept +{ return rhs.compare( lhs ) >= 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator<=( + basic_string_view lhs, + std::basic_string rhs ) nssv_noexcept +{ return lhs.compare( rhs ) <= 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator<=( + std::basic_string rhs, + basic_string_view lhs ) nssv_noexcept +{ return rhs.compare( lhs ) >= 0; } + +// > + +template< class CharT, class Traits> +nssv_constexpr bool operator>( + basic_string_view lhs, + CharT const * rhs ) nssv_noexcept +{ return lhs.compare( rhs ) > 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator>( + CharT const * lhs, + basic_string_view rhs ) nssv_noexcept +{ return rhs.compare( lhs ) < 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator>( + basic_string_view lhs, + std::basic_string rhs ) nssv_noexcept +{ return lhs.compare( rhs ) > 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator>( + std::basic_string rhs, + basic_string_view lhs ) nssv_noexcept +{ return rhs.compare( lhs ) < 0; } + +// >= + +template< class CharT, class Traits> +nssv_constexpr bool operator>=( + basic_string_view lhs, + CharT const * rhs ) nssv_noexcept +{ return lhs.compare( rhs ) >= 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator>=( + CharT const * lhs, + basic_string_view rhs ) nssv_noexcept +{ return rhs.compare( lhs ) <= 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator>=( + basic_string_view lhs, + std::basic_string rhs ) nssv_noexcept +{ return lhs.compare( rhs ) >= 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator>=( + std::basic_string rhs, + basic_string_view lhs ) nssv_noexcept +{ return rhs.compare( lhs ) <= 0; } + +#else // newer compilers: + +#define nssv_BASIC_STRING_VIEW_I(T,U) typename std::decay< basic_string_view >::type + +#if defined(_MSC_VER) // issue 40 +# define nssv_MSVC_ORDER(x) , int=x +#else +# define nssv_MSVC_ORDER(x) /*, int=x*/ +#endif + +// == + +template< class CharT, class Traits nssv_MSVC_ORDER(1) > +nssv_constexpr bool operator==( + basic_string_view lhs, + nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs ) nssv_noexcept +{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } + +template< class CharT, class Traits nssv_MSVC_ORDER(2) > +nssv_constexpr bool operator==( + nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, + basic_string_view rhs ) nssv_noexcept +{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } + +// != + +template< class CharT, class Traits nssv_MSVC_ORDER(1) > +nssv_constexpr bool operator!= ( + basic_string_view < CharT, Traits > lhs, + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept +{ return !( lhs == rhs ); } + +template< class CharT, class Traits nssv_MSVC_ORDER(2) > +nssv_constexpr bool operator!= ( + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, + basic_string_view < CharT, Traits > rhs ) nssv_noexcept +{ return !( lhs == rhs ); } + +// < + +template< class CharT, class Traits nssv_MSVC_ORDER(1) > +nssv_constexpr bool operator< ( + basic_string_view < CharT, Traits > lhs, + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept +{ return lhs.compare( rhs ) < 0; } + +template< class CharT, class Traits nssv_MSVC_ORDER(2) > +nssv_constexpr bool operator< ( + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, + basic_string_view < CharT, Traits > rhs ) nssv_noexcept +{ return lhs.compare( rhs ) < 0; } + +// <= + +template< class CharT, class Traits nssv_MSVC_ORDER(1) > +nssv_constexpr bool operator<= ( + basic_string_view < CharT, Traits > lhs, + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept +{ return lhs.compare( rhs ) <= 0; } + +template< class CharT, class Traits nssv_MSVC_ORDER(2) > +nssv_constexpr bool operator<= ( + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, + basic_string_view < CharT, Traits > rhs ) nssv_noexcept +{ return lhs.compare( rhs ) <= 0; } + +// > + +template< class CharT, class Traits nssv_MSVC_ORDER(1) > +nssv_constexpr bool operator> ( + basic_string_view < CharT, Traits > lhs, + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept +{ return lhs.compare( rhs ) > 0; } + +template< class CharT, class Traits nssv_MSVC_ORDER(2) > +nssv_constexpr bool operator> ( + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, + basic_string_view < CharT, Traits > rhs ) nssv_noexcept +{ return lhs.compare( rhs ) > 0; } + +// >= + +template< class CharT, class Traits nssv_MSVC_ORDER(1) > +nssv_constexpr bool operator>= ( + basic_string_view < CharT, Traits > lhs, + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept +{ return lhs.compare( rhs ) >= 0; } + +template< class CharT, class Traits nssv_MSVC_ORDER(2) > +nssv_constexpr bool operator>= ( + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, + basic_string_view < CharT, Traits > rhs ) nssv_noexcept +{ return lhs.compare( rhs ) >= 0; } + +#undef nssv_MSVC_ORDER +#undef nssv_BASIC_STRING_VIEW_I + +#endif // compiler-dependent approach to comparisons + +// 24.4.4 Inserters and extractors: + +#if ! nssv_CONFIG_NO_STREAM_INSERTION + +namespace detail { + +template< class Stream > +void write_padding( Stream & os, std::streamsize n ) +{ + for ( std::streamsize i = 0; i < n; ++i ) + os.rdbuf()->sputc( os.fill() ); +} + +template< class Stream, class View > +Stream & write_to_stream( Stream & os, View const & sv ) +{ + typename Stream::sentry sentry( os ); + + if ( !sentry ) + return os; + + const std::streamsize length = static_cast( sv.length() ); + + // Whether, and how, to pad: + const bool pad = ( length < os.width() ); + const bool left_pad = pad && ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::right; + + if ( left_pad ) + write_padding( os, os.width() - length ); + + // Write span characters: + os.rdbuf()->sputn( sv.begin(), length ); + + if ( pad && !left_pad ) + write_padding( os, os.width() - length ); + + // Reset output stream width: + os.width( 0 ); + + return os; +} + +} // namespace detail + +template< class CharT, class Traits > +std::basic_ostream & +operator<<( + std::basic_ostream& os, + basic_string_view sv ) +{ + return detail::write_to_stream( os, sv ); +} + +#endif // nssv_CONFIG_NO_STREAM_INSERTION + +// Several typedefs for common character types are provided: + +typedef basic_string_view string_view; +typedef basic_string_view wstring_view; +#if nssv_HAVE_WCHAR16_T +typedef basic_string_view u16string_view; +typedef basic_string_view u32string_view; +#endif + +}} // namespace nonstd::sv_lite + +// +// 24.4.6 Suffix for basic_string_view literals: +// + +#if nssv_HAVE_USER_DEFINED_LITERALS + +namespace nonstd { +nssv_inline_ns namespace literals { +nssv_inline_ns namespace string_view_literals { + +#if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS + +nssv_constexpr nonstd::sv_lite::string_view operator "" sv( const char* str, size_t len ) nssv_noexcept // (1) +{ + return nonstd::sv_lite::string_view{ str, len }; +} + +nssv_constexpr nonstd::sv_lite::u16string_view operator "" sv( const char16_t* str, size_t len ) nssv_noexcept // (2) +{ + return nonstd::sv_lite::u16string_view{ str, len }; +} + +nssv_constexpr nonstd::sv_lite::u32string_view operator "" sv( const char32_t* str, size_t len ) nssv_noexcept // (3) +{ + return nonstd::sv_lite::u32string_view{ str, len }; +} + +nssv_constexpr nonstd::sv_lite::wstring_view operator "" sv( const wchar_t* str, size_t len ) nssv_noexcept // (4) +{ + return nonstd::sv_lite::wstring_view{ str, len }; +} + +#endif // nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS + +#if nssv_CONFIG_USR_SV_OPERATOR + +nssv_constexpr nonstd::sv_lite::string_view operator "" _sv( const char* str, size_t len ) nssv_noexcept // (1) +{ + return nonstd::sv_lite::string_view{ str, len }; +} + +nssv_constexpr nonstd::sv_lite::u16string_view operator "" _sv( const char16_t* str, size_t len ) nssv_noexcept // (2) +{ + return nonstd::sv_lite::u16string_view{ str, len }; +} + +nssv_constexpr nonstd::sv_lite::u32string_view operator "" _sv( const char32_t* str, size_t len ) nssv_noexcept // (3) +{ + return nonstd::sv_lite::u32string_view{ str, len }; +} + +nssv_constexpr nonstd::sv_lite::wstring_view operator "" _sv( const wchar_t* str, size_t len ) nssv_noexcept // (4) +{ + return nonstd::sv_lite::wstring_view{ str, len }; +} + +#endif // nssv_CONFIG_USR_SV_OPERATOR + +}}} // namespace nonstd::literals::string_view_literals + +#endif + +// +// Extensions for std::string: +// + +#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS + +namespace nonstd { +namespace sv_lite { + +// Exclude MSVC 14 (19.00): it yields ambiguous to_string(): + +#if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140 + +template< class CharT, class Traits, class Allocator = std::allocator > +std::basic_string +to_string( basic_string_view v, Allocator const & a = Allocator() ) +{ + return std::basic_string( v.begin(), v.end(), a ); +} + +#else + +template< class CharT, class Traits > +std::basic_string +to_string( basic_string_view v ) +{ + return std::basic_string( v.begin(), v.end() ); +} + +template< class CharT, class Traits, class Allocator > +std::basic_string +to_string( basic_string_view v, Allocator const & a ) +{ + return std::basic_string( v.begin(), v.end(), a ); +} + +#endif // nssv_CPP11_OR_GREATER + +template< class CharT, class Traits, class Allocator > +basic_string_view +to_string_view( std::basic_string const & s ) +{ + return basic_string_view( s.data(), s.size() ); +} + +}} // namespace nonstd::sv_lite + +#endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS + +// +// make types and algorithms available in namespace nonstd: +// + +namespace nonstd { + +using sv_lite::basic_string_view; +using sv_lite::string_view; +using sv_lite::wstring_view; + +#if nssv_HAVE_WCHAR16_T +using sv_lite::u16string_view; +#endif +#if nssv_HAVE_WCHAR32_T +using sv_lite::u32string_view; +#endif + +// literal "sv" + +using sv_lite::operator==; +using sv_lite::operator!=; +using sv_lite::operator<; +using sv_lite::operator<=; +using sv_lite::operator>; +using sv_lite::operator>=; + +#if ! nssv_CONFIG_NO_STREAM_INSERTION +using sv_lite::operator<<; +#endif + +#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS +using sv_lite::to_string; +using sv_lite::to_string_view; +#endif + +} // namespace nonstd + +// 24.4.5 Hash support (C++11): + +// Note: The hash value of a string view object is equal to the hash value of +// the corresponding string object. + +#if nssv_HAVE_STD_HASH + +#include + +namespace std { + +template<> +struct hash< nonstd::string_view > +{ +public: + std::size_t operator()( nonstd::string_view v ) const nssv_noexcept + { + return std::hash()( std::string( v.data(), v.size() ) ); + } +}; + +template<> +struct hash< nonstd::wstring_view > +{ +public: + std::size_t operator()( nonstd::wstring_view v ) const nssv_noexcept + { + return std::hash()( std::wstring( v.data(), v.size() ) ); + } +}; + +template<> +struct hash< nonstd::u16string_view > +{ +public: + std::size_t operator()( nonstd::u16string_view v ) const nssv_noexcept + { + return std::hash()( std::u16string( v.data(), v.size() ) ); + } +}; + +template<> +struct hash< nonstd::u32string_view > +{ +public: + std::size_t operator()( nonstd::u32string_view v ) const nssv_noexcept + { + return std::hash()( std::u32string( v.data(), v.size() ) ); + } +}; + +} // namespace std + +#endif // nssv_HAVE_STD_HASH + +nssv_RESTORE_WARNINGS() + +#endif // nssv_HAVE_STD_STRING_VIEW +#endif // NONSTD_SV_LITE_H_INCLUDED +/* end file simdjson/nonstd/string_view.hpp */ +SIMDJSON_POP_DISABLE_WARNINGS + +namespace std { + using string_view = nonstd::string_view; +} +#endif // SIMDJSON_HAS_STRING_VIEW +#undef SIMDJSON_HAS_STRING_VIEW // We are not going to need this macro anymore. + +/// If EXPR is an error, returns it. +#define SIMDJSON_TRY(EXPR) { auto _err = (EXPR); if (_err) { return _err; } } + +// Unless the programmer has already set SIMDJSON_DEVELOPMENT_CHECKS, +// we want to set it under debug builds. We detect a debug build +// under Visual Studio when the _DEBUG macro is set. Under the other +// compilers, we use the fact that they define __OPTIMIZE__ whenever +// they allow optimizations. +// It is possible that this could miss some cases where SIMDJSON_DEVELOPMENT_CHECKS +// is helpful, but the programmer can set the macro SIMDJSON_DEVELOPMENT_CHECKS. +// It could also wrongly set SIMDJSON_DEVELOPMENT_CHECKS (e.g., if the programmer +// sets _DEBUG in a release build under Visual Studio, or if some compiler fails to +// set the __OPTIMIZE__ macro). +#ifndef SIMDJSON_DEVELOPMENT_CHECKS +#ifdef _MSC_VER +// Visual Studio seems to set _DEBUG for debug builds. +#ifdef _DEBUG +#define SIMDJSON_DEVELOPMENT_CHECKS 1 +#endif // _DEBUG +#else // _MSC_VER +// All other compilers appear to set __OPTIMIZE__ to a positive integer +// when the compiler is optimizing. +#ifndef __OPTIMIZE__ +#define SIMDJSON_DEVELOPMENT_CHECKS 1 +#endif // __OPTIMIZE__ +#endif // _MSC_VER +#endif // SIMDJSON_DEVELOPMENT_CHECKS + +// The SIMDJSON_CHECK_EOF macro is a feature flag for the "don't require padding" +// feature. + +#if SIMDJSON_CPLUSPLUS17 +// if we have C++, then fallthrough is a default attribute +# define simdjson_fallthrough [[fallthrough]] +// check if we have __attribute__ support +#elif defined(__has_attribute) +// check if we have the __fallthrough__ attribute +#if __has_attribute(__fallthrough__) +// we are good to go: +# define simdjson_fallthrough __attribute__((__fallthrough__)) +#endif // __has_attribute(__fallthrough__) +#endif // SIMDJSON_CPLUSPLUS17 +// on some systems, we simply do not have support for fallthrough, so use a default: +#ifndef simdjson_fallthrough +# define simdjson_fallthrough do {} while (0) /* fallthrough */ +#endif // simdjson_fallthrough + +#if SIMDJSON_DEVELOPMENT_CHECKS +#define SIMDJSON_DEVELOPMENT_ASSERT(expr) do { assert ((expr)); } while (0) +#else +#define SIMDJSON_DEVELOPMENT_ASSERT(expr) do { } while (0) +#endif + +#ifndef SIMDJSON_UTF8VALIDATION +#define SIMDJSON_UTF8VALIDATION 1 +#endif + +#ifdef __has_include +// How do we detect that a compiler supports vbmi2? +// For sure if the following header is found, we are ok? +#if __has_include() +#define SIMDJSON_COMPILER_SUPPORTS_VBMI2 1 +#endif +#endif + +#ifdef _MSC_VER +#if _MSC_VER >= 1920 +// Visual Studio 2019 and up support VBMI2 under x64 even if the header +// avx512vbmi2intrin.h is not found. +#define SIMDJSON_COMPILER_SUPPORTS_VBMI2 1 +#endif +#endif + +// By default, we allow AVX512. +#ifndef SIMDJSON_AVX512_ALLOWED +#define SIMDJSON_AVX512_ALLOWED 1 +#endif + +#endif // SIMDJSON_COMMON_DEFS_H +/* end file simdjson/common_defs.h */ +/* skipped duplicate #include "simdjson/compiler_check.h" */ +/* including simdjson/error.h: #include "simdjson/error.h" */ +/* begin file simdjson/error.h */ +#ifndef SIMDJSON_ERROR_H +#define SIMDJSON_ERROR_H + +/* skipped duplicate #include "simdjson/base.h" */ + +#include +#include + +namespace simdjson { + +/** + * All possible errors returned by simdjson. These error codes are subject to change + * and not all simdjson kernel returns the same error code given the same input: it is not + * well defined which error a given input should produce. + * + * Only SUCCESS evaluates to false as a Boolean. All other error codes will evaluate + * to true as a Boolean. + */ +enum error_code { + SUCCESS = 0, ///< No error + CAPACITY, ///< This parser can't support a document that big + MEMALLOC, ///< Error allocating memory, most likely out of memory + TAPE_ERROR, ///< Something went wrong, this is a generic error + DEPTH_ERROR, ///< Your document exceeds the user-specified depth limitation + STRING_ERROR, ///< Problem while parsing a string + T_ATOM_ERROR, ///< Problem while parsing an atom starting with the letter 't' + F_ATOM_ERROR, ///< Problem while parsing an atom starting with the letter 'f' + N_ATOM_ERROR, ///< Problem while parsing an atom starting with the letter 'n' + NUMBER_ERROR, ///< Problem while parsing a number + UTF8_ERROR, ///< the input is not valid UTF-8 + UNINITIALIZED, ///< unknown error, or uninitialized document + EMPTY, ///< no structural element found + UNESCAPED_CHARS, ///< found unescaped characters in a string. + UNCLOSED_STRING, ///< missing quote at the end + UNSUPPORTED_ARCHITECTURE, ///< unsupported architecture + INCORRECT_TYPE, ///< JSON element has a different type than user expected + NUMBER_OUT_OF_RANGE, ///< JSON number does not fit in 64 bits + INDEX_OUT_OF_BOUNDS, ///< JSON array index too large + NO_SUCH_FIELD, ///< JSON field not found in object + IO_ERROR, ///< Error reading a file + INVALID_JSON_POINTER, ///< Invalid JSON pointer reference + INVALID_URI_FRAGMENT, ///< Invalid URI fragment + UNEXPECTED_ERROR, ///< indicative of a bug in simdjson + PARSER_IN_USE, ///< parser is already in use. + OUT_OF_ORDER_ITERATION, ///< tried to iterate an array or object out of order (checked when SIMDJSON_DEVELOPMENT_CHECKS=1) + INSUFFICIENT_PADDING, ///< The JSON doesn't have enough padding for simdjson to safely parse it. + INCOMPLETE_ARRAY_OR_OBJECT, ///< The document ends early. + SCALAR_DOCUMENT_AS_VALUE, ///< A scalar document is treated as a value. + OUT_OF_BOUNDS, ///< Attempted to access location outside of document. + TRAILING_CONTENT, ///< Unexpected trailing content in the JSON input + NUM_ERROR_CODES +}; + +/** + * It is the convention throughout the code that the macro SIMDJSON_DEVELOPMENT_CHECKS determines whether + * we check for OUT_OF_ORDER_ITERATION. The logic behind it is that these errors only occurs when the code + * that was written while breaking some simdjson::ondemand requirement. They should not occur in released + * code after these issues were fixed. + */ + +/** + * Get the error message for the given error code. + * + * dom::parser parser; + * dom::element doc; + * auto error = parser.parse("foo",3).get(doc); + * if (error) { printf("Error: %s\n", error_message(error)); } + * + * @return The error message. + */ +inline const char *error_message(error_code error) noexcept; + +/** + * Write the error message to the output stream + */ +inline std::ostream& operator<<(std::ostream& out, error_code error) noexcept; + +/** + * Exception thrown when an exception-supporting simdjson method is called + */ +struct simdjson_error : public std::exception { + /** + * Create an exception from a simdjson error code. + * @param error The error code + */ + simdjson_error(error_code error) noexcept : _error{error} { } + /** The error message */ + const char *what() const noexcept { return error_message(error()); } + /** The error code */ + error_code error() const noexcept { return _error; } +private: + /** The error code that was used */ + error_code _error; +}; + +namespace internal { + +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + * + * This is a base class for implementations that want to add functions to the result type for + * chaining. + * + * Override like: + * + * struct simdjson_result : public internal::simdjson_result_base { + * simdjson_result() noexcept : internal::simdjson_result_base() {} + * simdjson_result(error_code error) noexcept : internal::simdjson_result_base(error) {} + * simdjson_result(T &&value) noexcept : internal::simdjson_result_base(std::forward(value)) {} + * simdjson_result(T &&value, error_code error) noexcept : internal::simdjson_result_base(value, error) {} + * // Your extra methods here + * } + * + * Then any method returning simdjson_result will be chainable with your methods. + */ +template +struct simdjson_result_base : protected std::pair { + + /** + * Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline simdjson_result_base() noexcept; + + /** + * Create a new error result. + */ + simdjson_inline simdjson_result_base(error_code error) noexcept; + + /** + * Create a new successful result. + */ + simdjson_inline simdjson_result_base(T &&value) noexcept; + + /** + * Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline simdjson_result_base(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; + +}; // struct simdjson_result_base + +} // namespace internal + +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + */ +template +struct simdjson_result : public internal::simdjson_result_base { + /** + * @private Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline simdjson_result() noexcept; + /** + * @private Create a new successful result. + */ + simdjson_inline simdjson_result(T &&value) noexcept; + /** + * @private Create a new error result. + */ + simdjson_inline simdjson_result(error_code error_code) noexcept; + /** + * @private Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline simdjson_result(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_warn_unused simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; + +}; // struct simdjson_result + +#if SIMDJSON_EXCEPTIONS + +template +inline std::ostream& operator<<(std::ostream& out, simdjson_result value) { return out << value.value(); } +#endif // SIMDJSON_EXCEPTIONS + +#ifndef SIMDJSON_DISABLE_DEPRECATED_API +/** + * @deprecated This is an alias and will be removed, use error_code instead + */ +using ErrorValues [[deprecated("This is an alias and will be removed, use error_code instead")]] = error_code; + +/** + * @deprecated Error codes should be stored and returned as `error_code`, use `error_message()` instead. + */ +[[deprecated("Error codes should be stored and returned as `error_code`, use `error_message()` instead.")]] +inline const std::string error_message(int error) noexcept; +#endif // SIMDJSON_DISABLE_DEPRECATED_API +} // namespace simdjson + +#endif // SIMDJSON_ERROR_H +/* end file simdjson/error.h */ +/* skipped duplicate #include "simdjson/portability.h" */ + +/** + * @brief The top level simdjson namespace, containing everything the library provides. + */ +namespace simdjson { + +SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS + +/** The maximum document size supported by simdjson. */ +constexpr size_t SIMDJSON_MAXSIZE_BYTES = 0xFFFFFFFF; + +/** + * The amount of padding needed in a buffer to parse JSON. + * + * The input buf should be readable up to buf + SIMDJSON_PADDING + * this is a stopgap; there should be a better description of the + * main loop and its behavior that abstracts over this + * See https://github.com/simdjson/simdjson/issues/174 + */ +constexpr size_t SIMDJSON_PADDING = 64; + +/** + * By default, simdjson supports this many nested objects and arrays. + * + * This is the default for parser::max_depth(). + */ +constexpr size_t DEFAULT_MAX_DEPTH = 1024; + +SIMDJSON_POP_DISABLE_UNUSED_WARNINGS + +class implementation; +struct padded_string; +class padded_string_view; +enum class stage1_mode; + +namespace internal { + +template +class atomic_ptr; +class dom_parser_implementation; +class escape_json_string; +class tape_ref; +struct value128; +enum class tape_type; + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_BASE_H +/* end file simdjson/base.h */ + +#endif // SIMDJSON_SRC_BASE_H +/* end file base.h */ + +SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS + +/* including to_chars.cpp: #include */ +/* begin file to_chars.cpp */ +#ifndef SIMDJSON_SRC_TO_CHARS_CPP +#define SIMDJSON_SRC_TO_CHARS_CPP + +/* skipped duplicate #include */ + +#include +#include +#include +#include + +namespace simdjson { +namespace internal { +/*! +implements the Grisu2 algorithm for binary to decimal floating-point +conversion. +Adapted from JSON for Modern C++ + +This implementation is a slightly modified version of the reference +implementation which may be obtained from +http://florian.loitsch.com/publications (bench.tar.gz). +The code is distributed under the MIT license, Copyright (c) 2009 Florian +Loitsch. For a detailed description of the algorithm see: [1] Loitsch, "Printing +Floating-Point Numbers Quickly and Accurately with Integers", Proceedings of the +ACM SIGPLAN 2010 Conference on Programming Language Design and Implementation, +PLDI 2010 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and +Accurately", Proceedings of the ACM SIGPLAN 1996 Conference on Programming +Language Design and Implementation, PLDI 1996 +*/ +namespace dtoa_impl { + +template +Target reinterpret_bits(const Source source) { + static_assert(sizeof(Target) == sizeof(Source), "size mismatch"); + + Target target; + std::memcpy(&target, &source, sizeof(Source)); + return target; +} + +struct diyfp // f * 2^e +{ + static constexpr int kPrecision = 64; // = q + + std::uint64_t f = 0; + int e = 0; + + constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {} + + /*! + @brief returns x - y + @pre x.e == y.e and x.f >= y.f + */ + static diyfp sub(const diyfp &x, const diyfp &y) noexcept { + + return {x.f - y.f, x.e}; + } + + /*! + @brief returns x * y + @note The result is rounded. (Only the upper q bits are returned.) + */ + static diyfp mul(const diyfp &x, const diyfp &y) noexcept { + static_assert(kPrecision == 64, "internal error"); + + // Computes: + // f = round((x.f * y.f) / 2^q) + // e = x.e + y.e + q + + // Emulate the 64-bit * 64-bit multiplication: + // + // p = u * v + // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi) + // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + + // 2^64 (u_hi v_hi ) = (p0 ) + 2^32 ((p1 ) + (p2 )) + // + 2^64 (p3 ) = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + + // 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 ) = + // (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + + // p2_hi + p3) = (p0_lo ) + 2^32 (Q ) + 2^64 (H ) = (p0_lo ) + + // 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H ) + // + // (Since Q might be larger than 2^32 - 1) + // + // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H) + // + // (Q_hi + H does not overflow a 64-bit int) + // + // = p_lo + 2^64 p_hi + + const std::uint64_t u_lo = x.f & 0xFFFFFFFFu; + const std::uint64_t u_hi = x.f >> 32u; + const std::uint64_t v_lo = y.f & 0xFFFFFFFFu; + const std::uint64_t v_hi = y.f >> 32u; + + const std::uint64_t p0 = u_lo * v_lo; + const std::uint64_t p1 = u_lo * v_hi; + const std::uint64_t p2 = u_hi * v_lo; + const std::uint64_t p3 = u_hi * v_hi; + + const std::uint64_t p0_hi = p0 >> 32u; + const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu; + const std::uint64_t p1_hi = p1 >> 32u; + const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu; + const std::uint64_t p2_hi = p2 >> 32u; + + std::uint64_t Q = p0_hi + p1_lo + p2_lo; + + // The full product might now be computed as + // + // p_hi = p3 + p2_hi + p1_hi + (Q >> 32) + // p_lo = p0_lo + (Q << 32) + // + // But in this particular case here, the full p_lo is not required. + // Effectively we only need to add the highest bit in p_lo to p_hi (and + // Q_hi + 1 does not overflow). + + Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up + + const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u); + + return {h, x.e + y.e + 64}; + } + + /*! + @brief normalize x such that the significand is >= 2^(q-1) + @pre x.f != 0 + */ + static diyfp normalize(diyfp x) noexcept { + + while ((x.f >> 63u) == 0) { + x.f <<= 1u; + x.e--; + } + + return x; + } + + /*! + @brief normalize x such that the result has the exponent E + @pre e >= x.e and the upper e - x.e bits of x.f must be zero. + */ + static diyfp normalize_to(const diyfp &x, + const int target_exponent) noexcept { + const int delta = x.e - target_exponent; + + return {x.f << delta, target_exponent}; + } +}; + +struct boundaries { + diyfp w; + diyfp minus; + diyfp plus; +}; + +/*! +Compute the (normalized) diyfp representing the input number 'value' and its +boundaries. +@pre value must be finite and positive +*/ +template boundaries compute_boundaries(FloatType value) { + + // Convert the IEEE representation into a diyfp. + // + // If v is denormal: + // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1)) + // If v is normalized: + // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1)) + + static_assert(std::numeric_limits::is_iec559, + "internal error: dtoa_short requires an IEEE-754 " + "floating-point implementation"); + + constexpr int kPrecision = + std::numeric_limits::digits; // = p (includes the hidden bit) + constexpr int kBias = + std::numeric_limits::max_exponent - 1 + (kPrecision - 1); + constexpr int kMinExp = 1 - kBias; + constexpr std::uint64_t kHiddenBit = std::uint64_t{1} + << (kPrecision - 1); // = 2^(p-1) + + using bits_type = typename std::conditional::type; + + const std::uint64_t bits = reinterpret_bits(value); + const std::uint64_t E = bits >> (kPrecision - 1); + const std::uint64_t F = bits & (kHiddenBit - 1); + + const bool is_denormal = E == 0; + const diyfp v = is_denormal + ? diyfp(F, kMinExp) + : diyfp(F + kHiddenBit, static_cast(E) - kBias); + + // Compute the boundaries m- and m+ of the floating-point value + // v = f * 2^e. + // + // Determine v- and v+, the floating-point predecessor and successor if v, + // respectively. + // + // v- = v - 2^e if f != 2^(p-1) or e == e_min (A) + // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B) + // + // v+ = v + 2^e + // + // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_ + // between m- and m+ round to v, regardless of how the input rounding + // algorithm breaks ties. + // + // ---+-------------+-------------+-------------+-------------+--- (A) + // v- m- v m+ v+ + // + // -----------------+------+------+-------------+-------------+--- (B) + // v- m- v m+ v+ + + const bool lower_boundary_is_closer = F == 0 && E > 1; + const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1); + const diyfp m_minus = lower_boundary_is_closer + ? diyfp(4 * v.f - 1, v.e - 2) // (B) + : diyfp(2 * v.f - 1, v.e - 1); // (A) + + // Determine the normalized w+ = m+. + const diyfp w_plus = diyfp::normalize(m_plus); + + // Determine w- = m- such that e_(w-) = e_(w+). + const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e); + + return {diyfp::normalize(v), w_minus, w_plus}; +} + +// Given normalized diyfp w, Grisu needs to find a (normalized) cached +// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies +// within a certain range [alpha, gamma] (Definition 3.2 from [1]) +// +// alpha <= e = e_c + e_w + q <= gamma +// +// or +// +// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q +// <= f_c * f_w * 2^gamma +// +// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies +// +// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma +// +// or +// +// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma) +// +// The choice of (alpha,gamma) determines the size of the table and the form of +// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well +// in practice: +// +// The idea is to cut the number c * w = f * 2^e into two parts, which can be +// processed independently: An integral part p1, and a fractional part p2: +// +// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e +// = (f div 2^-e) + (f mod 2^-e) * 2^e +// = p1 + p2 * 2^e +// +// The conversion of p1 into decimal form requires a series of divisions and +// modulos by (a power of) 10. These operations are faster for 32-bit than for +// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be +// achieved by choosing +// +// -e >= 32 or e <= -32 := gamma +// +// In order to convert the fractional part +// +// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ... +// +// into decimal form, the fraction is repeatedly multiplied by 10 and the digits +// d[-i] are extracted in order: +// +// (10 * p2) div 2^-e = d[-1] +// (10 * p2) mod 2^-e = d[-2] / 10^1 + ... +// +// The multiplication by 10 must not overflow. It is sufficient to choose +// +// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64. +// +// Since p2 = f mod 2^-e < 2^-e, +// +// -e <= 60 or e >= -60 := alpha + +constexpr int kAlpha = -60; +constexpr int kGamma = -32; + +struct cached_power // c = f * 2^e ~= 10^k +{ + std::uint64_t f; + int e; + int k; +}; + +/*! +For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached +power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c +satisfies (Definition 3.2 from [1]) + alpha <= e_c + e + q <= gamma. +*/ +inline cached_power get_cached_power_for_binary_exponent(int e) { + // Now + // + // alpha <= e_c + e + q <= gamma (1) + // ==> f_c * 2^alpha <= c * 2^e * 2^q + // + // and since the c's are normalized, 2^(q-1) <= f_c, + // + // ==> 2^(q - 1 + alpha) <= c * 2^(e + q) + // ==> 2^(alpha - e - 1) <= c + // + // If c were an exact power of ten, i.e. c = 10^k, one may determine k as + // + // k = ceil( log_10( 2^(alpha - e - 1) ) ) + // = ceil( (alpha - e - 1) * log_10(2) ) + // + // From the paper: + // "In theory the result of the procedure could be wrong since c is rounded, + // and the computation itself is approximated [...]. In practice, however, + // this simple function is sufficient." + // + // For IEEE double precision floating-point numbers converted into + // normalized diyfp's w = f * 2^e, with q = 64, + // + // e >= -1022 (min IEEE exponent) + // -52 (p - 1) + // -52 (p - 1, possibly normalize denormal IEEE numbers) + // -11 (normalize the diyfp) + // = -1137 + // + // and + // + // e <= +1023 (max IEEE exponent) + // -52 (p - 1) + // -11 (normalize the diyfp) + // = 960 + // + // This binary exponent range [-1137,960] results in a decimal exponent + // range [-307,324]. One does not need to store a cached power for each + // k in this range. For each such k it suffices to find a cached power + // such that the exponent of the product lies in [alpha,gamma]. + // This implies that the difference of the decimal exponents of adjacent + // table entries must be less than or equal to + // + // floor( (gamma - alpha) * log_10(2) ) = 8. + // + // (A smaller distance gamma-alpha would require a larger table.) + + // NB: + // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34. + + constexpr int kCachedPowersMinDecExp = -300; + constexpr int kCachedPowersDecStep = 8; + + static constexpr std::array kCachedPowers = {{ + {0xAB70FE17C79AC6CA, -1060, -300}, {0xFF77B1FCBEBCDC4F, -1034, -292}, + {0xBE5691EF416BD60C, -1007, -284}, {0x8DD01FAD907FFC3C, -980, -276}, + {0xD3515C2831559A83, -954, -268}, {0x9D71AC8FADA6C9B5, -927, -260}, + {0xEA9C227723EE8BCB, -901, -252}, {0xAECC49914078536D, -874, -244}, + {0x823C12795DB6CE57, -847, -236}, {0xC21094364DFB5637, -821, -228}, + {0x9096EA6F3848984F, -794, -220}, {0xD77485CB25823AC7, -768, -212}, + {0xA086CFCD97BF97F4, -741, -204}, {0xEF340A98172AACE5, -715, -196}, + {0xB23867FB2A35B28E, -688, -188}, {0x84C8D4DFD2C63F3B, -661, -180}, + {0xC5DD44271AD3CDBA, -635, -172}, {0x936B9FCEBB25C996, -608, -164}, + {0xDBAC6C247D62A584, -582, -156}, {0xA3AB66580D5FDAF6, -555, -148}, + {0xF3E2F893DEC3F126, -529, -140}, {0xB5B5ADA8AAFF80B8, -502, -132}, + {0x87625F056C7C4A8B, -475, -124}, {0xC9BCFF6034C13053, -449, -116}, + {0x964E858C91BA2655, -422, -108}, {0xDFF9772470297EBD, -396, -100}, + {0xA6DFBD9FB8E5B88F, -369, -92}, {0xF8A95FCF88747D94, -343, -84}, + {0xB94470938FA89BCF, -316, -76}, {0x8A08F0F8BF0F156B, -289, -68}, + {0xCDB02555653131B6, -263, -60}, {0x993FE2C6D07B7FAC, -236, -52}, + {0xE45C10C42A2B3B06, -210, -44}, {0xAA242499697392D3, -183, -36}, + {0xFD87B5F28300CA0E, -157, -28}, {0xBCE5086492111AEB, -130, -20}, + {0x8CBCCC096F5088CC, -103, -12}, {0xD1B71758E219652C, -77, -4}, + {0x9C40000000000000, -50, 4}, {0xE8D4A51000000000, -24, 12}, + {0xAD78EBC5AC620000, 3, 20}, {0x813F3978F8940984, 30, 28}, + {0xC097CE7BC90715B3, 56, 36}, {0x8F7E32CE7BEA5C70, 83, 44}, + {0xD5D238A4ABE98068, 109, 52}, {0x9F4F2726179A2245, 136, 60}, + {0xED63A231D4C4FB27, 162, 68}, {0xB0DE65388CC8ADA8, 189, 76}, + {0x83C7088E1AAB65DB, 216, 84}, {0xC45D1DF942711D9A, 242, 92}, + {0x924D692CA61BE758, 269, 100}, {0xDA01EE641A708DEA, 295, 108}, + {0xA26DA3999AEF774A, 322, 116}, {0xF209787BB47D6B85, 348, 124}, + {0xB454E4A179DD1877, 375, 132}, {0x865B86925B9BC5C2, 402, 140}, + {0xC83553C5C8965D3D, 428, 148}, {0x952AB45CFA97A0B3, 455, 156}, + {0xDE469FBD99A05FE3, 481, 164}, {0xA59BC234DB398C25, 508, 172}, + {0xF6C69A72A3989F5C, 534, 180}, {0xB7DCBF5354E9BECE, 561, 188}, + {0x88FCF317F22241E2, 588, 196}, {0xCC20CE9BD35C78A5, 614, 204}, + {0x98165AF37B2153DF, 641, 212}, {0xE2A0B5DC971F303A, 667, 220}, + {0xA8D9D1535CE3B396, 694, 228}, {0xFB9B7CD9A4A7443C, 720, 236}, + {0xBB764C4CA7A44410, 747, 244}, {0x8BAB8EEFB6409C1A, 774, 252}, + {0xD01FEF10A657842C, 800, 260}, {0x9B10A4E5E9913129, 827, 268}, + {0xE7109BFBA19C0C9D, 853, 276}, {0xAC2820D9623BF429, 880, 284}, + {0x80444B5E7AA7CF85, 907, 292}, {0xBF21E44003ACDD2D, 933, 300}, + {0x8E679C2F5E44FF8F, 960, 308}, {0xD433179D9C8CB841, 986, 316}, + {0x9E19DB92B4E31BA9, 1013, 324}, + }}; + + // This computation gives exactly the same results for k as + // k = ceil((kAlpha - e - 1) * 0.30102999566398114) + // for |e| <= 1500, but doesn't require floating-point operations. + // NB: log_10(2) ~= 78913 / 2^18 + const int f = kAlpha - e - 1; + const int k = (f * 78913) / (1 << 18) + static_cast(f > 0); + + const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / + kCachedPowersDecStep; + + const cached_power cached = kCachedPowers[static_cast(index)]; + + return cached; +} + +/*! +For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k. +For n == 0, returns 1 and sets pow10 := 1. +*/ +inline int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10) { + // LCOV_EXCL_START + if (n >= 1000000000) { + pow10 = 1000000000; + return 10; + } + // LCOV_EXCL_STOP + else if (n >= 100000000) { + pow10 = 100000000; + return 9; + } else if (n >= 10000000) { + pow10 = 10000000; + return 8; + } else if (n >= 1000000) { + pow10 = 1000000; + return 7; + } else if (n >= 100000) { + pow10 = 100000; + return 6; + } else if (n >= 10000) { + pow10 = 10000; + return 5; + } else if (n >= 1000) { + pow10 = 1000; + return 4; + } else if (n >= 100) { + pow10 = 100; + return 3; + } else if (n >= 10) { + pow10 = 10; + return 2; + } else { + pow10 = 1; + return 1; + } +} + +inline void grisu2_round(char *buf, int len, std::uint64_t dist, + std::uint64_t delta, std::uint64_t rest, + std::uint64_t ten_k) { + + // <--------------------------- delta ----> + // <---- dist ---------> + // --------------[------------------+-------------------]-------------- + // M- w M+ + // + // ten_k + // <------> + // <---- rest ----> + // --------------[------------------+----+--------------]-------------- + // w V + // = buf * 10^k + // + // ten_k represents a unit-in-the-last-place in the decimal representation + // stored in buf. + // Decrement buf by ten_k while this takes buf closer to w. + + // The tests are written in this order to avoid overflow in unsigned + // integer arithmetic. + + while (rest < dist && delta - rest >= ten_k && + (rest + ten_k < dist || dist - rest > rest + ten_k - dist)) { + buf[len - 1]--; + rest += ten_k; + } +} + +/*! +Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+. +M- and M+ must be normalized and share the same exponent -60 <= e <= -32. +*/ +inline void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, + diyfp M_minus, diyfp w, diyfp M_plus) { + static_assert(kAlpha >= -60, "internal error"); + static_assert(kGamma <= -32, "internal error"); + + // Generates the digits (and the exponent) of a decimal floating-point + // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's + // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= + // gamma. + // + // <--------------------------- delta ----> + // <---- dist ---------> + // --------------[------------------+-------------------]-------------- + // M- w M+ + // + // Grisu2 generates the digits of M+ from left to right and stops as soon as + // V is in [M-,M+]. + + std::uint64_t delta = + diyfp::sub(M_plus, M_minus) + .f; // (significand of (M+ - M-), implicit exponent is e) + std::uint64_t dist = + diyfp::sub(M_plus, w) + .f; // (significand of (M+ - w ), implicit exponent is e) + + // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0): + // + // M+ = f * 2^e + // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e + // = ((p1 ) * 2^-e + (p2 )) * 2^e + // = p1 + p2 * 2^e + + const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e); + + auto p1 = static_cast( + M_plus.f >> + -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.) + std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e + + // 1) + // + // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0] + + std::uint32_t pow10; + const int k = find_largest_pow10(p1, pow10); + + // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1) + // + // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1)) + // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1)) + // + // M+ = p1 + p2 * 2^e + // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e + // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e + // = d[k-1] * 10^(k-1) + ( rest) * 2^e + // + // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0) + // + // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0] + // + // but stop as soon as + // + // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e + + int n = k; + while (n > 0) { + // Invariants: + // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k) + // pow10 = 10^(n-1) <= p1 < 10^n + // + const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1) + const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1) + // + // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e + // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e) + // + buffer[length++] = static_cast('0' + d); // buffer := buffer * 10 + d + // + // M+ = buffer * 10^(n-1) + (r + p2 * 2^e) + // + p1 = r; + n--; + // + // M+ = buffer * 10^n + (p1 + p2 * 2^e) + // pow10 = 10^n + // + + // Now check if enough digits have been generated. + // Compute + // + // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e + // + // Note: + // Since rest and delta share the same exponent e, it suffices to + // compare the significands. + const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2; + if (rest <= delta) { + // V = buffer * 10^n, with M- <= V <= M+. + + decimal_exponent += n; + + // We may now just stop. But instead look if the buffer could be + // decremented to bring V closer to w. + // + // pow10 = 10^n is now 1 ulp in the decimal representation V. + // The rounding procedure works with diyfp's with an implicit + // exponent of e. + // + // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e + // + const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e; + grisu2_round(buffer, length, dist, delta, rest, ten_n); + + return; + } + + pow10 /= 10; + // + // pow10 = 10^(n-1) <= p1 < 10^n + // Invariants restored. + } + + // 2) + // + // The digits of the integral part have been generated: + // + // M+ = d[k-1]...d[1]d[0] + p2 * 2^e + // = buffer + p2 * 2^e + // + // Now generate the digits of the fractional part p2 * 2^e. + // + // Note: + // No decimal point is generated: the exponent is adjusted instead. + // + // p2 actually represents the fraction + // + // p2 * 2^e + // = p2 / 2^-e + // = d[-1] / 10^1 + d[-2] / 10^2 + ... + // + // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...) + // + // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m + // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...) + // + // using + // + // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e) + // = ( d) * 2^-e + ( r) + // + // or + // 10^m * p2 * 2^e = d + r * 2^e + // + // i.e. + // + // M+ = buffer + p2 * 2^e + // = buffer + 10^-m * (d + r * 2^e) + // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e + // + // and stop as soon as 10^-m * r * 2^e <= delta * 2^e + + int m = 0; + for (;;) { + // Invariant: + // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) + // * 2^e + // = buffer * 10^-m + 10^-m * (p2 ) + // * 2^e = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e = + // buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + + // (10*p2 mod 2^-e)) * 2^e + // + p2 *= 10; + const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e + const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e + // + // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e + // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e)) + // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e + // + buffer[length++] = static_cast('0' + d); // buffer := buffer * 10 + d + // + // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e + // + p2 = r; + m++; + // + // M+ = buffer * 10^-m + 10^-m * p2 * 2^e + // Invariant restored. + + // Check if enough digits have been generated. + // + // 10^-m * p2 * 2^e <= delta * 2^e + // p2 * 2^e <= 10^m * delta * 2^e + // p2 <= 10^m * delta + delta *= 10; + dist *= 10; + if (p2 <= delta) { + break; + } + } + + // V = buffer * 10^-m, with M- <= V <= M+. + + decimal_exponent -= m; + + // 1 ulp in the decimal representation is now 10^-m. + // Since delta and dist are now scaled by 10^m, we need to do the + // same with ulp in order to keep the units in sync. + // + // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e + // + const std::uint64_t ten_m = one.f; + grisu2_round(buffer, length, dist, delta, p2, ten_m); + + // By construction this algorithm generates the shortest possible decimal + // number (Loitsch, Theorem 6.2) which rounds back to w. + // For an input number of precision p, at least + // + // N = 1 + ceil(p * log_10(2)) + // + // decimal digits are sufficient to identify all binary floating-point + // numbers (Matula, "In-and-Out conversions"). + // This implies that the algorithm does not produce more than N decimal + // digits. + // + // N = 17 for p = 53 (IEEE double precision) + // N = 9 for p = 24 (IEEE single precision) +} + +/*! +v = buf * 10^decimal_exponent +len is the length of the buffer (number of decimal digits) +The buffer must be large enough, i.e. >= max_digits10. +*/ +inline void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, + diyfp v, diyfp m_plus) { + + // --------(-----------------------+-----------------------)-------- (A) + // m- v m+ + // + // --------------------(-----------+-----------------------)-------- (B) + // m- v m+ + // + // First scale v (and m- and m+) such that the exponent is in the range + // [alpha, gamma]. + + const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e); + + const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k + + // The exponent of the products is = v.e + c_minus_k.e + q and is in the range + // [alpha,gamma] + const diyfp w = diyfp::mul(v, c_minus_k); + const diyfp w_minus = diyfp::mul(m_minus, c_minus_k); + const diyfp w_plus = diyfp::mul(m_plus, c_minus_k); + + // ----(---+---)---------------(---+---)---------------(---+---)---- + // w- w w+ + // = c*m- = c*v = c*m+ + // + // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and + // w+ are now off by a small amount. + // In fact: + // + // w - v * 10^k < 1 ulp + // + // To account for this inaccuracy, add resp. subtract 1 ulp. + // + // --------+---[---------------(---+---)---------------]---+-------- + // w- M- w M+ w+ + // + // Now any number in [M-, M+] (bounds included) will round to w when input, + // regardless of how the input rounding algorithm breaks ties. + // + // And digit_gen generates the shortest possible such number in [M-, M+]. + // Note that this does not mean that Grisu2 always generates the shortest + // possible number in the interval (m-, m+). + const diyfp M_minus(w_minus.f + 1, w_minus.e); + const diyfp M_plus(w_plus.f - 1, w_plus.e); + + decimal_exponent = -cached.k; // = -(-k) = k + + grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus); +} + +/*! +v = buf * 10^decimal_exponent +len is the length of the buffer (number of decimal digits) +The buffer must be large enough, i.e. >= max_digits10. +*/ +template +void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value) { + static_assert(diyfp::kPrecision >= std::numeric_limits::digits + 3, + "internal error: not enough precision"); + + // If the neighbors (and boundaries) of 'value' are always computed for + // double-precision numbers, all float's can be recovered using strtod (and + // strtof). However, the resulting decimal representations are not exactly + // "short". + // + // The documentation for 'std::to_chars' + // (https://en.cppreference.com/w/cpp/utility/to_chars) says "value is + // converted to a string as if by std::sprintf in the default ("C") locale" + // and since sprintf promotes float's to double's, I think this is exactly + // what 'std::to_chars' does. On the other hand, the documentation for + // 'std::to_chars' requires that "parsing the representation using the + // corresponding std::from_chars function recovers value exactly". That + // indicates that single precision floating-point numbers should be recovered + // using 'std::strtof'. + // + // NB: If the neighbors are computed for single-precision numbers, there is a + // single float + // (7.0385307e-26f) which can't be recovered using strtod. The resulting + // double precision value is off by 1 ulp. +#if 0 + const boundaries w = compute_boundaries(static_cast(value)); +#else + const boundaries w = compute_boundaries(value); +#endif + + grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus); +} + +/*! +@brief appends a decimal representation of e to buf +@return a pointer to the element following the exponent. +@pre -1000 < e < 1000 +*/ +inline char *append_exponent(char *buf, int e) { + + if (e < 0) { + e = -e; + *buf++ = '-'; + } else { + *buf++ = '+'; + } + + auto k = static_cast(e); + if (k < 10) { + // Always print at least two digits in the exponent. + // This is for compatibility with printf("%g"). + *buf++ = '0'; + *buf++ = static_cast('0' + k); + } else if (k < 100) { + *buf++ = static_cast('0' + k / 10); + k %= 10; + *buf++ = static_cast('0' + k); + } else { + *buf++ = static_cast('0' + k / 100); + k %= 100; + *buf++ = static_cast('0' + k / 10); + k %= 10; + *buf++ = static_cast('0' + k); + } + + return buf; +} + +/*! +@brief prettify v = buf * 10^decimal_exponent +If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point +notation. Otherwise it will be printed in exponential notation. +@pre min_exp < 0 +@pre max_exp > 0 +*/ +inline char *format_buffer(char *buf, int len, int decimal_exponent, + int min_exp, int max_exp) { + + const int k = len; + const int n = len + decimal_exponent; + + // v = buf * 10^(n-k) + // k is the length of the buffer (number of decimal digits) + // n is the position of the decimal point relative to the start of the buffer. + + if (k <= n && n <= max_exp) { + // digits[000] + // len <= max_exp + 2 + + std::memset(buf + k, '0', static_cast(n) - static_cast(k)); + // Make it look like a floating-point number (#362, #378) + buf[n + 0] = '.'; + buf[n + 1] = '0'; + return buf + (static_cast(n)) + 2; + } + + if (0 < n && n <= max_exp) { + // dig.its + // len <= max_digits10 + 1 + std::memmove(buf + (static_cast(n) + 1), buf + n, + static_cast(k) - static_cast(n)); + buf[n] = '.'; + return buf + (static_cast(k) + 1U); + } + + if (min_exp < n && n <= 0) { + // 0.[000]digits + // len <= 2 + (-min_exp - 1) + max_digits10 + + std::memmove(buf + (2 + static_cast(-n)), buf, + static_cast(k)); + buf[0] = '0'; + buf[1] = '.'; + std::memset(buf + 2, '0', static_cast(-n)); + return buf + (2U + static_cast(-n) + static_cast(k)); + } + + if (k == 1) { + // dE+123 + // len <= 1 + 5 + + buf += 1; + } else { + // d.igitsE+123 + // len <= max_digits10 + 1 + 5 + + std::memmove(buf + 2, buf + 1, static_cast(k) - 1); + buf[1] = '.'; + buf += 1 + static_cast(k); + } + + *buf++ = 'e'; + return append_exponent(buf, n - 1); +} + +} // namespace dtoa_impl + +/*! +The format of the resulting decimal representation is similar to printf's %g +format. Returns an iterator pointing past-the-end of the decimal representation. +@note The input number must be finite, i.e. NaN's and Inf's are not supported. +@note The buffer must be large enough. +@note The result is NOT null-terminated. +*/ +char *to_chars(char *first, const char *last, double value) { + static_cast(last); // maybe unused - fix warning + bool negative = std::signbit(value); + if (negative) { + value = -value; + *first++ = '-'; + } + + if (value == 0) // +-0 + { + *first++ = '0'; + // Make it look like a floating-point number (#362, #378) + *first++ = '.'; + *first++ = '0'; + return first; + } + // Compute v = buffer * 10^decimal_exponent. + // The decimal digits are stored in the buffer, which needs to be interpreted + // as an unsigned decimal integer. + // len is the length of the buffer, i.e. the number of decimal digits. + int len = 0; + int decimal_exponent = 0; + dtoa_impl::grisu2(first, len, decimal_exponent, value); + // Format the buffer like printf("%.*g", prec, value) + constexpr int kMinExp = -4; + constexpr int kMaxExp = std::numeric_limits::digits10; + + return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, + kMaxExp); +} +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_SRC_TO_CHARS_CPP +/* end file to_chars.cpp */ +/* including from_chars.cpp: #include */ +/* begin file from_chars.cpp */ +#ifndef SIMDJSON_SRC_FROM_CHARS_CPP +#define SIMDJSON_SRC_FROM_CHARS_CPP + +/* skipped duplicate #include */ + +#include +#include +#include + +namespace simdjson { +namespace internal { + +/** + * The code in the internal::from_chars function is meant to handle the floating-point number parsing + * when we have more than 19 digits in the decimal mantissa. This should only be seen + * in adversarial scenarios: we do not expect production systems to even produce + * such floating-point numbers. + * + * The parser is based on work by Nigel Tao (at https://github.com/google/wuffs/) + * who credits Ken Thompson for the design (via a reference to the Go source + * code). See + * https://github.com/google/wuffs/blob/aa46859ea40c72516deffa1b146121952d6dfd3b/internal/cgen/base/floatconv-submodule-data.c + * https://github.com/google/wuffs/blob/46cd8105f47ca07ae2ba8e6a7818ef9c0df6c152/internal/cgen/base/floatconv-submodule-code.c + * It is probably not very fast but it is a fallback that should almost never be + * called in real life. Google Wuffs is published under APL 2.0. + **/ + +namespace { +constexpr uint32_t max_digits = 768; +constexpr int32_t decimal_point_range = 2047; +} // namespace + +struct adjusted_mantissa { + uint64_t mantissa; + int power2; + adjusted_mantissa() : mantissa(0), power2(0) {} +}; + +struct decimal { + uint32_t num_digits; + int32_t decimal_point; + bool negative; + bool truncated; + uint8_t digits[max_digits]; +}; + +template struct binary_format { + static constexpr int mantissa_explicit_bits(); + static constexpr int minimum_exponent(); + static constexpr int infinite_power(); + static constexpr int sign_index(); +}; + +template <> constexpr int binary_format::mantissa_explicit_bits() { + return 52; +} + +template <> constexpr int binary_format::minimum_exponent() { + return -1023; +} +template <> constexpr int binary_format::infinite_power() { + return 0x7FF; +} + +template <> constexpr int binary_format::sign_index() { return 63; } + +bool is_integer(char c) noexcept { return (c >= '0' && c <= '9'); } + +// This should always succeed since it follows a call to parse_number. +decimal parse_decimal(const char *&p) noexcept { + decimal answer; + answer.num_digits = 0; + answer.decimal_point = 0; + answer.truncated = false; + answer.negative = (*p == '-'); + if ((*p == '-') || (*p == '+')) { + ++p; + } + + while (*p == '0') { + ++p; + } + while (is_integer(*p)) { + if (answer.num_digits < max_digits) { + answer.digits[answer.num_digits] = uint8_t(*p - '0'); + } + answer.num_digits++; + ++p; + } + if (*p == '.') { + ++p; + const char *first_after_period = p; + // if we have not yet encountered a zero, we have to skip it as well + if (answer.num_digits == 0) { + // skip zeros + while (*p == '0') { + ++p; + } + } + while (is_integer(*p)) { + if (answer.num_digits < max_digits) { + answer.digits[answer.num_digits] = uint8_t(*p - '0'); + } + answer.num_digits++; + ++p; + } + answer.decimal_point = int32_t(first_after_period - p); + } + if(answer.num_digits > 0) { + const char *preverse = p - 1; + int32_t trailing_zeros = 0; + while ((*preverse == '0') || (*preverse == '.')) { + if(*preverse == '0') { trailing_zeros++; }; + --preverse; + } + answer.decimal_point += int32_t(answer.num_digits); + answer.num_digits -= uint32_t(trailing_zeros); + } + if(answer.num_digits > max_digits ) { + answer.num_digits = max_digits; + answer.truncated = true; + } + if (('e' == *p) || ('E' == *p)) { + ++p; + bool neg_exp = false; + if ('-' == *p) { + neg_exp = true; + ++p; + } else if ('+' == *p) { + ++p; + } + int32_t exp_number = 0; // exponential part + while (is_integer(*p)) { + uint8_t digit = uint8_t(*p - '0'); + if (exp_number < 0x10000) { + exp_number = 10 * exp_number + digit; + } + ++p; + } + answer.decimal_point += (neg_exp ? -exp_number : exp_number); + } + return answer; +} + +// This should always succeed since it follows a call to parse_number. +// Will not read at or beyond the "end" pointer. +decimal parse_decimal(const char *&p, const char * end) noexcept { + decimal answer; + answer.num_digits = 0; + answer.decimal_point = 0; + answer.truncated = false; + if(p == end) { return answer; } // should never happen + answer.negative = (*p == '-'); + if ((*p == '-') || (*p == '+')) { + ++p; + } + + while ((p != end) && (*p == '0')) { + ++p; + } + while ((p != end) && is_integer(*p)) { + if (answer.num_digits < max_digits) { + answer.digits[answer.num_digits] = uint8_t(*p - '0'); + } + answer.num_digits++; + ++p; + } + if ((p != end) && (*p == '.')) { + ++p; + if(p == end) { return answer; } // should never happen + const char *first_after_period = p; + // if we have not yet encountered a zero, we have to skip it as well + if (answer.num_digits == 0) { + // skip zeros + while (*p == '0') { + ++p; + } + } + while ((p != end) && is_integer(*p)) { + if (answer.num_digits < max_digits) { + answer.digits[answer.num_digits] = uint8_t(*p - '0'); + } + answer.num_digits++; + ++p; + } + answer.decimal_point = int32_t(first_after_period - p); + } + if(answer.num_digits > 0) { + const char *preverse = p - 1; + int32_t trailing_zeros = 0; + while ((*preverse == '0') || (*preverse == '.')) { + if(*preverse == '0') { trailing_zeros++; }; + --preverse; + } + answer.decimal_point += int32_t(answer.num_digits); + answer.num_digits -= uint32_t(trailing_zeros); + } + if(answer.num_digits > max_digits ) { + answer.num_digits = max_digits; + answer.truncated = true; + } + if ((p != end) && (('e' == *p) || ('E' == *p))) { + ++p; + if(p == end) { return answer; } // should never happen + bool neg_exp = false; + if ('-' == *p) { + neg_exp = true; + ++p; + } else if ('+' == *p) { + ++p; + } + int32_t exp_number = 0; // exponential part + while ((p != end) && is_integer(*p)) { + uint8_t digit = uint8_t(*p - '0'); + if (exp_number < 0x10000) { + exp_number = 10 * exp_number + digit; + } + ++p; + } + answer.decimal_point += (neg_exp ? -exp_number : exp_number); + } + return answer; +} + +namespace { + +// remove all final zeroes +inline void trim(decimal &h) { + while ((h.num_digits > 0) && (h.digits[h.num_digits - 1] == 0)) { + h.num_digits--; + } +} + +uint32_t number_of_digits_decimal_left_shift(decimal &h, uint32_t shift) { + shift &= 63; + const static uint16_t number_of_digits_decimal_left_shift_table[65] = { + 0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817, + 0x181D, 0x2024, 0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067, + 0x3073, 0x3080, 0x388E, 0x389C, 0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF, + 0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169, 0x5180, 0x5998, 0x59B0, + 0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B, 0x72AA, + 0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC, + 0x8C02, 0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C, + 0x051C, 0x051C, + }; + uint32_t x_a = number_of_digits_decimal_left_shift_table[shift]; + uint32_t x_b = number_of_digits_decimal_left_shift_table[shift + 1]; + uint32_t num_new_digits = x_a >> 11; + uint32_t pow5_a = 0x7FF & x_a; + uint32_t pow5_b = 0x7FF & x_b; + const static uint8_t + number_of_digits_decimal_left_shift_table_powers_of_5[0x051C] = { + 5, 2, 5, 1, 2, 5, 6, 2, 5, 3, 1, 2, 5, 1, 5, 6, 2, 5, 7, 8, 1, 2, 5, + 3, 9, 0, 6, 2, 5, 1, 9, 5, 3, 1, 2, 5, 9, 7, 6, 5, 6, 2, 5, 4, 8, 8, + 2, 8, 1, 2, 5, 2, 4, 4, 1, 4, 0, 6, 2, 5, 1, 2, 2, 0, 7, 0, 3, 1, 2, + 5, 6, 1, 0, 3, 5, 1, 5, 6, 2, 5, 3, 0, 5, 1, 7, 5, 7, 8, 1, 2, 5, 1, + 5, 2, 5, 8, 7, 8, 9, 0, 6, 2, 5, 7, 6, 2, 9, 3, 9, 4, 5, 3, 1, 2, 5, + 3, 8, 1, 4, 6, 9, 7, 2, 6, 5, 6, 2, 5, 1, 9, 0, 7, 3, 4, 8, 6, 3, 2, + 8, 1, 2, 5, 9, 5, 3, 6, 7, 4, 3, 1, 6, 4, 0, 6, 2, 5, 4, 7, 6, 8, 3, + 7, 1, 5, 8, 2, 0, 3, 1, 2, 5, 2, 3, 8, 4, 1, 8, 5, 7, 9, 1, 0, 1, 5, + 6, 2, 5, 1, 1, 9, 2, 0, 9, 2, 8, 9, 5, 5, 0, 7, 8, 1, 2, 5, 5, 9, 6, + 0, 4, 6, 4, 4, 7, 7, 5, 3, 9, 0, 6, 2, 5, 2, 9, 8, 0, 2, 3, 2, 2, 3, + 8, 7, 6, 9, 5, 3, 1, 2, 5, 1, 4, 9, 0, 1, 1, 6, 1, 1, 9, 3, 8, 4, 7, + 6, 5, 6, 2, 5, 7, 4, 5, 0, 5, 8, 0, 5, 9, 6, 9, 2, 3, 8, 2, 8, 1, 2, + 5, 3, 7, 2, 5, 2, 9, 0, 2, 9, 8, 4, 6, 1, 9, 1, 4, 0, 6, 2, 5, 1, 8, + 6, 2, 6, 4, 5, 1, 4, 9, 2, 3, 0, 9, 5, 7, 0, 3, 1, 2, 5, 9, 3, 1, 3, + 2, 2, 5, 7, 4, 6, 1, 5, 4, 7, 8, 5, 1, 5, 6, 2, 5, 4, 6, 5, 6, 6, 1, + 2, 8, 7, 3, 0, 7, 7, 3, 9, 2, 5, 7, 8, 1, 2, 5, 2, 3, 2, 8, 3, 0, 6, + 4, 3, 6, 5, 3, 8, 6, 9, 6, 2, 8, 9, 0, 6, 2, 5, 1, 1, 6, 4, 1, 5, 3, + 2, 1, 8, 2, 6, 9, 3, 4, 8, 1, 4, 4, 5, 3, 1, 2, 5, 5, 8, 2, 0, 7, 6, + 6, 0, 9, 1, 3, 4, 6, 7, 4, 0, 7, 2, 2, 6, 5, 6, 2, 5, 2, 9, 1, 0, 3, + 8, 3, 0, 4, 5, 6, 7, 3, 3, 7, 0, 3, 6, 1, 3, 2, 8, 1, 2, 5, 1, 4, 5, + 5, 1, 9, 1, 5, 2, 2, 8, 3, 6, 6, 8, 5, 1, 8, 0, 6, 6, 4, 0, 6, 2, 5, + 7, 2, 7, 5, 9, 5, 7, 6, 1, 4, 1, 8, 3, 4, 2, 5, 9, 0, 3, 3, 2, 0, 3, + 1, 2, 5, 3, 6, 3, 7, 9, 7, 8, 8, 0, 7, 0, 9, 1, 7, 1, 2, 9, 5, 1, 6, + 6, 0, 1, 5, 6, 2, 5, 1, 8, 1, 8, 9, 8, 9, 4, 0, 3, 5, 4, 5, 8, 5, 6, + 4, 7, 5, 8, 3, 0, 0, 7, 8, 1, 2, 5, 9, 0, 9, 4, 9, 4, 7, 0, 1, 7, 7, + 2, 9, 2, 8, 2, 3, 7, 9, 1, 5, 0, 3, 9, 0, 6, 2, 5, 4, 5, 4, 7, 4, 7, + 3, 5, 0, 8, 8, 6, 4, 6, 4, 1, 1, 8, 9, 5, 7, 5, 1, 9, 5, 3, 1, 2, 5, + 2, 2, 7, 3, 7, 3, 6, 7, 5, 4, 4, 3, 2, 3, 2, 0, 5, 9, 4, 7, 8, 7, 5, + 9, 7, 6, 5, 6, 2, 5, 1, 1, 3, 6, 8, 6, 8, 3, 7, 7, 2, 1, 6, 1, 6, 0, + 2, 9, 7, 3, 9, 3, 7, 9, 8, 8, 2, 8, 1, 2, 5, 5, 6, 8, 4, 3, 4, 1, 8, + 8, 6, 0, 8, 0, 8, 0, 1, 4, 8, 6, 9, 6, 8, 9, 9, 4, 1, 4, 0, 6, 2, 5, + 2, 8, 4, 2, 1, 7, 0, 9, 4, 3, 0, 4, 0, 4, 0, 0, 7, 4, 3, 4, 8, 4, 4, + 9, 7, 0, 7, 0, 3, 1, 2, 5, 1, 4, 2, 1, 0, 8, 5, 4, 7, 1, 5, 2, 0, 2, + 0, 0, 3, 7, 1, 7, 4, 2, 2, 4, 8, 5, 3, 5, 1, 5, 6, 2, 5, 7, 1, 0, 5, + 4, 2, 7, 3, 5, 7, 6, 0, 1, 0, 0, 1, 8, 5, 8, 7, 1, 1, 2, 4, 2, 6, 7, + 5, 7, 8, 1, 2, 5, 3, 5, 5, 2, 7, 1, 3, 6, 7, 8, 8, 0, 0, 5, 0, 0, 9, + 2, 9, 3, 5, 5, 6, 2, 1, 3, 3, 7, 8, 9, 0, 6, 2, 5, 1, 7, 7, 6, 3, 5, + 6, 8, 3, 9, 4, 0, 0, 2, 5, 0, 4, 6, 4, 6, 7, 7, 8, 1, 0, 6, 6, 8, 9, + 4, 5, 3, 1, 2, 5, 8, 8, 8, 1, 7, 8, 4, 1, 9, 7, 0, 0, 1, 2, 5, 2, 3, + 2, 3, 3, 8, 9, 0, 5, 3, 3, 4, 4, 7, 2, 6, 5, 6, 2, 5, 4, 4, 4, 0, 8, + 9, 2, 0, 9, 8, 5, 0, 0, 6, 2, 6, 1, 6, 1, 6, 9, 4, 5, 2, 6, 6, 7, 2, + 3, 6, 3, 2, 8, 1, 2, 5, 2, 2, 2, 0, 4, 4, 6, 0, 4, 9, 2, 5, 0, 3, 1, + 3, 0, 8, 0, 8, 4, 7, 2, 6, 3, 3, 3, 6, 1, 8, 1, 6, 4, 0, 6, 2, 5, 1, + 1, 1, 0, 2, 2, 3, 0, 2, 4, 6, 2, 5, 1, 5, 6, 5, 4, 0, 4, 2, 3, 6, 3, + 1, 6, 6, 8, 0, 9, 0, 8, 2, 0, 3, 1, 2, 5, 5, 5, 5, 1, 1, 1, 5, 1, 2, + 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5, 8, 3, 4, 0, 4, 5, 4, 1, + 0, 1, 5, 6, 2, 5, 2, 7, 7, 5, 5, 5, 7, 5, 6, 1, 5, 6, 2, 8, 9, 1, 3, + 5, 1, 0, 5, 9, 0, 7, 9, 1, 7, 0, 2, 2, 7, 0, 5, 0, 7, 8, 1, 2, 5, 1, + 3, 8, 7, 7, 7, 8, 7, 8, 0, 7, 8, 1, 4, 4, 5, 6, 7, 5, 5, 2, 9, 5, 3, + 9, 5, 8, 5, 1, 1, 3, 5, 2, 5, 3, 9, 0, 6, 2, 5, 6, 9, 3, 8, 8, 9, 3, + 9, 0, 3, 9, 0, 7, 2, 2, 8, 3, 7, 7, 6, 4, 7, 6, 9, 7, 9, 2, 5, 5, 6, + 7, 6, 2, 6, 9, 5, 3, 1, 2, 5, 3, 4, 6, 9, 4, 4, 6, 9, 5, 1, 9, 5, 3, + 6, 1, 4, 1, 8, 8, 8, 2, 3, 8, 4, 8, 9, 6, 2, 7, 8, 3, 8, 1, 3, 4, 7, + 6, 5, 6, 2, 5, 1, 7, 3, 4, 7, 2, 3, 4, 7, 5, 9, 7, 6, 8, 0, 7, 0, 9, + 4, 4, 1, 1, 9, 2, 4, 4, 8, 1, 3, 9, 1, 9, 0, 6, 7, 3, 8, 2, 8, 1, 2, + 5, 8, 6, 7, 3, 6, 1, 7, 3, 7, 9, 8, 8, 4, 0, 3, 5, 4, 7, 2, 0, 5, 9, + 6, 2, 2, 4, 0, 6, 9, 5, 9, 5, 3, 3, 6, 9, 1, 4, 0, 6, 2, 5, + }; + const uint8_t *pow5 = + &number_of_digits_decimal_left_shift_table_powers_of_5[pow5_a]; + uint32_t i = 0; + uint32_t n = pow5_b - pow5_a; + for (; i < n; i++) { + if (i >= h.num_digits) { + return num_new_digits - 1; + } else if (h.digits[i] == pow5[i]) { + continue; + } else if (h.digits[i] < pow5[i]) { + return num_new_digits - 1; + } else { + return num_new_digits; + } + } + return num_new_digits; +} + +} // end of anonymous namespace + +uint64_t round(decimal &h) { + if ((h.num_digits == 0) || (h.decimal_point < 0)) { + return 0; + } else if (h.decimal_point > 18) { + return UINT64_MAX; + } + // at this point, we know that h.decimal_point >= 0 + uint32_t dp = uint32_t(h.decimal_point); + uint64_t n = 0; + for (uint32_t i = 0; i < dp; i++) { + n = (10 * n) + ((i < h.num_digits) ? h.digits[i] : 0); + } + bool round_up = false; + if (dp < h.num_digits) { + round_up = h.digits[dp] >= 5; // normally, we round up + // but we may need to round to even! + if ((h.digits[dp] == 5) && (dp + 1 == h.num_digits)) { + round_up = h.truncated || ((dp > 0) && (1 & h.digits[dp - 1])); + } + } + if (round_up) { + n++; + } + return n; +} + +// computes h * 2^-shift +void decimal_left_shift(decimal &h, uint32_t shift) { + if (h.num_digits == 0) { + return; + } + uint32_t num_new_digits = number_of_digits_decimal_left_shift(h, shift); + int32_t read_index = int32_t(h.num_digits - 1); + uint32_t write_index = h.num_digits - 1 + num_new_digits; + uint64_t n = 0; + + while (read_index >= 0) { + n += uint64_t(h.digits[read_index]) << shift; + uint64_t quotient = n / 10; + uint64_t remainder = n - (10 * quotient); + if (write_index < max_digits) { + h.digits[write_index] = uint8_t(remainder); + } else if (remainder > 0) { + h.truncated = true; + } + n = quotient; + write_index--; + read_index--; + } + while (n > 0) { + uint64_t quotient = n / 10; + uint64_t remainder = n - (10 * quotient); + if (write_index < max_digits) { + h.digits[write_index] = uint8_t(remainder); + } else if (remainder > 0) { + h.truncated = true; + } + n = quotient; + write_index--; + } + h.num_digits += num_new_digits; + if (h.num_digits > max_digits) { + h.num_digits = max_digits; + } + h.decimal_point += int32_t(num_new_digits); + trim(h); +} + +// computes h * 2^shift +void decimal_right_shift(decimal &h, uint32_t shift) { + uint32_t read_index = 0; + uint32_t write_index = 0; + + uint64_t n = 0; + + while ((n >> shift) == 0) { + if (read_index < h.num_digits) { + n = (10 * n) + h.digits[read_index++]; + } else if (n == 0) { + return; + } else { + while ((n >> shift) == 0) { + n = 10 * n; + read_index++; + } + break; + } + } + h.decimal_point -= int32_t(read_index - 1); + if (h.decimal_point < -decimal_point_range) { // it is zero + h.num_digits = 0; + h.decimal_point = 0; + h.negative = false; + h.truncated = false; + return; + } + uint64_t mask = (uint64_t(1) << shift) - 1; + while (read_index < h.num_digits) { + uint8_t new_digit = uint8_t(n >> shift); + n = (10 * (n & mask)) + h.digits[read_index++]; + h.digits[write_index++] = new_digit; + } + while (n > 0) { + uint8_t new_digit = uint8_t(n >> shift); + n = 10 * (n & mask); + if (write_index < max_digits) { + h.digits[write_index++] = new_digit; + } else if (new_digit > 0) { + h.truncated = true; + } + } + h.num_digits = write_index; + trim(h); +} + +template adjusted_mantissa compute_float(decimal &d) { + adjusted_mantissa answer; + if (d.num_digits == 0) { + // should be zero + answer.power2 = 0; + answer.mantissa = 0; + return answer; + } + // At this point, going further, we can assume that d.num_digits > 0. + // We want to guard against excessive decimal point values because + // they can result in long running times. Indeed, we do + // shifts by at most 60 bits. We have that log(10**400)/log(2**60) ~= 22 + // which is fine, but log(10**299995)/log(2**60) ~= 16609 which is not + // fine (runs for a long time). + // + if(d.decimal_point < -324) { + // We have something smaller than 1e-324 which is always zero + // in binary64 and binary32. + // It should be zero. + answer.power2 = 0; + answer.mantissa = 0; + return answer; + } else if(d.decimal_point >= 310) { + // We have something at least as large as 0.1e310 which is + // always infinite. + answer.power2 = binary::infinite_power(); + answer.mantissa = 0; + return answer; + } + + static const uint32_t max_shift = 60; + static const uint32_t num_powers = 19; + static const uint8_t powers[19] = { + 0, 3, 6, 9, 13, 16, 19, 23, 26, 29, // + 33, 36, 39, 43, 46, 49, 53, 56, 59, // + }; + int32_t exp2 = 0; + while (d.decimal_point > 0) { + uint32_t n = uint32_t(d.decimal_point); + uint32_t shift = (n < num_powers) ? powers[n] : max_shift; + decimal_right_shift(d, shift); + if (d.decimal_point < -decimal_point_range) { + // should be zero + answer.power2 = 0; + answer.mantissa = 0; + return answer; + } + exp2 += int32_t(shift); + } + // We shift left toward [1/2 ... 1]. + while (d.decimal_point <= 0) { + uint32_t shift; + if (d.decimal_point == 0) { + if (d.digits[0] >= 5) { + break; + } + shift = (d.digits[0] < 2) ? 2 : 1; + } else { + uint32_t n = uint32_t(-d.decimal_point); + shift = (n < num_powers) ? powers[n] : max_shift; + } + decimal_left_shift(d, shift); + if (d.decimal_point > decimal_point_range) { + // we want to get infinity: + answer.power2 = 0xFF; + answer.mantissa = 0; + return answer; + } + exp2 -= int32_t(shift); + } + // We are now in the range [1/2 ... 1] but the binary format uses [1 ... 2]. + exp2--; + constexpr int32_t minimum_exponent = binary::minimum_exponent(); + while ((minimum_exponent + 1) > exp2) { + uint32_t n = uint32_t((minimum_exponent + 1) - exp2); + if (n > max_shift) { + n = max_shift; + } + decimal_right_shift(d, n); + exp2 += int32_t(n); + } + if ((exp2 - minimum_exponent) >= binary::infinite_power()) { + answer.power2 = binary::infinite_power(); + answer.mantissa = 0; + return answer; + } + + const int mantissa_size_in_bits = binary::mantissa_explicit_bits() + 1; + decimal_left_shift(d, mantissa_size_in_bits); + + uint64_t mantissa = round(d); + // It is possible that we have an overflow, in which case we need + // to shift back. + if (mantissa >= (uint64_t(1) << mantissa_size_in_bits)) { + decimal_right_shift(d, 1); + exp2 += 1; + mantissa = round(d); + if ((exp2 - minimum_exponent) >= binary::infinite_power()) { + answer.power2 = binary::infinite_power(); + answer.mantissa = 0; + return answer; + } + } + answer.power2 = exp2 - binary::minimum_exponent(); + if (mantissa < (uint64_t(1) << binary::mantissa_explicit_bits())) { + answer.power2--; + } + answer.mantissa = + mantissa & ((uint64_t(1) << binary::mantissa_explicit_bits()) - 1); + return answer; +} + +template +adjusted_mantissa parse_long_mantissa(const char *first) { + decimal d = parse_decimal(first); + return compute_float(d); +} + +template +adjusted_mantissa parse_long_mantissa(const char *first, const char *end) { + decimal d = parse_decimal(first, end); + return compute_float(d); +} + +double from_chars(const char *first) noexcept { + bool negative = first[0] == '-'; + if (negative) { + first++; + } + adjusted_mantissa am = parse_long_mantissa>(first); + uint64_t word = am.mantissa; + word |= uint64_t(am.power2) + << binary_format::mantissa_explicit_bits(); + word = negative ? word | (uint64_t(1) << binary_format::sign_index()) + : word; + double value; + std::memcpy(&value, &word, sizeof(double)); + return value; +} + + +double from_chars(const char *first, const char *end) noexcept { + bool negative = first[0] == '-'; + if (negative) { + first++; + } + adjusted_mantissa am = parse_long_mantissa>(first, end); + uint64_t word = am.mantissa; + word |= uint64_t(am.power2) + << binary_format::mantissa_explicit_bits(); + word = negative ? word | (uint64_t(1) << binary_format::sign_index()) + : word; + double value; + std::memcpy(&value, &word, sizeof(double)); + return value; +} + +} // internal +} // simdjson + +#endif // SIMDJSON_SRC_FROM_CHARS_CPP +/* end file from_chars.cpp */ +/* including internal/error_tables.cpp: #include */ +/* begin file internal/error_tables.cpp */ +#ifndef SIMDJSON_SRC_ERROR_TABLES_CPP +#define SIMDJSON_SRC_ERROR_TABLES_CPP + +/* including simdjson/internal/jsoncharutils_tables.h: #include */ +/* begin file simdjson/internal/jsoncharutils_tables.h */ +#ifndef SIMDJSON_INTERNAL_JSONCHARUTILS_TABLES_H +#define SIMDJSON_INTERNAL_JSONCHARUTILS_TABLES_H + +/* skipped duplicate #include "simdjson/base.h" */ + +#ifdef JSON_TEST_STRINGS +void found_string(const uint8_t *buf, const uint8_t *parsed_begin, + const uint8_t *parsed_end); +void found_bad_string(const uint8_t *buf); +#endif + +namespace simdjson { +namespace internal { +// structural chars here are +// they are { 0x7b } 0x7d : 0x3a [ 0x5b ] 0x5d , 0x2c (and NULL) +// we are also interested in the four whitespace characters +// space 0x20, linefeed 0x0a, horizontal tab 0x09 and carriage return 0x0d + +extern SIMDJSON_DLLIMPORTEXPORT const bool structural_or_whitespace_negated[256]; +extern SIMDJSON_DLLIMPORTEXPORT const bool structural_or_whitespace[256]; +extern SIMDJSON_DLLIMPORTEXPORT const uint32_t digit_to_val32[886]; + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_JSONCHARUTILS_TABLES_H +/* end file simdjson/internal/jsoncharutils_tables.h */ +/* including simdjson/error-inl.h: #include */ +/* begin file simdjson/error-inl.h */ +#ifndef SIMDJSON_ERROR_INL_H +#define SIMDJSON_ERROR_INL_H + +/* skipped duplicate #include "simdjson/error.h" */ + +#include + +namespace simdjson { +namespace internal { + // We store the error code so we can validate the error message is associated with the right code + struct error_code_info { + error_code code; + const char* message; // do not use a fancy std::string where a simple C string will do (no alloc, no destructor) + }; + // These MUST match the codes in error_code. We check this constraint in basictests. + extern SIMDJSON_DLLIMPORTEXPORT const error_code_info error_codes[]; +} // namespace internal + + +inline const char *error_message(error_code error) noexcept { + // If you're using error_code, we're trusting you got it from the enum. + return internal::error_codes[int(error)].message; +} + +// deprecated function +#ifndef SIMDJSON_DISABLE_DEPRECATED_API +inline const std::string error_message(int error) noexcept { + if (error < 0 || error >= error_code::NUM_ERROR_CODES) { + return internal::error_codes[UNEXPECTED_ERROR].message; + } + return internal::error_codes[error].message; +} +#endif // SIMDJSON_DISABLE_DEPRECATED_API + +inline std::ostream& operator<<(std::ostream& out, error_code error) noexcept { + return out << error_message(error); +} + +namespace internal { + +// +// internal::simdjson_result_base inline implementation +// + +template +simdjson_inline void simdjson_result_base::tie(T &value, error_code &error) && noexcept { + error = this->second; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +simdjson_warn_unused simdjson_inline error_code simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; +} + +template +simdjson_inline error_code simdjson_result_base::error() const noexcept { + return this->second; +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& simdjson_result_base::value() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return this->first; +} + +template +simdjson_inline T&& simdjson_result_base::value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline T&& simdjson_result_base::take_value() && noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return std::forward(this->first); +} + +template +simdjson_inline simdjson_result_base::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& simdjson_result_base::value_unsafe() const& noexcept { + return this->first; +} + +template +simdjson_inline T&& simdjson_result_base::value_unsafe() && noexcept { + return std::forward(this->first); +} + +template +simdjson_inline simdjson_result_base::simdjson_result_base(T &&value, error_code error) noexcept + : std::pair(std::forward(value), error) {} +template +simdjson_inline simdjson_result_base::simdjson_result_base(error_code error) noexcept + : simdjson_result_base(T{}, error) {} +template +simdjson_inline simdjson_result_base::simdjson_result_base(T &&value) noexcept + : simdjson_result_base(std::forward(value), SUCCESS) {} +template +simdjson_inline simdjson_result_base::simdjson_result_base() noexcept + : simdjson_result_base(T{}, UNINITIALIZED) {} + +} // namespace internal + +/// +/// simdjson_result inline implementation +/// + +template +simdjson_inline void simdjson_result::tie(T &value, error_code &error) && noexcept { + std::forward>(*this).tie(value, error); +} + +template +simdjson_warn_unused simdjson_inline error_code simdjson_result::get(T &value) && noexcept { + return std::forward>(*this).get(value); +} + +template +simdjson_inline error_code simdjson_result::error() const noexcept { + return internal::simdjson_result_base::error(); +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& simdjson_result::value() & noexcept(false) { + return internal::simdjson_result_base::value(); +} + +template +simdjson_inline T&& simdjson_result::value() && noexcept(false) { + return std::forward>(*this).value(); +} + +template +simdjson_inline T&& simdjson_result::take_value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline simdjson_result::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& simdjson_result::value_unsafe() const& noexcept { + return internal::simdjson_result_base::value_unsafe(); +} + +template +simdjson_inline T&& simdjson_result::value_unsafe() && noexcept { + return std::forward>(*this).value_unsafe(); +} + +template +simdjson_inline simdjson_result::simdjson_result(T &&value, error_code error) noexcept + : internal::simdjson_result_base(std::forward(value), error) {} +template +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : internal::simdjson_result_base(error) {} +template +simdjson_inline simdjson_result::simdjson_result(T &&value) noexcept + : internal::simdjson_result_base(std::forward(value)) {} +template +simdjson_inline simdjson_result::simdjson_result() noexcept + : internal::simdjson_result_base() {} + +} // namespace simdjson + +#endif // SIMDJSON_ERROR_INL_H +/* end file simdjson/error-inl.h */ + +namespace simdjson { +namespace internal { + + SIMDJSON_DLLIMPORTEXPORT const error_code_info error_codes[] { + { SUCCESS, "SUCCESS: No error" }, + { CAPACITY, "CAPACITY: This parser can't support a document that big" }, + { MEMALLOC, "MEMALLOC: Error allocating memory, we're most likely out of memory" }, + { TAPE_ERROR, "TAPE_ERROR: The JSON document has an improper structure: missing or superfluous commas, braces, missing keys, etc." }, + { DEPTH_ERROR, "DEPTH_ERROR: The JSON document was too deep (too many nested objects and arrays)" }, + { STRING_ERROR, "STRING_ERROR: Problem while parsing a string" }, + { T_ATOM_ERROR, "T_ATOM_ERROR: Problem while parsing an atom starting with the letter 't'" }, + { F_ATOM_ERROR, "F_ATOM_ERROR: Problem while parsing an atom starting with the letter 'f'" }, + { N_ATOM_ERROR, "N_ATOM_ERROR: Problem while parsing an atom starting with the letter 'n'" }, + { NUMBER_ERROR, "NUMBER_ERROR: Problem while parsing a number" }, + { UTF8_ERROR, "UTF8_ERROR: The input is not valid UTF-8" }, + { UNINITIALIZED, "UNINITIALIZED: Uninitialized" }, + { EMPTY, "EMPTY: no JSON found" }, + { UNESCAPED_CHARS, "UNESCAPED_CHARS: Within strings, some characters must be escaped, we found unescaped characters" }, + { UNCLOSED_STRING, "UNCLOSED_STRING: A string is opened, but never closed." }, + { UNSUPPORTED_ARCHITECTURE, "UNSUPPORTED_ARCHITECTURE: simdjson does not have an implementation supported by this CPU architecture. Please report this error to the core team as it should never happen." }, + { INCORRECT_TYPE, "INCORRECT_TYPE: The JSON element does not have the requested type." }, + { NUMBER_OUT_OF_RANGE, "NUMBER_OUT_OF_RANGE: The JSON number is too large or too small to fit within the requested type." }, + { INDEX_OUT_OF_BOUNDS, "INDEX_OUT_OF_BOUNDS: Attempted to access an element of a JSON array that is beyond its length." }, + { NO_SUCH_FIELD, "NO_SUCH_FIELD: The JSON field referenced does not exist in this object." }, + { IO_ERROR, "IO_ERROR: Error reading the file." }, + { INVALID_JSON_POINTER, "INVALID_JSON_POINTER: Invalid JSON pointer syntax." }, + { INVALID_URI_FRAGMENT, "INVALID_URI_FRAGMENT: Invalid URI fragment syntax." }, + { UNEXPECTED_ERROR, "UNEXPECTED_ERROR: Unexpected error, consider reporting this problem as you may have found a bug in simdjson" }, + { PARSER_IN_USE, "PARSER_IN_USE: Cannot parse a new document while a document is still in use." }, + { OUT_OF_ORDER_ITERATION, "OUT_OF_ORDER_ITERATION: Objects and arrays can only be iterated when they are first encountered." }, + { INSUFFICIENT_PADDING, "INSUFFICIENT_PADDING: simdjson requires the input JSON string to have at least SIMDJSON_PADDING extra bytes allocated, beyond the string's length. Consider using the simdjson::padded_string class if needed." }, + { INCOMPLETE_ARRAY_OR_OBJECT, "INCOMPLETE_ARRAY_OR_OBJECT: JSON document ended early in the middle of an object or array." }, + { SCALAR_DOCUMENT_AS_VALUE, "SCALAR_DOCUMENT_AS_VALUE: A JSON document made of a scalar (number, Boolean, null or string) is treated as a value. Use get_bool(), get_double(), etc. on the document instead. "}, + { OUT_OF_BOUNDS, "OUT_OF_BOUNDS: Attempt to access location outside of document."}, + { TRAILING_CONTENT, "TRAILING_CONTENT: Unexpected trailing content in the JSON input."} + }; // error_messages[] + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_SRC_ERROR_TABLES_CPP +/* end file internal/error_tables.cpp */ +/* including internal/jsoncharutils_tables.cpp: #include */ +/* begin file internal/jsoncharutils_tables.cpp */ +#ifndef SIMDJSON_SRC_JSONCHARUTILS_TABLES_CPP +#define SIMDJSON_SRC_JSONCHARUTILS_TABLES_CPP + +/* skipped duplicate #include */ + +namespace simdjson { +namespace internal { + +// structural chars here are +// they are { 0x7b } 0x7d : 0x3a [ 0x5b ] 0x5d , 0x2c (and NULL) +// we are also interested in the four whitespace characters +// space 0x20, linefeed 0x0a, horizontal tab 0x09 and carriage return 0x0d + +SIMDJSON_DLLIMPORTEXPORT const bool structural_or_whitespace_negated[256] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + +SIMDJSON_DLLIMPORTEXPORT const bool structural_or_whitespace[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +SIMDJSON_DLLIMPORTEXPORT const uint32_t digit_to_val32[886] = { + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, + 0x6, 0x7, 0x8, 0x9, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xa, + 0xb, 0xc, 0xd, 0xe, 0xf, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xa, 0xb, 0xc, 0xd, 0xe, + 0xf, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x0, 0x10, 0x20, 0x30, 0x40, 0x50, + 0x60, 0x70, 0x80, 0x90, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xa0, + 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, + 0xf0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x0, 0x100, 0x200, 0x300, 0x400, 0x500, + 0x600, 0x700, 0x800, 0x900, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xa00, + 0xb00, 0xc00, 0xd00, 0xe00, 0xf00, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00, + 0xf00, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x0, 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, + 0x6000, 0x7000, 0x8000, 0x9000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xa000, + 0xb000, 0xc000, 0xd000, 0xe000, 0xf000, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xa000, 0xb000, 0xc000, 0xd000, 0xe000, + 0xf000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_SRC_JSONCHARUTILS_TABLES_CPP +/* end file internal/jsoncharutils_tables.cpp */ +/* including internal/numberparsing_tables.cpp: #include */ +/* begin file internal/numberparsing_tables.cpp */ +#ifndef SIMDJSON_SRC_NUMBERPARSING_TABLES_CPP +#define SIMDJSON_SRC_NUMBERPARSING_TABLES_CPP + +/* skipped duplicate #include */ +/* including simdjson/internal/numberparsing_tables.h: #include */ +/* begin file simdjson/internal/numberparsing_tables.h */ +#ifndef SIMDJSON_INTERNAL_NUMBERPARSING_TABLES_H +#define SIMDJSON_INTERNAL_NUMBERPARSING_TABLES_H + +/* skipped duplicate #include "simdjson/base.h" */ + +namespace simdjson { +namespace internal { +/** + * The smallest non-zero float (binary64) is 2^-1074. + * We take as input numbers of the form w x 10^q where w < 2^64. + * We have that w * 10^-343 < 2^(64-344) 5^-343 < 2^-1076. + * However, we have that + * (2^64-1) * 10^-342 = (2^64-1) * 2^-342 * 5^-342 > 2^-1074. + * Thus it is possible for a number of the form w * 10^-342 where + * w is a 64-bit value to be a non-zero floating-point number. + ********* + * Any number of form w * 10^309 where w>= 1 is going to be + * infinite in binary64 so we never need to worry about powers + * of 5 greater than 308. + */ +constexpr int smallest_power = -342; +constexpr int largest_power = 308; + +/** + * Represents a 128-bit value. + * low: least significant 64 bits. + * high: most significant 64 bits. + */ +struct value128 { + uint64_t low; + uint64_t high; +}; + + +// Precomputed powers of ten from 10^0 to 10^22. These +// can be represented exactly using the double type. +extern SIMDJSON_DLLIMPORTEXPORT const double power_of_ten[]; + + +/** + * When mapping numbers from decimal to binary, + * we go from w * 10^q to m * 2^p but we have + * 10^q = 5^q * 2^q, so effectively + * we are trying to match + * w * 2^q * 5^q to m * 2^p. Thus the powers of two + * are not a concern since they can be represented + * exactly using the binary notation, only the powers of five + * affect the binary significand. + */ + + +// The truncated powers of five from 5^-342 all the way to 5^308 +// The mantissa is truncated to 128 bits, and +// never rounded up. Uses about 10KB. +extern SIMDJSON_DLLIMPORTEXPORT const uint64_t power_of_five_128[]; +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_NUMBERPARSING_TABLES_H +/* end file simdjson/internal/numberparsing_tables.h */ + +// Precomputed powers of ten from 10^0 to 10^22. These +// can be represented exactly using the double type. +SIMDJSON_DLLIMPORTEXPORT const double simdjson::internal::power_of_ten[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, + 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; + +/** + * When mapping numbers from decimal to binary, + * we go from w * 10^q to m * 2^p but we have + * 10^q = 5^q * 2^q, so effectively + * we are trying to match + * w * 2^q * 5^q to m * 2^p. Thus the powers of two + * are not a concern since they can be represented + * exactly using the binary notation, only the powers of five + * affect the binary significand. + */ + + +// The truncated powers of five from 5^-342 all the way to 5^308 +// The mantissa is truncated to 128 bits, and +// never rounded up. Uses about 10KB. +SIMDJSON_DLLIMPORTEXPORT const uint64_t simdjson::internal::power_of_five_128[]= { + 0xeef453d6923bd65a,0x113faa2906a13b3f, + 0x9558b4661b6565f8,0x4ac7ca59a424c507, + 0xbaaee17fa23ebf76,0x5d79bcf00d2df649, + 0xe95a99df8ace6f53,0xf4d82c2c107973dc, + 0x91d8a02bb6c10594,0x79071b9b8a4be869, + 0xb64ec836a47146f9,0x9748e2826cdee284, + 0xe3e27a444d8d98b7,0xfd1b1b2308169b25, + 0x8e6d8c6ab0787f72,0xfe30f0f5e50e20f7, + 0xb208ef855c969f4f,0xbdbd2d335e51a935, + 0xde8b2b66b3bc4723,0xad2c788035e61382, + 0x8b16fb203055ac76,0x4c3bcb5021afcc31, + 0xaddcb9e83c6b1793,0xdf4abe242a1bbf3d, + 0xd953e8624b85dd78,0xd71d6dad34a2af0d, + 0x87d4713d6f33aa6b,0x8672648c40e5ad68, + 0xa9c98d8ccb009506,0x680efdaf511f18c2, + 0xd43bf0effdc0ba48,0x212bd1b2566def2, + 0x84a57695fe98746d,0x14bb630f7604b57, + 0xa5ced43b7e3e9188,0x419ea3bd35385e2d, + 0xcf42894a5dce35ea,0x52064cac828675b9, + 0x818995ce7aa0e1b2,0x7343efebd1940993, + 0xa1ebfb4219491a1f,0x1014ebe6c5f90bf8, + 0xca66fa129f9b60a6,0xd41a26e077774ef6, + 0xfd00b897478238d0,0x8920b098955522b4, + 0x9e20735e8cb16382,0x55b46e5f5d5535b0, + 0xc5a890362fddbc62,0xeb2189f734aa831d, + 0xf712b443bbd52b7b,0xa5e9ec7501d523e4, + 0x9a6bb0aa55653b2d,0x47b233c92125366e, + 0xc1069cd4eabe89f8,0x999ec0bb696e840a, + 0xf148440a256e2c76,0xc00670ea43ca250d, + 0x96cd2a865764dbca,0x380406926a5e5728, + 0xbc807527ed3e12bc,0xc605083704f5ecf2, + 0xeba09271e88d976b,0xf7864a44c633682e, + 0x93445b8731587ea3,0x7ab3ee6afbe0211d, + 0xb8157268fdae9e4c,0x5960ea05bad82964, + 0xe61acf033d1a45df,0x6fb92487298e33bd, + 0x8fd0c16206306bab,0xa5d3b6d479f8e056, + 0xb3c4f1ba87bc8696,0x8f48a4899877186c, + 0xe0b62e2929aba83c,0x331acdabfe94de87, + 0x8c71dcd9ba0b4925,0x9ff0c08b7f1d0b14, + 0xaf8e5410288e1b6f,0x7ecf0ae5ee44dd9, + 0xdb71e91432b1a24a,0xc9e82cd9f69d6150, + 0x892731ac9faf056e,0xbe311c083a225cd2, + 0xab70fe17c79ac6ca,0x6dbd630a48aaf406, + 0xd64d3d9db981787d,0x92cbbccdad5b108, + 0x85f0468293f0eb4e,0x25bbf56008c58ea5, + 0xa76c582338ed2621,0xaf2af2b80af6f24e, + 0xd1476e2c07286faa,0x1af5af660db4aee1, + 0x82cca4db847945ca,0x50d98d9fc890ed4d, + 0xa37fce126597973c,0xe50ff107bab528a0, + 0xcc5fc196fefd7d0c,0x1e53ed49a96272c8, + 0xff77b1fcbebcdc4f,0x25e8e89c13bb0f7a, + 0x9faacf3df73609b1,0x77b191618c54e9ac, + 0xc795830d75038c1d,0xd59df5b9ef6a2417, + 0xf97ae3d0d2446f25,0x4b0573286b44ad1d, + 0x9becce62836ac577,0x4ee367f9430aec32, + 0xc2e801fb244576d5,0x229c41f793cda73f, + 0xf3a20279ed56d48a,0x6b43527578c1110f, + 0x9845418c345644d6,0x830a13896b78aaa9, + 0xbe5691ef416bd60c,0x23cc986bc656d553, + 0xedec366b11c6cb8f,0x2cbfbe86b7ec8aa8, + 0x94b3a202eb1c3f39,0x7bf7d71432f3d6a9, + 0xb9e08a83a5e34f07,0xdaf5ccd93fb0cc53, + 0xe858ad248f5c22c9,0xd1b3400f8f9cff68, + 0x91376c36d99995be,0x23100809b9c21fa1, + 0xb58547448ffffb2d,0xabd40a0c2832a78a, + 0xe2e69915b3fff9f9,0x16c90c8f323f516c, + 0x8dd01fad907ffc3b,0xae3da7d97f6792e3, + 0xb1442798f49ffb4a,0x99cd11cfdf41779c, + 0xdd95317f31c7fa1d,0x40405643d711d583, + 0x8a7d3eef7f1cfc52,0x482835ea666b2572, + 0xad1c8eab5ee43b66,0xda3243650005eecf, + 0xd863b256369d4a40,0x90bed43e40076a82, + 0x873e4f75e2224e68,0x5a7744a6e804a291, + 0xa90de3535aaae202,0x711515d0a205cb36, + 0xd3515c2831559a83,0xd5a5b44ca873e03, + 0x8412d9991ed58091,0xe858790afe9486c2, + 0xa5178fff668ae0b6,0x626e974dbe39a872, + 0xce5d73ff402d98e3,0xfb0a3d212dc8128f, + 0x80fa687f881c7f8e,0x7ce66634bc9d0b99, + 0xa139029f6a239f72,0x1c1fffc1ebc44e80, + 0xc987434744ac874e,0xa327ffb266b56220, + 0xfbe9141915d7a922,0x4bf1ff9f0062baa8, + 0x9d71ac8fada6c9b5,0x6f773fc3603db4a9, + 0xc4ce17b399107c22,0xcb550fb4384d21d3, + 0xf6019da07f549b2b,0x7e2a53a146606a48, + 0x99c102844f94e0fb,0x2eda7444cbfc426d, + 0xc0314325637a1939,0xfa911155fefb5308, + 0xf03d93eebc589f88,0x793555ab7eba27ca, + 0x96267c7535b763b5,0x4bc1558b2f3458de, + 0xbbb01b9283253ca2,0x9eb1aaedfb016f16, + 0xea9c227723ee8bcb,0x465e15a979c1cadc, + 0x92a1958a7675175f,0xbfacd89ec191ec9, + 0xb749faed14125d36,0xcef980ec671f667b, + 0xe51c79a85916f484,0x82b7e12780e7401a, + 0x8f31cc0937ae58d2,0xd1b2ecb8b0908810, + 0xb2fe3f0b8599ef07,0x861fa7e6dcb4aa15, + 0xdfbdcece67006ac9,0x67a791e093e1d49a, + 0x8bd6a141006042bd,0xe0c8bb2c5c6d24e0, + 0xaecc49914078536d,0x58fae9f773886e18, + 0xda7f5bf590966848,0xaf39a475506a899e, + 0x888f99797a5e012d,0x6d8406c952429603, + 0xaab37fd7d8f58178,0xc8e5087ba6d33b83, + 0xd5605fcdcf32e1d6,0xfb1e4a9a90880a64, + 0x855c3be0a17fcd26,0x5cf2eea09a55067f, + 0xa6b34ad8c9dfc06f,0xf42faa48c0ea481e, + 0xd0601d8efc57b08b,0xf13b94daf124da26, + 0x823c12795db6ce57,0x76c53d08d6b70858, + 0xa2cb1717b52481ed,0x54768c4b0c64ca6e, + 0xcb7ddcdda26da268,0xa9942f5dcf7dfd09, + 0xfe5d54150b090b02,0xd3f93b35435d7c4c, + 0x9efa548d26e5a6e1,0xc47bc5014a1a6daf, + 0xc6b8e9b0709f109a,0x359ab6419ca1091b, + 0xf867241c8cc6d4c0,0xc30163d203c94b62, + 0x9b407691d7fc44f8,0x79e0de63425dcf1d, + 0xc21094364dfb5636,0x985915fc12f542e4, + 0xf294b943e17a2bc4,0x3e6f5b7b17b2939d, + 0x979cf3ca6cec5b5a,0xa705992ceecf9c42, + 0xbd8430bd08277231,0x50c6ff782a838353, + 0xece53cec4a314ebd,0xa4f8bf5635246428, + 0x940f4613ae5ed136,0x871b7795e136be99, + 0xb913179899f68584,0x28e2557b59846e3f, + 0xe757dd7ec07426e5,0x331aeada2fe589cf, + 0x9096ea6f3848984f,0x3ff0d2c85def7621, + 0xb4bca50b065abe63,0xfed077a756b53a9, + 0xe1ebce4dc7f16dfb,0xd3e8495912c62894, + 0x8d3360f09cf6e4bd,0x64712dd7abbbd95c, + 0xb080392cc4349dec,0xbd8d794d96aacfb3, + 0xdca04777f541c567,0xecf0d7a0fc5583a0, + 0x89e42caaf9491b60,0xf41686c49db57244, + 0xac5d37d5b79b6239,0x311c2875c522ced5, + 0xd77485cb25823ac7,0x7d633293366b828b, + 0x86a8d39ef77164bc,0xae5dff9c02033197, + 0xa8530886b54dbdeb,0xd9f57f830283fdfc, + 0xd267caa862a12d66,0xd072df63c324fd7b, + 0x8380dea93da4bc60,0x4247cb9e59f71e6d, + 0xa46116538d0deb78,0x52d9be85f074e608, + 0xcd795be870516656,0x67902e276c921f8b, + 0x806bd9714632dff6,0xba1cd8a3db53b6, + 0xa086cfcd97bf97f3,0x80e8a40eccd228a4, + 0xc8a883c0fdaf7df0,0x6122cd128006b2cd, + 0xfad2a4b13d1b5d6c,0x796b805720085f81, + 0x9cc3a6eec6311a63,0xcbe3303674053bb0, + 0xc3f490aa77bd60fc,0xbedbfc4411068a9c, + 0xf4f1b4d515acb93b,0xee92fb5515482d44, + 0x991711052d8bf3c5,0x751bdd152d4d1c4a, + 0xbf5cd54678eef0b6,0xd262d45a78a0635d, + 0xef340a98172aace4,0x86fb897116c87c34, + 0x9580869f0e7aac0e,0xd45d35e6ae3d4da0, + 0xbae0a846d2195712,0x8974836059cca109, + 0xe998d258869facd7,0x2bd1a438703fc94b, + 0x91ff83775423cc06,0x7b6306a34627ddcf, + 0xb67f6455292cbf08,0x1a3bc84c17b1d542, + 0xe41f3d6a7377eeca,0x20caba5f1d9e4a93, + 0x8e938662882af53e,0x547eb47b7282ee9c, + 0xb23867fb2a35b28d,0xe99e619a4f23aa43, + 0xdec681f9f4c31f31,0x6405fa00e2ec94d4, + 0x8b3c113c38f9f37e,0xde83bc408dd3dd04, + 0xae0b158b4738705e,0x9624ab50b148d445, + 0xd98ddaee19068c76,0x3badd624dd9b0957, + 0x87f8a8d4cfa417c9,0xe54ca5d70a80e5d6, + 0xa9f6d30a038d1dbc,0x5e9fcf4ccd211f4c, + 0xd47487cc8470652b,0x7647c3200069671f, + 0x84c8d4dfd2c63f3b,0x29ecd9f40041e073, + 0xa5fb0a17c777cf09,0xf468107100525890, + 0xcf79cc9db955c2cc,0x7182148d4066eeb4, + 0x81ac1fe293d599bf,0xc6f14cd848405530, + 0xa21727db38cb002f,0xb8ada00e5a506a7c, + 0xca9cf1d206fdc03b,0xa6d90811f0e4851c, + 0xfd442e4688bd304a,0x908f4a166d1da663, + 0x9e4a9cec15763e2e,0x9a598e4e043287fe, + 0xc5dd44271ad3cdba,0x40eff1e1853f29fd, + 0xf7549530e188c128,0xd12bee59e68ef47c, + 0x9a94dd3e8cf578b9,0x82bb74f8301958ce, + 0xc13a148e3032d6e7,0xe36a52363c1faf01, + 0xf18899b1bc3f8ca1,0xdc44e6c3cb279ac1, + 0x96f5600f15a7b7e5,0x29ab103a5ef8c0b9, + 0xbcb2b812db11a5de,0x7415d448f6b6f0e7, + 0xebdf661791d60f56,0x111b495b3464ad21, + 0x936b9fcebb25c995,0xcab10dd900beec34, + 0xb84687c269ef3bfb,0x3d5d514f40eea742, + 0xe65829b3046b0afa,0xcb4a5a3112a5112, + 0x8ff71a0fe2c2e6dc,0x47f0e785eaba72ab, + 0xb3f4e093db73a093,0x59ed216765690f56, + 0xe0f218b8d25088b8,0x306869c13ec3532c, + 0x8c974f7383725573,0x1e414218c73a13fb, + 0xafbd2350644eeacf,0xe5d1929ef90898fa, + 0xdbac6c247d62a583,0xdf45f746b74abf39, + 0x894bc396ce5da772,0x6b8bba8c328eb783, + 0xab9eb47c81f5114f,0x66ea92f3f326564, + 0xd686619ba27255a2,0xc80a537b0efefebd, + 0x8613fd0145877585,0xbd06742ce95f5f36, + 0xa798fc4196e952e7,0x2c48113823b73704, + 0xd17f3b51fca3a7a0,0xf75a15862ca504c5, + 0x82ef85133de648c4,0x9a984d73dbe722fb, + 0xa3ab66580d5fdaf5,0xc13e60d0d2e0ebba, + 0xcc963fee10b7d1b3,0x318df905079926a8, + 0xffbbcfe994e5c61f,0xfdf17746497f7052, + 0x9fd561f1fd0f9bd3,0xfeb6ea8bedefa633, + 0xc7caba6e7c5382c8,0xfe64a52ee96b8fc0, + 0xf9bd690a1b68637b,0x3dfdce7aa3c673b0, + 0x9c1661a651213e2d,0x6bea10ca65c084e, + 0xc31bfa0fe5698db8,0x486e494fcff30a62, + 0xf3e2f893dec3f126,0x5a89dba3c3efccfa, + 0x986ddb5c6b3a76b7,0xf89629465a75e01c, + 0xbe89523386091465,0xf6bbb397f1135823, + 0xee2ba6c0678b597f,0x746aa07ded582e2c, + 0x94db483840b717ef,0xa8c2a44eb4571cdc, + 0xba121a4650e4ddeb,0x92f34d62616ce413, + 0xe896a0d7e51e1566,0x77b020baf9c81d17, + 0x915e2486ef32cd60,0xace1474dc1d122e, + 0xb5b5ada8aaff80b8,0xd819992132456ba, + 0xe3231912d5bf60e6,0x10e1fff697ed6c69, + 0x8df5efabc5979c8f,0xca8d3ffa1ef463c1, + 0xb1736b96b6fd83b3,0xbd308ff8a6b17cb2, + 0xddd0467c64bce4a0,0xac7cb3f6d05ddbde, + 0x8aa22c0dbef60ee4,0x6bcdf07a423aa96b, + 0xad4ab7112eb3929d,0x86c16c98d2c953c6, + 0xd89d64d57a607744,0xe871c7bf077ba8b7, + 0x87625f056c7c4a8b,0x11471cd764ad4972, + 0xa93af6c6c79b5d2d,0xd598e40d3dd89bcf, + 0xd389b47879823479,0x4aff1d108d4ec2c3, + 0x843610cb4bf160cb,0xcedf722a585139ba, + 0xa54394fe1eedb8fe,0xc2974eb4ee658828, + 0xce947a3da6a9273e,0x733d226229feea32, + 0x811ccc668829b887,0x806357d5a3f525f, + 0xa163ff802a3426a8,0xca07c2dcb0cf26f7, + 0xc9bcff6034c13052,0xfc89b393dd02f0b5, + 0xfc2c3f3841f17c67,0xbbac2078d443ace2, + 0x9d9ba7832936edc0,0xd54b944b84aa4c0d, + 0xc5029163f384a931,0xa9e795e65d4df11, + 0xf64335bcf065d37d,0x4d4617b5ff4a16d5, + 0x99ea0196163fa42e,0x504bced1bf8e4e45, + 0xc06481fb9bcf8d39,0xe45ec2862f71e1d6, + 0xf07da27a82c37088,0x5d767327bb4e5a4c, + 0x964e858c91ba2655,0x3a6a07f8d510f86f, + 0xbbe226efb628afea,0x890489f70a55368b, + 0xeadab0aba3b2dbe5,0x2b45ac74ccea842e, + 0x92c8ae6b464fc96f,0x3b0b8bc90012929d, + 0xb77ada0617e3bbcb,0x9ce6ebb40173744, + 0xe55990879ddcaabd,0xcc420a6a101d0515, + 0x8f57fa54c2a9eab6,0x9fa946824a12232d, + 0xb32df8e9f3546564,0x47939822dc96abf9, + 0xdff9772470297ebd,0x59787e2b93bc56f7, + 0x8bfbea76c619ef36,0x57eb4edb3c55b65a, + 0xaefae51477a06b03,0xede622920b6b23f1, + 0xdab99e59958885c4,0xe95fab368e45eced, + 0x88b402f7fd75539b,0x11dbcb0218ebb414, + 0xaae103b5fcd2a881,0xd652bdc29f26a119, + 0xd59944a37c0752a2,0x4be76d3346f0495f, + 0x857fcae62d8493a5,0x6f70a4400c562ddb, + 0xa6dfbd9fb8e5b88e,0xcb4ccd500f6bb952, + 0xd097ad07a71f26b2,0x7e2000a41346a7a7, + 0x825ecc24c873782f,0x8ed400668c0c28c8, + 0xa2f67f2dfa90563b,0x728900802f0f32fa, + 0xcbb41ef979346bca,0x4f2b40a03ad2ffb9, + 0xfea126b7d78186bc,0xe2f610c84987bfa8, + 0x9f24b832e6b0f436,0xdd9ca7d2df4d7c9, + 0xc6ede63fa05d3143,0x91503d1c79720dbb, + 0xf8a95fcf88747d94,0x75a44c6397ce912a, + 0x9b69dbe1b548ce7c,0xc986afbe3ee11aba, + 0xc24452da229b021b,0xfbe85badce996168, + 0xf2d56790ab41c2a2,0xfae27299423fb9c3, + 0x97c560ba6b0919a5,0xdccd879fc967d41a, + 0xbdb6b8e905cb600f,0x5400e987bbc1c920, + 0xed246723473e3813,0x290123e9aab23b68, + 0x9436c0760c86e30b,0xf9a0b6720aaf6521, + 0xb94470938fa89bce,0xf808e40e8d5b3e69, + 0xe7958cb87392c2c2,0xb60b1d1230b20e04, + 0x90bd77f3483bb9b9,0xb1c6f22b5e6f48c2, + 0xb4ecd5f01a4aa828,0x1e38aeb6360b1af3, + 0xe2280b6c20dd5232,0x25c6da63c38de1b0, + 0x8d590723948a535f,0x579c487e5a38ad0e, + 0xb0af48ec79ace837,0x2d835a9df0c6d851, + 0xdcdb1b2798182244,0xf8e431456cf88e65, + 0x8a08f0f8bf0f156b,0x1b8e9ecb641b58ff, + 0xac8b2d36eed2dac5,0xe272467e3d222f3f, + 0xd7adf884aa879177,0x5b0ed81dcc6abb0f, + 0x86ccbb52ea94baea,0x98e947129fc2b4e9, + 0xa87fea27a539e9a5,0x3f2398d747b36224, + 0xd29fe4b18e88640e,0x8eec7f0d19a03aad, + 0x83a3eeeef9153e89,0x1953cf68300424ac, + 0xa48ceaaab75a8e2b,0x5fa8c3423c052dd7, + 0xcdb02555653131b6,0x3792f412cb06794d, + 0x808e17555f3ebf11,0xe2bbd88bbee40bd0, + 0xa0b19d2ab70e6ed6,0x5b6aceaeae9d0ec4, + 0xc8de047564d20a8b,0xf245825a5a445275, + 0xfb158592be068d2e,0xeed6e2f0f0d56712, + 0x9ced737bb6c4183d,0x55464dd69685606b, + 0xc428d05aa4751e4c,0xaa97e14c3c26b886, + 0xf53304714d9265df,0xd53dd99f4b3066a8, + 0x993fe2c6d07b7fab,0xe546a8038efe4029, + 0xbf8fdb78849a5f96,0xde98520472bdd033, + 0xef73d256a5c0f77c,0x963e66858f6d4440, + 0x95a8637627989aad,0xdde7001379a44aa8, + 0xbb127c53b17ec159,0x5560c018580d5d52, + 0xe9d71b689dde71af,0xaab8f01e6e10b4a6, + 0x9226712162ab070d,0xcab3961304ca70e8, + 0xb6b00d69bb55c8d1,0x3d607b97c5fd0d22, + 0xe45c10c42a2b3b05,0x8cb89a7db77c506a, + 0x8eb98a7a9a5b04e3,0x77f3608e92adb242, + 0xb267ed1940f1c61c,0x55f038b237591ed3, + 0xdf01e85f912e37a3,0x6b6c46dec52f6688, + 0x8b61313bbabce2c6,0x2323ac4b3b3da015, + 0xae397d8aa96c1b77,0xabec975e0a0d081a, + 0xd9c7dced53c72255,0x96e7bd358c904a21, + 0x881cea14545c7575,0x7e50d64177da2e54, + 0xaa242499697392d2,0xdde50bd1d5d0b9e9, + 0xd4ad2dbfc3d07787,0x955e4ec64b44e864, + 0x84ec3c97da624ab4,0xbd5af13bef0b113e, + 0xa6274bbdd0fadd61,0xecb1ad8aeacdd58e, + 0xcfb11ead453994ba,0x67de18eda5814af2, + 0x81ceb32c4b43fcf4,0x80eacf948770ced7, + 0xa2425ff75e14fc31,0xa1258379a94d028d, + 0xcad2f7f5359a3b3e,0x96ee45813a04330, + 0xfd87b5f28300ca0d,0x8bca9d6e188853fc, + 0x9e74d1b791e07e48,0x775ea264cf55347e, + 0xc612062576589dda,0x95364afe032a81a0, + 0xf79687aed3eec551,0x3a83ddbd83f52210, + 0x9abe14cd44753b52,0xc4926a9672793580, + 0xc16d9a0095928a27,0x75b7053c0f178400, + 0xf1c90080baf72cb1,0x5324c68b12dd6800, + 0x971da05074da7bee,0xd3f6fc16ebca8000, + 0xbce5086492111aea,0x88f4bb1ca6bd0000, + 0xec1e4a7db69561a5,0x2b31e9e3d0700000, + 0x9392ee8e921d5d07,0x3aff322e62600000, + 0xb877aa3236a4b449,0x9befeb9fad487c3, + 0xe69594bec44de15b,0x4c2ebe687989a9b4, + 0x901d7cf73ab0acd9,0xf9d37014bf60a11, + 0xb424dc35095cd80f,0x538484c19ef38c95, + 0xe12e13424bb40e13,0x2865a5f206b06fba, + 0x8cbccc096f5088cb,0xf93f87b7442e45d4, + 0xafebff0bcb24aafe,0xf78f69a51539d749, + 0xdbe6fecebdedd5be,0xb573440e5a884d1c, + 0x89705f4136b4a597,0x31680a88f8953031, + 0xabcc77118461cefc,0xfdc20d2b36ba7c3e, + 0xd6bf94d5e57a42bc,0x3d32907604691b4d, + 0x8637bd05af6c69b5,0xa63f9a49c2c1b110, + 0xa7c5ac471b478423,0xfcf80dc33721d54, + 0xd1b71758e219652b,0xd3c36113404ea4a9, + 0x83126e978d4fdf3b,0x645a1cac083126ea, + 0xa3d70a3d70a3d70a,0x3d70a3d70a3d70a4, + 0xcccccccccccccccc,0xcccccccccccccccd, + 0x8000000000000000,0x0, + 0xa000000000000000,0x0, + 0xc800000000000000,0x0, + 0xfa00000000000000,0x0, + 0x9c40000000000000,0x0, + 0xc350000000000000,0x0, + 0xf424000000000000,0x0, + 0x9896800000000000,0x0, + 0xbebc200000000000,0x0, + 0xee6b280000000000,0x0, + 0x9502f90000000000,0x0, + 0xba43b74000000000,0x0, + 0xe8d4a51000000000,0x0, + 0x9184e72a00000000,0x0, + 0xb5e620f480000000,0x0, + 0xe35fa931a0000000,0x0, + 0x8e1bc9bf04000000,0x0, + 0xb1a2bc2ec5000000,0x0, + 0xde0b6b3a76400000,0x0, + 0x8ac7230489e80000,0x0, + 0xad78ebc5ac620000,0x0, + 0xd8d726b7177a8000,0x0, + 0x878678326eac9000,0x0, + 0xa968163f0a57b400,0x0, + 0xd3c21bcecceda100,0x0, + 0x84595161401484a0,0x0, + 0xa56fa5b99019a5c8,0x0, + 0xcecb8f27f4200f3a,0x0, + 0x813f3978f8940984,0x4000000000000000, + 0xa18f07d736b90be5,0x5000000000000000, + 0xc9f2c9cd04674ede,0xa400000000000000, + 0xfc6f7c4045812296,0x4d00000000000000, + 0x9dc5ada82b70b59d,0xf020000000000000, + 0xc5371912364ce305,0x6c28000000000000, + 0xf684df56c3e01bc6,0xc732000000000000, + 0x9a130b963a6c115c,0x3c7f400000000000, + 0xc097ce7bc90715b3,0x4b9f100000000000, + 0xf0bdc21abb48db20,0x1e86d40000000000, + 0x96769950b50d88f4,0x1314448000000000, + 0xbc143fa4e250eb31,0x17d955a000000000, + 0xeb194f8e1ae525fd,0x5dcfab0800000000, + 0x92efd1b8d0cf37be,0x5aa1cae500000000, + 0xb7abc627050305ad,0xf14a3d9e40000000, + 0xe596b7b0c643c719,0x6d9ccd05d0000000, + 0x8f7e32ce7bea5c6f,0xe4820023a2000000, + 0xb35dbf821ae4f38b,0xdda2802c8a800000, + 0xe0352f62a19e306e,0xd50b2037ad200000, + 0x8c213d9da502de45,0x4526f422cc340000, + 0xaf298d050e4395d6,0x9670b12b7f410000, + 0xdaf3f04651d47b4c,0x3c0cdd765f114000, + 0x88d8762bf324cd0f,0xa5880a69fb6ac800, + 0xab0e93b6efee0053,0x8eea0d047a457a00, + 0xd5d238a4abe98068,0x72a4904598d6d880, + 0x85a36366eb71f041,0x47a6da2b7f864750, + 0xa70c3c40a64e6c51,0x999090b65f67d924, + 0xd0cf4b50cfe20765,0xfff4b4e3f741cf6d, + 0x82818f1281ed449f,0xbff8f10e7a8921a4, + 0xa321f2d7226895c7,0xaff72d52192b6a0d, + 0xcbea6f8ceb02bb39,0x9bf4f8a69f764490, + 0xfee50b7025c36a08,0x2f236d04753d5b4, + 0x9f4f2726179a2245,0x1d762422c946590, + 0xc722f0ef9d80aad6,0x424d3ad2b7b97ef5, + 0xf8ebad2b84e0d58b,0xd2e0898765a7deb2, + 0x9b934c3b330c8577,0x63cc55f49f88eb2f, + 0xc2781f49ffcfa6d5,0x3cbf6b71c76b25fb, + 0xf316271c7fc3908a,0x8bef464e3945ef7a, + 0x97edd871cfda3a56,0x97758bf0e3cbb5ac, + 0xbde94e8e43d0c8ec,0x3d52eeed1cbea317, + 0xed63a231d4c4fb27,0x4ca7aaa863ee4bdd, + 0x945e455f24fb1cf8,0x8fe8caa93e74ef6a, + 0xb975d6b6ee39e436,0xb3e2fd538e122b44, + 0xe7d34c64a9c85d44,0x60dbbca87196b616, + 0x90e40fbeea1d3a4a,0xbc8955e946fe31cd, + 0xb51d13aea4a488dd,0x6babab6398bdbe41, + 0xe264589a4dcdab14,0xc696963c7eed2dd1, + 0x8d7eb76070a08aec,0xfc1e1de5cf543ca2, + 0xb0de65388cc8ada8,0x3b25a55f43294bcb, + 0xdd15fe86affad912,0x49ef0eb713f39ebe, + 0x8a2dbf142dfcc7ab,0x6e3569326c784337, + 0xacb92ed9397bf996,0x49c2c37f07965404, + 0xd7e77a8f87daf7fb,0xdc33745ec97be906, + 0x86f0ac99b4e8dafd,0x69a028bb3ded71a3, + 0xa8acd7c0222311bc,0xc40832ea0d68ce0c, + 0xd2d80db02aabd62b,0xf50a3fa490c30190, + 0x83c7088e1aab65db,0x792667c6da79e0fa, + 0xa4b8cab1a1563f52,0x577001b891185938, + 0xcde6fd5e09abcf26,0xed4c0226b55e6f86, + 0x80b05e5ac60b6178,0x544f8158315b05b4, + 0xa0dc75f1778e39d6,0x696361ae3db1c721, + 0xc913936dd571c84c,0x3bc3a19cd1e38e9, + 0xfb5878494ace3a5f,0x4ab48a04065c723, + 0x9d174b2dcec0e47b,0x62eb0d64283f9c76, + 0xc45d1df942711d9a,0x3ba5d0bd324f8394, + 0xf5746577930d6500,0xca8f44ec7ee36479, + 0x9968bf6abbe85f20,0x7e998b13cf4e1ecb, + 0xbfc2ef456ae276e8,0x9e3fedd8c321a67e, + 0xefb3ab16c59b14a2,0xc5cfe94ef3ea101e, + 0x95d04aee3b80ece5,0xbba1f1d158724a12, + 0xbb445da9ca61281f,0x2a8a6e45ae8edc97, + 0xea1575143cf97226,0xf52d09d71a3293bd, + 0x924d692ca61be758,0x593c2626705f9c56, + 0xb6e0c377cfa2e12e,0x6f8b2fb00c77836c, + 0xe498f455c38b997a,0xb6dfb9c0f956447, + 0x8edf98b59a373fec,0x4724bd4189bd5eac, + 0xb2977ee300c50fe7,0x58edec91ec2cb657, + 0xdf3d5e9bc0f653e1,0x2f2967b66737e3ed, + 0x8b865b215899f46c,0xbd79e0d20082ee74, + 0xae67f1e9aec07187,0xecd8590680a3aa11, + 0xda01ee641a708de9,0xe80e6f4820cc9495, + 0x884134fe908658b2,0x3109058d147fdcdd, + 0xaa51823e34a7eede,0xbd4b46f0599fd415, + 0xd4e5e2cdc1d1ea96,0x6c9e18ac7007c91a, + 0x850fadc09923329e,0x3e2cf6bc604ddb0, + 0xa6539930bf6bff45,0x84db8346b786151c, + 0xcfe87f7cef46ff16,0xe612641865679a63, + 0x81f14fae158c5f6e,0x4fcb7e8f3f60c07e, + 0xa26da3999aef7749,0xe3be5e330f38f09d, + 0xcb090c8001ab551c,0x5cadf5bfd3072cc5, + 0xfdcb4fa002162a63,0x73d9732fc7c8f7f6, + 0x9e9f11c4014dda7e,0x2867e7fddcdd9afa, + 0xc646d63501a1511d,0xb281e1fd541501b8, + 0xf7d88bc24209a565,0x1f225a7ca91a4226, + 0x9ae757596946075f,0x3375788de9b06958, + 0xc1a12d2fc3978937,0x52d6b1641c83ae, + 0xf209787bb47d6b84,0xc0678c5dbd23a49a, + 0x9745eb4d50ce6332,0xf840b7ba963646e0, + 0xbd176620a501fbff,0xb650e5a93bc3d898, + 0xec5d3fa8ce427aff,0xa3e51f138ab4cebe, + 0x93ba47c980e98cdf,0xc66f336c36b10137, + 0xb8a8d9bbe123f017,0xb80b0047445d4184, + 0xe6d3102ad96cec1d,0xa60dc059157491e5, + 0x9043ea1ac7e41392,0x87c89837ad68db2f, + 0xb454e4a179dd1877,0x29babe4598c311fb, + 0xe16a1dc9d8545e94,0xf4296dd6fef3d67a, + 0x8ce2529e2734bb1d,0x1899e4a65f58660c, + 0xb01ae745b101e9e4,0x5ec05dcff72e7f8f, + 0xdc21a1171d42645d,0x76707543f4fa1f73, + 0x899504ae72497eba,0x6a06494a791c53a8, + 0xabfa45da0edbde69,0x487db9d17636892, + 0xd6f8d7509292d603,0x45a9d2845d3c42b6, + 0x865b86925b9bc5c2,0xb8a2392ba45a9b2, + 0xa7f26836f282b732,0x8e6cac7768d7141e, + 0xd1ef0244af2364ff,0x3207d795430cd926, + 0x8335616aed761f1f,0x7f44e6bd49e807b8, + 0xa402b9c5a8d3a6e7,0x5f16206c9c6209a6, + 0xcd036837130890a1,0x36dba887c37a8c0f, + 0x802221226be55a64,0xc2494954da2c9789, + 0xa02aa96b06deb0fd,0xf2db9baa10b7bd6c, + 0xc83553c5c8965d3d,0x6f92829494e5acc7, + 0xfa42a8b73abbf48c,0xcb772339ba1f17f9, + 0x9c69a97284b578d7,0xff2a760414536efb, + 0xc38413cf25e2d70d,0xfef5138519684aba, + 0xf46518c2ef5b8cd1,0x7eb258665fc25d69, + 0x98bf2f79d5993802,0xef2f773ffbd97a61, + 0xbeeefb584aff8603,0xaafb550ffacfd8fa, + 0xeeaaba2e5dbf6784,0x95ba2a53f983cf38, + 0x952ab45cfa97a0b2,0xdd945a747bf26183, + 0xba756174393d88df,0x94f971119aeef9e4, + 0xe912b9d1478ceb17,0x7a37cd5601aab85d, + 0x91abb422ccb812ee,0xac62e055c10ab33a, + 0xb616a12b7fe617aa,0x577b986b314d6009, + 0xe39c49765fdf9d94,0xed5a7e85fda0b80b, + 0x8e41ade9fbebc27d,0x14588f13be847307, + 0xb1d219647ae6b31c,0x596eb2d8ae258fc8, + 0xde469fbd99a05fe3,0x6fca5f8ed9aef3bb, + 0x8aec23d680043bee,0x25de7bb9480d5854, + 0xada72ccc20054ae9,0xaf561aa79a10ae6a, + 0xd910f7ff28069da4,0x1b2ba1518094da04, + 0x87aa9aff79042286,0x90fb44d2f05d0842, + 0xa99541bf57452b28,0x353a1607ac744a53, + 0xd3fa922f2d1675f2,0x42889b8997915ce8, + 0x847c9b5d7c2e09b7,0x69956135febada11, + 0xa59bc234db398c25,0x43fab9837e699095, + 0xcf02b2c21207ef2e,0x94f967e45e03f4bb, + 0x8161afb94b44f57d,0x1d1be0eebac278f5, + 0xa1ba1ba79e1632dc,0x6462d92a69731732, + 0xca28a291859bbf93,0x7d7b8f7503cfdcfe, + 0xfcb2cb35e702af78,0x5cda735244c3d43e, + 0x9defbf01b061adab,0x3a0888136afa64a7, + 0xc56baec21c7a1916,0x88aaa1845b8fdd0, + 0xf6c69a72a3989f5b,0x8aad549e57273d45, + 0x9a3c2087a63f6399,0x36ac54e2f678864b, + 0xc0cb28a98fcf3c7f,0x84576a1bb416a7dd, + 0xf0fdf2d3f3c30b9f,0x656d44a2a11c51d5, + 0x969eb7c47859e743,0x9f644ae5a4b1b325, + 0xbc4665b596706114,0x873d5d9f0dde1fee, + 0xeb57ff22fc0c7959,0xa90cb506d155a7ea, + 0x9316ff75dd87cbd8,0x9a7f12442d588f2, + 0xb7dcbf5354e9bece,0xc11ed6d538aeb2f, + 0xe5d3ef282a242e81,0x8f1668c8a86da5fa, + 0x8fa475791a569d10,0xf96e017d694487bc, + 0xb38d92d760ec4455,0x37c981dcc395a9ac, + 0xe070f78d3927556a,0x85bbe253f47b1417, + 0x8c469ab843b89562,0x93956d7478ccec8e, + 0xaf58416654a6babb,0x387ac8d1970027b2, + 0xdb2e51bfe9d0696a,0x6997b05fcc0319e, + 0x88fcf317f22241e2,0x441fece3bdf81f03, + 0xab3c2fddeeaad25a,0xd527e81cad7626c3, + 0xd60b3bd56a5586f1,0x8a71e223d8d3b074, + 0x85c7056562757456,0xf6872d5667844e49, + 0xa738c6bebb12d16c,0xb428f8ac016561db, + 0xd106f86e69d785c7,0xe13336d701beba52, + 0x82a45b450226b39c,0xecc0024661173473, + 0xa34d721642b06084,0x27f002d7f95d0190, + 0xcc20ce9bd35c78a5,0x31ec038df7b441f4, + 0xff290242c83396ce,0x7e67047175a15271, + 0x9f79a169bd203e41,0xf0062c6e984d386, + 0xc75809c42c684dd1,0x52c07b78a3e60868, + 0xf92e0c3537826145,0xa7709a56ccdf8a82, + 0x9bbcc7a142b17ccb,0x88a66076400bb691, + 0xc2abf989935ddbfe,0x6acff893d00ea435, + 0xf356f7ebf83552fe,0x583f6b8c4124d43, + 0x98165af37b2153de,0xc3727a337a8b704a, + 0xbe1bf1b059e9a8d6,0x744f18c0592e4c5c, + 0xeda2ee1c7064130c,0x1162def06f79df73, + 0x9485d4d1c63e8be7,0x8addcb5645ac2ba8, + 0xb9a74a0637ce2ee1,0x6d953e2bd7173692, + 0xe8111c87c5c1ba99,0xc8fa8db6ccdd0437, + 0x910ab1d4db9914a0,0x1d9c9892400a22a2, + 0xb54d5e4a127f59c8,0x2503beb6d00cab4b, + 0xe2a0b5dc971f303a,0x2e44ae64840fd61d, + 0x8da471a9de737e24,0x5ceaecfed289e5d2, + 0xb10d8e1456105dad,0x7425a83e872c5f47, + 0xdd50f1996b947518,0xd12f124e28f77719, + 0x8a5296ffe33cc92f,0x82bd6b70d99aaa6f, + 0xace73cbfdc0bfb7b,0x636cc64d1001550b, + 0xd8210befd30efa5a,0x3c47f7e05401aa4e, + 0x8714a775e3e95c78,0x65acfaec34810a71, + 0xa8d9d1535ce3b396,0x7f1839a741a14d0d, + 0xd31045a8341ca07c,0x1ede48111209a050, + 0x83ea2b892091e44d,0x934aed0aab460432, + 0xa4e4b66b68b65d60,0xf81da84d5617853f, + 0xce1de40642e3f4b9,0x36251260ab9d668e, + 0x80d2ae83e9ce78f3,0xc1d72b7c6b426019, + 0xa1075a24e4421730,0xb24cf65b8612f81f, + 0xc94930ae1d529cfc,0xdee033f26797b627, + 0xfb9b7cd9a4a7443c,0x169840ef017da3b1, + 0x9d412e0806e88aa5,0x8e1f289560ee864e, + 0xc491798a08a2ad4e,0xf1a6f2bab92a27e2, + 0xf5b5d7ec8acb58a2,0xae10af696774b1db, + 0x9991a6f3d6bf1765,0xacca6da1e0a8ef29, + 0xbff610b0cc6edd3f,0x17fd090a58d32af3, + 0xeff394dcff8a948e,0xddfc4b4cef07f5b0, + 0x95f83d0a1fb69cd9,0x4abdaf101564f98e, + 0xbb764c4ca7a4440f,0x9d6d1ad41abe37f1, + 0xea53df5fd18d5513,0x84c86189216dc5ed, + 0x92746b9be2f8552c,0x32fd3cf5b4e49bb4, + 0xb7118682dbb66a77,0x3fbc8c33221dc2a1, + 0xe4d5e82392a40515,0xfabaf3feaa5334a, + 0x8f05b1163ba6832d,0x29cb4d87f2a7400e, + 0xb2c71d5bca9023f8,0x743e20e9ef511012, + 0xdf78e4b2bd342cf6,0x914da9246b255416, + 0x8bab8eefb6409c1a,0x1ad089b6c2f7548e, + 0xae9672aba3d0c320,0xa184ac2473b529b1, + 0xda3c0f568cc4f3e8,0xc9e5d72d90a2741e, + 0x8865899617fb1871,0x7e2fa67c7a658892, + 0xaa7eebfb9df9de8d,0xddbb901b98feeab7, + 0xd51ea6fa85785631,0x552a74227f3ea565, + 0x8533285c936b35de,0xd53a88958f87275f, + 0xa67ff273b8460356,0x8a892abaf368f137, + 0xd01fef10a657842c,0x2d2b7569b0432d85, + 0x8213f56a67f6b29b,0x9c3b29620e29fc73, + 0xa298f2c501f45f42,0x8349f3ba91b47b8f, + 0xcb3f2f7642717713,0x241c70a936219a73, + 0xfe0efb53d30dd4d7,0xed238cd383aa0110, + 0x9ec95d1463e8a506,0xf4363804324a40aa, + 0xc67bb4597ce2ce48,0xb143c6053edcd0d5, + 0xf81aa16fdc1b81da,0xdd94b7868e94050a, + 0x9b10a4e5e9913128,0xca7cf2b4191c8326, + 0xc1d4ce1f63f57d72,0xfd1c2f611f63a3f0, + 0xf24a01a73cf2dccf,0xbc633b39673c8cec, + 0x976e41088617ca01,0xd5be0503e085d813, + 0xbd49d14aa79dbc82,0x4b2d8644d8a74e18, + 0xec9c459d51852ba2,0xddf8e7d60ed1219e, + 0x93e1ab8252f33b45,0xcabb90e5c942b503, + 0xb8da1662e7b00a17,0x3d6a751f3b936243, + 0xe7109bfba19c0c9d,0xcc512670a783ad4, + 0x906a617d450187e2,0x27fb2b80668b24c5, + 0xb484f9dc9641e9da,0xb1f9f660802dedf6, + 0xe1a63853bbd26451,0x5e7873f8a0396973, + 0x8d07e33455637eb2,0xdb0b487b6423e1e8, + 0xb049dc016abc5e5f,0x91ce1a9a3d2cda62, + 0xdc5c5301c56b75f7,0x7641a140cc7810fb, + 0x89b9b3e11b6329ba,0xa9e904c87fcb0a9d, + 0xac2820d9623bf429,0x546345fa9fbdcd44, + 0xd732290fbacaf133,0xa97c177947ad4095, + 0x867f59a9d4bed6c0,0x49ed8eabcccc485d, + 0xa81f301449ee8c70,0x5c68f256bfff5a74, + 0xd226fc195c6a2f8c,0x73832eec6fff3111, + 0x83585d8fd9c25db7,0xc831fd53c5ff7eab, + 0xa42e74f3d032f525,0xba3e7ca8b77f5e55, + 0xcd3a1230c43fb26f,0x28ce1bd2e55f35eb, + 0x80444b5e7aa7cf85,0x7980d163cf5b81b3, + 0xa0555e361951c366,0xd7e105bcc332621f, + 0xc86ab5c39fa63440,0x8dd9472bf3fefaa7, + 0xfa856334878fc150,0xb14f98f6f0feb951, + 0x9c935e00d4b9d8d2,0x6ed1bf9a569f33d3, + 0xc3b8358109e84f07,0xa862f80ec4700c8, + 0xf4a642e14c6262c8,0xcd27bb612758c0fa, + 0x98e7e9cccfbd7dbd,0x8038d51cb897789c, + 0xbf21e44003acdd2c,0xe0470a63e6bd56c3, + 0xeeea5d5004981478,0x1858ccfce06cac74, + 0x95527a5202df0ccb,0xf37801e0c43ebc8, + 0xbaa718e68396cffd,0xd30560258f54e6ba, + 0xe950df20247c83fd,0x47c6b82ef32a2069, + 0x91d28b7416cdd27e,0x4cdc331d57fa5441, + 0xb6472e511c81471d,0xe0133fe4adf8e952, + 0xe3d8f9e563a198e5,0x58180fddd97723a6, + 0x8e679c2f5e44ff8f,0x570f09eaa7ea7648,}; + +#endif // SIMDJSON_SRC_NUMBERPARSING_TABLES_CPP +/* end file internal/numberparsing_tables.cpp */ +/* including internal/simdprune_tables.cpp: #include */ +/* begin file internal/simdprune_tables.cpp */ +#ifndef SIMDJSON_SRC_SIMDPRUNE_TABLES_CPP +#define SIMDJSON_SRC_SIMDPRUNE_TABLES_CPP + +/* including simdjson/implementation_detection.h: #include */ +/* begin file simdjson/implementation_detection.h */ +#ifndef SIMDJSON_IMPLEMENTATION_DETECTION_H +#define SIMDJSON_IMPLEMENTATION_DETECTION_H + +/* skipped duplicate #include "simdjson/base.h" */ + +// 0 is reserved, because undefined SIMDJSON_IMPLEMENTATION equals 0 in preprocessor macros. +#define SIMDJSON_IMPLEMENTATION_ID_arm64 1 +#define SIMDJSON_IMPLEMENTATION_ID_fallback 2 +#define SIMDJSON_IMPLEMENTATION_ID_haswell 3 +#define SIMDJSON_IMPLEMENTATION_ID_icelake 4 +#define SIMDJSON_IMPLEMENTATION_ID_ppc64 5 +#define SIMDJSON_IMPLEMENTATION_ID_westmere 6 + +#define SIMDJSON_IMPLEMENTATION_ID_FOR(IMPL) SIMDJSON_CAT(SIMDJSON_IMPLEMENTATION_ID_, IMPL) +#define SIMDJSON_IMPLEMENTATION_ID SIMDJSON_IMPLEMENTATION_ID_FOR(SIMDJSON_IMPLEMENTATION) + +#define SIMDJSON_IMPLEMENTATION_IS(IMPL) SIMDJSON_IMPLEMENTATION_ID == SIMDJSON_IMPLEMENTATION_ID_FOR(IMPL) + +// +// First, figure out which implementations can be run. Doing it here makes it so we don't have to worry about the order +// in which we include them. +// + +#ifndef SIMDJSON_IMPLEMENTATION_ARM64 +#define SIMDJSON_IMPLEMENTATION_ARM64 (SIMDJSON_IS_ARM64) +#endif +#define SIMDJSON_CAN_ALWAYS_RUN_ARM64 SIMDJSON_IMPLEMENTATION_ARM64 && SIMDJSON_IS_ARM64 + +// Default Icelake to on if this is x86-64. Even if we're not compiled for it, it could be selected +// at runtime. +#ifndef SIMDJSON_IMPLEMENTATION_ICELAKE +#define SIMDJSON_IMPLEMENTATION_ICELAKE ((SIMDJSON_IS_X86_64) && (SIMDJSON_AVX512_ALLOWED) && (SIMDJSON_COMPILER_SUPPORTS_VBMI2)) +#endif + +#ifdef _MSC_VER +// To see why (__BMI__) && (__PCLMUL__) && (__LZCNT__) are not part of this next line, see +// https://github.com/simdjson/simdjson/issues/1247 +#define SIMDJSON_CAN_ALWAYS_RUN_ICELAKE ((SIMDJSON_IMPLEMENTATION_ICELAKE) && (__AVX2__) && (__AVX512F__) && (__AVX512DQ__) && (__AVX512CD__) && (__AVX512BW__) && (__AVX512VL__) && (__AVX512VBMI2__)) +#else +#define SIMDJSON_CAN_ALWAYS_RUN_ICELAKE ((SIMDJSON_IMPLEMENTATION_ICELAKE) && (__AVX2__) && (__BMI__) && (__PCLMUL__) && (__LZCNT__) && (__AVX512F__) && (__AVX512DQ__) && (__AVX512CD__) && (__AVX512BW__) && (__AVX512VL__) && (__AVX512VBMI2__)) +#endif + +// Default Haswell to on if this is x86-64. Even if we're not compiled for it, it could be selected +// at runtime. +#ifndef SIMDJSON_IMPLEMENTATION_HASWELL +#if SIMDJSON_CAN_ALWAYS_RUN_ICELAKE +// if icelake is always available, never enable haswell. +#define SIMDJSON_IMPLEMENTATION_HASWELL 0 +#else +#define SIMDJSON_IMPLEMENTATION_HASWELL SIMDJSON_IS_X86_64 +#endif +#endif +#ifdef _MSC_VER +// To see why (__BMI__) && (__PCLMUL__) && (__LZCNT__) are not part of this next line, see +// https://github.com/simdjson/simdjson/issues/1247 +#define SIMDJSON_CAN_ALWAYS_RUN_HASWELL ((SIMDJSON_IMPLEMENTATION_HASWELL) && (SIMDJSON_IS_X86_64) && (__AVX2__)) +#else +#define SIMDJSON_CAN_ALWAYS_RUN_HASWELL ((SIMDJSON_IMPLEMENTATION_HASWELL) && (SIMDJSON_IS_X86_64) && (__AVX2__) && (__BMI__) && (__PCLMUL__) && (__LZCNT__)) +#endif + +// Default Westmere to on if this is x86-64. +#ifndef SIMDJSON_IMPLEMENTATION_WESTMERE +#if SIMDJSON_CAN_ALWAYS_RUN_ICELAKE || SIMDJSON_CAN_ALWAYS_RUN_HASWELL +// if icelake or haswell are always available, never enable westmere. +#define SIMDJSON_IMPLEMENTATION_WESTMERE 0 +#else +#define SIMDJSON_IMPLEMENTATION_WESTMERE SIMDJSON_IS_X86_64 +#endif +#endif +#define SIMDJSON_CAN_ALWAYS_RUN_WESTMERE (SIMDJSON_IMPLEMENTATION_WESTMERE && SIMDJSON_IS_X86_64 && __SSE4_2__ && __PCLMUL__) + +#ifndef SIMDJSON_IMPLEMENTATION_PPC64 +#define SIMDJSON_IMPLEMENTATION_PPC64 (SIMDJSON_IS_PPC64 && SIMDJSON_IS_PPC64_VMX) +#endif +#define SIMDJSON_CAN_ALWAYS_RUN_PPC64 SIMDJSON_IMPLEMENTATION_PPC64 && SIMDJSON_IS_PPC64 && SIMDJSON_IS_PPC64_VMX + +// Default Fallback to on unless a builtin implementation has already been selected. +#ifndef SIMDJSON_IMPLEMENTATION_FALLBACK +#if SIMDJSON_CAN_ALWAYS_RUN_ARM64 || SIMDJSON_CAN_ALWAYS_RUN_ICELAKE || SIMDJSON_CAN_ALWAYS_RUN_HASWELL || SIMDJSON_CAN_ALWAYS_RUN_WESTMERE || SIMDJSON_CAN_ALWAYS_RUN_PPC64 +// if anything at all except fallback can always run, then disable fallback. +#define SIMDJSON_IMPLEMENTATION_FALLBACK 0 +#else +#define SIMDJSON_IMPLEMENTATION_FALLBACK 1 +#endif +#endif +#define SIMDJSON_CAN_ALWAYS_RUN_FALLBACK SIMDJSON_IMPLEMENTATION_FALLBACK + +// Determine the best builtin implementation +#ifndef SIMDJSON_BUILTIN_IMPLEMENTATION + +#if SIMDJSON_CAN_ALWAYS_RUN_ICELAKE +#define SIMDJSON_BUILTIN_IMPLEMENTATION icelake +#elif SIMDJSON_CAN_ALWAYS_RUN_HASWELL +#define SIMDJSON_BUILTIN_IMPLEMENTATION haswell +#elif SIMDJSON_CAN_ALWAYS_RUN_WESTMERE +#define SIMDJSON_BUILTIN_IMPLEMENTATION westmere +#elif SIMDJSON_CAN_ALWAYS_RUN_ARM64 +#define SIMDJSON_BUILTIN_IMPLEMENTATION arm64 +#elif SIMDJSON_CAN_ALWAYS_RUN_PPC64 +#define SIMDJSON_BUILTIN_IMPLEMENTATION ppc64 +#elif SIMDJSON_CAN_ALWAYS_RUN_FALLBACK +#define SIMDJSON_BUILTIN_IMPLEMENTATION fallback +#else +#error "All possible implementations (including fallback) have been disabled! simdjson will not run." +#endif + +#endif // SIMDJSON_BUILTIN_IMPLEMENTATION + +#define SIMDJSON_BUILTIN_IMPLEMENTATION_ID SIMDJSON_IMPLEMENTATION_ID_FOR(SIMDJSON_BUILTIN_IMPLEMENTATION) +#define SIMDJSON_BUILTIN_IMPLEMENTATION_IS(IMPL) SIMDJSON_BUILTIN_IMPLEMENTATION_ID == SIMDJSON_IMPLEMENTATION_ID_FOR(IMPL) + +#endif // SIMDJSON_IMPLEMENTATION_DETECTION_H +/* end file simdjson/implementation_detection.h */ + +#if SIMDJSON_IMPLEMENTATION_ARM64 || SIMDJSON_IMPLEMENTATION_ICELAKE || SIMDJSON_IMPLEMENTATION_HASWELL || SIMDJSON_IMPLEMENTATION_WESTMERE || SIMDJSON_IMPLEMENTATION_PPC64 + +#include + +namespace simdjson { // table modified and copied from +namespace internal { // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable +SIMDJSON_DLLIMPORTEXPORT const unsigned char BitsSetTable256mul2[256] = { + 0, 2, 2, 4, 2, 4, 4, 6, 2, 4, 4, 6, 4, 6, 6, 8, 2, 4, 4, + 6, 4, 6, 6, 8, 4, 6, 6, 8, 6, 8, 8, 10, 2, 4, 4, 6, 4, 6, + 6, 8, 4, 6, 6, 8, 6, 8, 8, 10, 4, 6, 6, 8, 6, 8, 8, 10, 6, + 8, 8, 10, 8, 10, 10, 12, 2, 4, 4, 6, 4, 6, 6, 8, 4, 6, 6, 8, + 6, 8, 8, 10, 4, 6, 6, 8, 6, 8, 8, 10, 6, 8, 8, 10, 8, 10, 10, + 12, 4, 6, 6, 8, 6, 8, 8, 10, 6, 8, 8, 10, 8, 10, 10, 12, 6, 8, + 8, 10, 8, 10, 10, 12, 8, 10, 10, 12, 10, 12, 12, 14, 2, 4, 4, 6, 4, + 6, 6, 8, 4, 6, 6, 8, 6, 8, 8, 10, 4, 6, 6, 8, 6, 8, 8, 10, + 6, 8, 8, 10, 8, 10, 10, 12, 4, 6, 6, 8, 6, 8, 8, 10, 6, 8, 8, + 10, 8, 10, 10, 12, 6, 8, 8, 10, 8, 10, 10, 12, 8, 10, 10, 12, 10, 12, + 12, 14, 4, 6, 6, 8, 6, 8, 8, 10, 6, 8, 8, 10, 8, 10, 10, 12, 6, + 8, 8, 10, 8, 10, 10, 12, 8, 10, 10, 12, 10, 12, 12, 14, 6, 8, 8, 10, + 8, 10, 10, 12, 8, 10, 10, 12, 10, 12, 12, 14, 8, 10, 10, 12, 10, 12, 12, + 14, 10, 12, 12, 14, 12, 14, 14, 16}; + +SIMDJSON_DLLIMPORTEXPORT const uint8_t pshufb_combine_table[272] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x01, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; + +// 256 * 8 bytes = 2kB, easily fits in cache. +SIMDJSON_DLLIMPORTEXPORT const uint64_t thintable_epi8[256] = { + 0x0706050403020100, 0x0007060504030201, 0x0007060504030200, + 0x0000070605040302, 0x0007060504030100, 0x0000070605040301, + 0x0000070605040300, 0x0000000706050403, 0x0007060504020100, + 0x0000070605040201, 0x0000070605040200, 0x0000000706050402, + 0x0000070605040100, 0x0000000706050401, 0x0000000706050400, + 0x0000000007060504, 0x0007060503020100, 0x0000070605030201, + 0x0000070605030200, 0x0000000706050302, 0x0000070605030100, + 0x0000000706050301, 0x0000000706050300, 0x0000000007060503, + 0x0000070605020100, 0x0000000706050201, 0x0000000706050200, + 0x0000000007060502, 0x0000000706050100, 0x0000000007060501, + 0x0000000007060500, 0x0000000000070605, 0x0007060403020100, + 0x0000070604030201, 0x0000070604030200, 0x0000000706040302, + 0x0000070604030100, 0x0000000706040301, 0x0000000706040300, + 0x0000000007060403, 0x0000070604020100, 0x0000000706040201, + 0x0000000706040200, 0x0000000007060402, 0x0000000706040100, + 0x0000000007060401, 0x0000000007060400, 0x0000000000070604, + 0x0000070603020100, 0x0000000706030201, 0x0000000706030200, + 0x0000000007060302, 0x0000000706030100, 0x0000000007060301, + 0x0000000007060300, 0x0000000000070603, 0x0000000706020100, + 0x0000000007060201, 0x0000000007060200, 0x0000000000070602, + 0x0000000007060100, 0x0000000000070601, 0x0000000000070600, + 0x0000000000000706, 0x0007050403020100, 0x0000070504030201, + 0x0000070504030200, 0x0000000705040302, 0x0000070504030100, + 0x0000000705040301, 0x0000000705040300, 0x0000000007050403, + 0x0000070504020100, 0x0000000705040201, 0x0000000705040200, + 0x0000000007050402, 0x0000000705040100, 0x0000000007050401, + 0x0000000007050400, 0x0000000000070504, 0x0000070503020100, + 0x0000000705030201, 0x0000000705030200, 0x0000000007050302, + 0x0000000705030100, 0x0000000007050301, 0x0000000007050300, + 0x0000000000070503, 0x0000000705020100, 0x0000000007050201, + 0x0000000007050200, 0x0000000000070502, 0x0000000007050100, + 0x0000000000070501, 0x0000000000070500, 0x0000000000000705, + 0x0000070403020100, 0x0000000704030201, 0x0000000704030200, + 0x0000000007040302, 0x0000000704030100, 0x0000000007040301, + 0x0000000007040300, 0x0000000000070403, 0x0000000704020100, + 0x0000000007040201, 0x0000000007040200, 0x0000000000070402, + 0x0000000007040100, 0x0000000000070401, 0x0000000000070400, + 0x0000000000000704, 0x0000000703020100, 0x0000000007030201, + 0x0000000007030200, 0x0000000000070302, 0x0000000007030100, + 0x0000000000070301, 0x0000000000070300, 0x0000000000000703, + 0x0000000007020100, 0x0000000000070201, 0x0000000000070200, + 0x0000000000000702, 0x0000000000070100, 0x0000000000000701, + 0x0000000000000700, 0x0000000000000007, 0x0006050403020100, + 0x0000060504030201, 0x0000060504030200, 0x0000000605040302, + 0x0000060504030100, 0x0000000605040301, 0x0000000605040300, + 0x0000000006050403, 0x0000060504020100, 0x0000000605040201, + 0x0000000605040200, 0x0000000006050402, 0x0000000605040100, + 0x0000000006050401, 0x0000000006050400, 0x0000000000060504, + 0x0000060503020100, 0x0000000605030201, 0x0000000605030200, + 0x0000000006050302, 0x0000000605030100, 0x0000000006050301, + 0x0000000006050300, 0x0000000000060503, 0x0000000605020100, + 0x0000000006050201, 0x0000000006050200, 0x0000000000060502, + 0x0000000006050100, 0x0000000000060501, 0x0000000000060500, + 0x0000000000000605, 0x0000060403020100, 0x0000000604030201, + 0x0000000604030200, 0x0000000006040302, 0x0000000604030100, + 0x0000000006040301, 0x0000000006040300, 0x0000000000060403, + 0x0000000604020100, 0x0000000006040201, 0x0000000006040200, + 0x0000000000060402, 0x0000000006040100, 0x0000000000060401, + 0x0000000000060400, 0x0000000000000604, 0x0000000603020100, + 0x0000000006030201, 0x0000000006030200, 0x0000000000060302, + 0x0000000006030100, 0x0000000000060301, 0x0000000000060300, + 0x0000000000000603, 0x0000000006020100, 0x0000000000060201, + 0x0000000000060200, 0x0000000000000602, 0x0000000000060100, + 0x0000000000000601, 0x0000000000000600, 0x0000000000000006, + 0x0000050403020100, 0x0000000504030201, 0x0000000504030200, + 0x0000000005040302, 0x0000000504030100, 0x0000000005040301, + 0x0000000005040300, 0x0000000000050403, 0x0000000504020100, + 0x0000000005040201, 0x0000000005040200, 0x0000000000050402, + 0x0000000005040100, 0x0000000000050401, 0x0000000000050400, + 0x0000000000000504, 0x0000000503020100, 0x0000000005030201, + 0x0000000005030200, 0x0000000000050302, 0x0000000005030100, + 0x0000000000050301, 0x0000000000050300, 0x0000000000000503, + 0x0000000005020100, 0x0000000000050201, 0x0000000000050200, + 0x0000000000000502, 0x0000000000050100, 0x0000000000000501, + 0x0000000000000500, 0x0000000000000005, 0x0000000403020100, + 0x0000000004030201, 0x0000000004030200, 0x0000000000040302, + 0x0000000004030100, 0x0000000000040301, 0x0000000000040300, + 0x0000000000000403, 0x0000000004020100, 0x0000000000040201, + 0x0000000000040200, 0x0000000000000402, 0x0000000000040100, + 0x0000000000000401, 0x0000000000000400, 0x0000000000000004, + 0x0000000003020100, 0x0000000000030201, 0x0000000000030200, + 0x0000000000000302, 0x0000000000030100, 0x0000000000000301, + 0x0000000000000300, 0x0000000000000003, 0x0000000000020100, + 0x0000000000000201, 0x0000000000000200, 0x0000000000000002, + 0x0000000000000100, 0x0000000000000001, 0x0000000000000000, + 0x0000000000000000, +}; //static uint64_t thintable_epi8[256] + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_IMPLEMENTATION_ARM64 || SIMDJSON_IMPLEMENTATION_ICELAKE || SIMDJSON_IMPLEMENTATION_HASWELL || SIMDJSON_IMPLEMENTATION_WESTMERE || SIMDJSON_IMPLEMENTATION_PPC64 + +#endif // SIMDJSON_SRC_SIMDPRUNE_TABLES_CPP +/* end file internal/simdprune_tables.cpp */ + +/* including simdjson/generic/dependencies.h: #include */ +/* begin file simdjson/generic/dependencies.h */ +#ifdef SIMDJSON_CONDITIONAL_INCLUDE +#error simdjson/generic/dependencies.h must be included before defining SIMDJSON_CONDITIONAL_INCLUDE! +#endif + +#ifndef SIMDJSON_GENERIC_DEPENDENCIES_H +#define SIMDJSON_GENERIC_DEPENDENCIES_H + +// Internal headers needed for generics. +// All includes referencing simdjson headers *not* under simdjson/generic must be here! +// Otherwise, amalgamation will fail. +/* skipped duplicate #include "simdjson/base.h" */ +/* including simdjson/implementation.h: #include "simdjson/implementation.h" */ +/* begin file simdjson/implementation.h */ +#ifndef SIMDJSON_IMPLEMENTATION_H +#define SIMDJSON_IMPLEMENTATION_H + +/* including simdjson/internal/atomic_ptr.h: #include "simdjson/internal/atomic_ptr.h" */ +/* begin file simdjson/internal/atomic_ptr.h */ +#ifndef SIMDJSON_INTERNAL_ATOMIC_PTR_H +#define SIMDJSON_INTERNAL_ATOMIC_PTR_H + +/* skipped duplicate #include "simdjson/base.h" */ +#include + +namespace simdjson { +namespace internal { + +template +class atomic_ptr { +public: + atomic_ptr(T *_ptr) : ptr{_ptr} {} + + operator const T*() const { return ptr.load(); } + const T& operator*() const { return *ptr; } + const T* operator->() const { return ptr.load(); } + + operator T*() { return ptr.load(); } + T& operator*() { return *ptr; } + T* operator->() { return ptr.load(); } + atomic_ptr& operator=(T *_ptr) { ptr = _ptr; return *this; } + +private: + std::atomic ptr; +}; + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_ATOMIC_PTR_H +/* end file simdjson/internal/atomic_ptr.h */ +/* including simdjson/internal/dom_parser_implementation.h: #include "simdjson/internal/dom_parser_implementation.h" */ +/* begin file simdjson/internal/dom_parser_implementation.h */ +#ifndef SIMDJSON_INTERNAL_DOM_PARSER_IMPLEMENTATION_H +#define SIMDJSON_INTERNAL_DOM_PARSER_IMPLEMENTATION_H + +/* skipped duplicate #include "simdjson/base.h" */ +/* skipped duplicate #include "simdjson/error.h" */ +#include + +namespace simdjson { + +namespace dom { +class document; +} // namespace dom + +/** +* This enum is used with the dom_parser_implementation::stage1 function. +* 1) The regular mode expects a fully formed JSON document. +* 2) The streaming_partial mode expects a possibly truncated +* input within a stream on JSON documents. +* 3) The stream_final mode allows us to truncate final +* unterminated strings. It is useful in conjunction with streaming_partial. +*/ +enum class stage1_mode { regular, streaming_partial, streaming_final}; + +/** + * Returns true if mode == streaming_partial or mode == streaming_final + */ +inline bool is_streaming(stage1_mode mode) { + // performance note: it is probably faster to check that mode is different + // from regular than checking that it is either streaming_partial or streaming_final. + return (mode != stage1_mode::regular); + // return (mode == stage1_mode::streaming_partial || mode == stage1_mode::streaming_final); +} + + +namespace internal { + + +/** + * An implementation of simdjson's DOM parser for a particular CPU architecture. + * + * This class is expected to be accessed only by pointer, and never move in memory (though the + * pointer can move). + */ +class dom_parser_implementation { +public: + + /** + * @private For internal implementation use + * + * Run a full JSON parse on a single document (stage1 + stage2). + * + * Guaranteed only to be called when capacity > document length. + * + * Overridden by each implementation. + * + * @param buf The json document to parse. *MUST* be allocated up to len + SIMDJSON_PADDING bytes. + * @param len The length of the json document. + * @return The error code, or SUCCESS if there was no error. + */ + simdjson_warn_unused virtual error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept = 0; + + /** + * @private For internal implementation use + * + * Stage 1 of the document parser. + * + * Guaranteed only to be called when capacity > document length. + * + * Overridden by each implementation. + * + * @param buf The json document to parse. + * @param len The length of the json document. + * @param streaming Whether this is being called by parser::parse_many. + * @return The error code, or SUCCESS if there was no error. + */ + simdjson_warn_unused virtual error_code stage1(const uint8_t *buf, size_t len, stage1_mode streaming) noexcept = 0; + + /** + * @private For internal implementation use + * + * Stage 2 of the document parser. + * + * Called after stage1(). + * + * Overridden by each implementation. + * + * @param doc The document to output to. + * @return The error code, or SUCCESS if there was no error. + */ + simdjson_warn_unused virtual error_code stage2(dom::document &doc) noexcept = 0; + + /** + * @private For internal implementation use + * + * Stage 2 of the document parser for parser::parse_many. + * + * Guaranteed only to be called after stage1(). + * Overridden by each implementation. + * + * @param doc The document to output to. + * @return The error code, SUCCESS if there was no error, or EMPTY if all documents have been parsed. + */ + simdjson_warn_unused virtual error_code stage2_next(dom::document &doc) noexcept = 0; + + /** + * Unescape a valid UTF-8 string from src to dst, stopping at a final unescaped quote. There + * must be an unescaped quote terminating the string. It returns the final output + * position as pointer. In case of error (e.g., the string has bad escaped codes), + * then null_nullptrptr is returned. It is assumed that the output buffer is large + * enough. E.g., if src points at 'joe"', then dst needs to have four free bytes + + * SIMDJSON_PADDING bytes. + * + * Overridden by each implementation. + * + * @param str pointer to the beginning of a valid UTF-8 JSON string, must end with an unescaped quote. + * @param dst pointer to a destination buffer, it must point a region in memory of sufficient size. + * @param allow_replacement whether we allow a replacement character when the UTF-8 contains unmatched surrogate pairs. + * @return end of the of the written region (exclusive) or nullptr in case of error. + */ + simdjson_warn_unused virtual uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept = 0; + + /** + * Unescape a NON-valid UTF-8 string from src to dst, stopping at a final unescaped quote. There + * must be an unescaped quote terminating the string. It returns the final output + * position as pointer. In case of error (e.g., the string has bad escaped codes), + * then null_nullptrptr is returned. It is assumed that the output buffer is large + * enough. E.g., if src points at 'joe"', then dst needs to have four free bytes + + * SIMDJSON_PADDING bytes. + * + * Overridden by each implementation. + * + * @param str pointer to the beginning of a possibly invalid UTF-8 JSON string, must end with an unescaped quote. + * @param dst pointer to a destination buffer, it must point a region in memory of sufficient size. + * @return end of the of the written region (exclusive) or nullptr in case of error. + */ + simdjson_warn_unused virtual uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept = 0; + + /** + * Change the capacity of this parser. + * + * The capacity can never exceed SIMDJSON_MAXSIZE_BYTES (e.g., 4 GB) + * and an CAPACITY error is returned if it is attempted. + * + * Generally used for reallocation. + * + * @param capacity The new capacity. + * @param max_depth The new max_depth. + * @return The error code, or SUCCESS if there was no error. + */ + virtual error_code set_capacity(size_t capacity) noexcept = 0; + + /** + * Change the max depth of this parser. + * + * Generally used for reallocation. + * + * @param capacity The new capacity. + * @param max_depth The new max_depth. + * @return The error code, or SUCCESS if there was no error. + */ + virtual error_code set_max_depth(size_t max_depth) noexcept = 0; + + /** + * Deallocate this parser. + */ + virtual ~dom_parser_implementation() = default; + + /** Number of structural indices passed from stage 1 to stage 2 */ + uint32_t n_structural_indexes{0}; + /** Structural indices passed from stage 1 to stage 2 */ + std::unique_ptr structural_indexes{}; + /** Next structural index to parse */ + uint32_t next_structural_index{0}; + + /** + * The largest document this parser can support without reallocating. + * + * @return Current capacity, in bytes. + */ + simdjson_inline size_t capacity() const noexcept; + + /** + * The maximum level of nested object and arrays supported by this parser. + * + * @return Maximum depth, in bytes. + */ + simdjson_inline size_t max_depth() const noexcept; + + /** + * Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length + * and `max_depth` depth. + * + * @param capacity The new capacity. + * @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH. + * @return The error, if there is one. + */ + simdjson_warn_unused inline error_code allocate(size_t capacity, size_t max_depth) noexcept; + + +protected: + /** + * The maximum document length this parser supports. + * + * Buffers are large enough to handle any document up to this length. + */ + size_t _capacity{0}; + + /** + * The maximum depth (number of nested objects and arrays) supported by this parser. + * + * Defaults to DEFAULT_MAX_DEPTH. + */ + size_t _max_depth{0}; + + // Declaring these so that subclasses can use them to implement their constructors. + simdjson_inline dom_parser_implementation() noexcept; + simdjson_inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; + simdjson_inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; + + simdjson_inline dom_parser_implementation(const dom_parser_implementation &) noexcept = delete; + simdjson_inline dom_parser_implementation &operator=(const dom_parser_implementation &other) noexcept = delete; +}; // class dom_parser_implementation + +simdjson_inline dom_parser_implementation::dom_parser_implementation() noexcept = default; +simdjson_inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; +simdjson_inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; + +simdjson_inline size_t dom_parser_implementation::capacity() const noexcept { + return _capacity; +} + +simdjson_inline size_t dom_parser_implementation::max_depth() const noexcept { + return _max_depth; +} + +simdjson_warn_unused +inline error_code dom_parser_implementation::allocate(size_t capacity, size_t max_depth) noexcept { + if (this->max_depth() != max_depth) { + error_code err = set_max_depth(max_depth); + if (err) { return err; } + } + if (_capacity != capacity) { + error_code err = set_capacity(capacity); + if (err) { return err; } + } + return SUCCESS; +} + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_DOM_PARSER_IMPLEMENTATION_H +/* end file simdjson/internal/dom_parser_implementation.h */ + +#include + +namespace simdjson { + +/** + * Validate the UTF-8 string. + * + * @param buf the string to validate. + * @param len the length of the string in bytes. + * @return true if the string is valid UTF-8. + */ +simdjson_warn_unused bool validate_utf8(const char * buf, size_t len) noexcept; +/** + * Validate the UTF-8 string. + * + * @param sv the string_view to validate. + * @return true if the string is valid UTF-8. + */ +simdjson_inline simdjson_warn_unused bool validate_utf8(const std::string_view sv) noexcept { + return validate_utf8(sv.data(), sv.size()); +} + +/** + * Validate the UTF-8 string. + * + * @param p the string to validate. + * @return true if the string is valid UTF-8. + */ +simdjson_inline simdjson_warn_unused bool validate_utf8(const std::string& s) noexcept { + return validate_utf8(s.data(), s.size()); +} + +/** + * An implementation of simdjson for a particular CPU architecture. + * + * Also used to maintain the currently active implementation. The active implementation is + * automatically initialized on first use to the most advanced implementation supported by the host. + */ +class implementation { +public: + + /** + * The name of this implementation. + * + * const implementation *impl = simdjson::get_active_implementation(); + * cout << "simdjson is optimized for " << impl->name() << "(" << impl->description() << ")" << endl; + * + * @return the name of the implementation, e.g. "haswell", "westmere", "arm64". + */ + virtual const std::string &name() const { return _name; } + + /** + * The description of this implementation. + * + * const implementation *impl = simdjson::get_active_implementation(); + * cout << "simdjson is optimized for " << impl->name() << "(" << impl->description() << ")" << endl; + * + * @return the description of the implementation, e.g. "Intel/AMD AVX2", "Intel/AMD SSE4.2", "ARM NEON". + */ + virtual const std::string &description() const { return _description; } + + /** + * The instruction sets this implementation is compiled against + * and the current CPU match. This function may poll the current CPU/system + * and should therefore not be called too often if performance is a concern. + * + * @return true if the implementation can be safely used on the current system (determined at runtime). + */ + bool supported_by_runtime_system() const; + + /** + * @private For internal implementation use + * + * The instruction sets this implementation is compiled against. + * + * @return a mask of all required `internal::instruction_set::` values. + */ + virtual uint32_t required_instruction_sets() const { return _required_instruction_sets; } + + /** + * @private For internal implementation use + * + * const implementation *impl = simdjson::get_active_implementation(); + * cout << "simdjson is optimized for " << impl->name() << "(" << impl->description() << ")" << endl; + * + * @param capacity The largest document that will be passed to the parser. + * @param max_depth The maximum JSON object/array nesting this parser is expected to handle. + * @param dst The place to put the resulting parser implementation. + * @return the error code, or SUCCESS if there was no error. + */ + virtual error_code create_dom_parser_implementation( + size_t capacity, + size_t max_depth, + std::unique_ptr &dst + ) const noexcept = 0; + + /** + * @private For internal implementation use + * + * Minify the input string assuming that it represents a JSON string, does not parse or validate. + * + * Overridden by each implementation. + * + * @param buf the json document to minify. + * @param len the length of the json document. + * @param dst the buffer to write the minified document to. *MUST* be allocated up to len + SIMDJSON_PADDING bytes. + * @param dst_len the number of bytes written. Output only. + * @return the error code, or SUCCESS if there was no error. + */ + simdjson_warn_unused virtual error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept = 0; + + + /** + * Validate the UTF-8 string. + * + * Overridden by each implementation. + * + * @param buf the string to validate. + * @param len the length of the string in bytes. + * @return true if and only if the string is valid UTF-8. + */ + simdjson_warn_unused virtual bool validate_utf8(const char *buf, size_t len) const noexcept = 0; + +protected: + /** @private Construct an implementation with the given name and description. For subclasses. */ + simdjson_inline implementation( + std::string_view name, + std::string_view description, + uint32_t required_instruction_sets + ) : + _name(name), + _description(description), + _required_instruction_sets(required_instruction_sets) + { + } + virtual ~implementation()=default; + +private: + /** + * The name of this implementation. + */ + const std::string _name; + + /** + * The description of this implementation. + */ + const std::string _description; + + /** + * Instruction sets required for this implementation. + */ + const uint32_t _required_instruction_sets; +}; + +/** @private */ +namespace internal { + +/** + * The list of available implementations compiled into simdjson. + */ +class available_implementation_list { +public: + /** Get the list of available implementations compiled into simdjson */ + simdjson_inline available_implementation_list() {} + /** Number of implementations */ + size_t size() const noexcept; + /** STL const begin() iterator */ + const implementation * const *begin() const noexcept; + /** STL const end() iterator */ + const implementation * const *end() const noexcept; + + /** + * Get the implementation with the given name. + * + * Case sensitive. + * + * const implementation *impl = simdjson::get_available_implementations()["westmere"]; + * if (!impl) { exit(1); } + * if (!imp->supported_by_runtime_system()) { exit(1); } + * simdjson::get_active_implementation() = impl; + * + * @param name the implementation to find, e.g. "westmere", "haswell", "arm64" + * @return the implementation, or nullptr if the parse failed. + */ + const implementation * operator[](const std::string_view &name) const noexcept { + for (const implementation * impl : *this) { + if (impl->name() == name) { return impl; } + } + return nullptr; + } + + /** + * Detect the most advanced implementation supported by the current host. + * + * This is used to initialize the implementation on startup. + * + * const implementation *impl = simdjson::available_implementation::detect_best_supported(); + * simdjson::get_active_implementation() = impl; + * + * @return the most advanced supported implementation for the current host, or an + * implementation that returns UNSUPPORTED_ARCHITECTURE if there is no supported + * implementation. Will never return nullptr. + */ + const implementation *detect_best_supported() const noexcept; +}; + +} // namespace internal + +/** + * The list of available implementations compiled into simdjson. + */ +extern SIMDJSON_DLLIMPORTEXPORT const internal::available_implementation_list& get_available_implementations(); + +/** + * The active implementation. + * + * Automatically initialized on first use to the most advanced implementation supported by this hardware. + */ +extern SIMDJSON_DLLIMPORTEXPORT internal::atomic_ptr& get_active_implementation(); + +} // namespace simdjson + +#endif // SIMDJSON_IMPLEMENTATION_H +/* end file simdjson/implementation.h */ +/* skipped duplicate #include "simdjson/implementation_detection.h" */ +/* including simdjson/internal/instruction_set.h: #include "simdjson/internal/instruction_set.h" */ +/* begin file simdjson/internal/instruction_set.h */ +/* From +https://github.com/endorno/pytorch/blob/master/torch/lib/TH/generic/simd/simd.h +Highly modified. + +Copyright (c) 2016- Facebook, Inc (Adam Paszke) +Copyright (c) 2014- Facebook, Inc (Soumith Chintala) +Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert) +Copyright (c) 2012-2014 Deepmind Technologies (Koray Kavukcuoglu) +Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu) +Copyright (c) 2011-2013 NYU (Clement Farabet) +Copyright (c) 2006-2010 NEC Laboratories America (Ronan Collobert, Leon Bottou, +Iain Melvin, Jason Weston) Copyright (c) 2006 Idiap Research Institute +(Samy Bengio) Copyright (c) 2001-2004 Idiap Research Institute (Ronan Collobert, +Samy Bengio, Johnny Mariethoz) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the names of Facebook, Deepmind Technologies, NYU, NEC Laboratories +America and IDIAP Research Institute nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef SIMDJSON_INTERNAL_INSTRUCTION_SET_H +#define SIMDJSON_INTERNAL_INSTRUCTION_SET_H + +namespace simdjson { +namespace internal { + +enum instruction_set { + DEFAULT = 0x0, + NEON = 0x1, + AVX2 = 0x4, + SSE42 = 0x8, + PCLMULQDQ = 0x10, + BMI1 = 0x20, + BMI2 = 0x40, + ALTIVEC = 0x80, + AVX512F = 0x100, + AVX512DQ = 0x200, + AVX512IFMA = 0x400, + AVX512PF = 0x800, + AVX512ER = 0x1000, + AVX512CD = 0x2000, + AVX512BW = 0x4000, + AVX512VL = 0x8000, + AVX512VBMI2 = 0x10000 +}; + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_INSTRUCTION_SET_H +/* end file simdjson/internal/instruction_set.h */ +/* skipped duplicate #include "simdjson/internal/dom_parser_implementation.h" */ +/* skipped duplicate #include "simdjson/internal/jsoncharutils_tables.h" */ +/* skipped duplicate #include "simdjson/internal/numberparsing_tables.h" */ +/* including simdjson/internal/simdprune_tables.h: #include "simdjson/internal/simdprune_tables.h" */ +/* begin file simdjson/internal/simdprune_tables.h */ +#ifndef SIMDJSON_INTERNAL_SIMDPRUNE_TABLES_H +#define SIMDJSON_INTERNAL_SIMDPRUNE_TABLES_H + +/* skipped duplicate #include "simdjson/base.h" */ + +#include + +namespace simdjson { // table modified and copied from +namespace internal { // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable + +extern SIMDJSON_DLLIMPORTEXPORT const unsigned char BitsSetTable256mul2[256]; + +extern SIMDJSON_DLLIMPORTEXPORT const uint8_t pshufb_combine_table[272]; + +// 256 * 8 bytes = 2kB, easily fits in cache. +extern SIMDJSON_DLLIMPORTEXPORT const uint64_t thintable_epi8[256]; + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_SIMDPRUNE_TABLES_H +/* end file simdjson/internal/simdprune_tables.h */ + +#endif // SIMDJSON_GENERIC_DEPENDENCIES_H +/* end file simdjson/generic/dependencies.h */ +/* including generic/dependencies.h: #include */ +/* begin file generic/dependencies.h */ +#ifdef SIMDJSON_CONDITIONAL_INCLUDE +#error generic/dependencies.h must be included before defining SIMDJSON_CONDITIONAL_INCLUDE! +#endif + +#ifndef SIMDJSON_SRC_GENERIC_DEPENDENCIES_H +#define SIMDJSON_SRC_GENERIC_DEPENDENCIES_H + +/* skipped duplicate #include */ + +#endif // SIMDJSON_SRC_GENERIC_DEPENDENCIES_H +/* end file generic/dependencies.h */ +/* including generic/stage1/dependencies.h: #include */ +/* begin file generic/stage1/dependencies.h */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_DEPENDENCIES_H +#define SIMDJSON_SRC_GENERIC_STAGE1_DEPENDENCIES_H + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_DEPENDENCIES_H +/* end file generic/stage1/dependencies.h */ +/* including generic/stage2/dependencies.h: #include */ +/* begin file generic/stage2/dependencies.h */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_DEPENDENCIES_H +#define SIMDJSON_SRC_GENERIC_STAGE2_DEPENDENCIES_H + +/* including simdjson/dom/document.h: #include */ +/* begin file simdjson/dom/document.h */ +#ifndef SIMDJSON_DOM_DOCUMENT_H +#define SIMDJSON_DOM_DOCUMENT_H + +/* including simdjson/dom/base.h: #include "simdjson/dom/base.h" */ +/* begin file simdjson/dom/base.h */ +#ifndef SIMDJSON_DOM_BASE_H +#define SIMDJSON_DOM_BASE_H + +/* skipped duplicate #include "simdjson/base.h" */ + +namespace simdjson { + +/** + * @brief A DOM API on top of the simdjson parser. + */ +namespace dom { + +/** The default batch size for parser.parse_many() and parser.load_many() */ +static constexpr size_t DEFAULT_BATCH_SIZE = 1000000; +/** + * Some adversary might try to set the batch size to 0 or 1, which might cause problems. + * We set a minimum of 32B since anything else is highly likely to be an error. In practice, + * most users will want a much larger batch size. + * + * All non-negative MINIMAL_BATCH_SIZE values should be 'safe' except that, obviously, no JSON + * document can ever span 0 or 1 byte and that very large values would create memory allocation issues. + */ +static constexpr size_t MINIMAL_BATCH_SIZE = 32; + +/** + * It is wasteful to allocate memory for tiny documents (e.g., 4 bytes). + */ +static constexpr size_t MINIMAL_DOCUMENT_CAPACITY = 32; + +class array; +class document; +class document_stream; +class element; +class key_value_pair; +class object; +class parser; + +#ifdef SIMDJSON_THREADS_ENABLED +struct stage1_worker; +#endif // SIMDJSON_THREADS_ENABLED + +} // namespace dom + +namespace internal { + +template +class string_builder; +class tape_ref; + +} // namespace internal + +} // namespace simdjson + +#endif // SIMDJSON_DOM_BASE_H +/* end file simdjson/dom/base.h */ + +#include + +namespace simdjson { +namespace dom { + +/** + * A parsed JSON document. + * + * This class cannot be copied, only moved, to avoid unintended allocations. + */ +class document { +public: + /** + * Create a document container with zero capacity. + * + * The parser will allocate capacity as needed. + */ + document() noexcept = default; + ~document() noexcept = default; + + /** + * Take another document's buffers. + * + * @param other The document to take. Its capacity is zeroed and it is invalidated. + */ + document(document &&other) noexcept = default; + /** @private */ + document(const document &) = delete; // Disallow copying + /** + * Take another document's buffers. + * + * @param other The document to take. Its capacity is zeroed. + */ + document &operator=(document &&other) noexcept = default; + /** @private */ + document &operator=(const document &) = delete; // Disallow copying + + /** + * Get the root element of this document as a JSON array. + */ + element root() const noexcept; + + /** + * @private Dump the raw tape for debugging. + * + * @param os the stream to output to. + * @return false if the tape is likely wrong (e.g., you did not parse a valid JSON). + */ + bool dump_raw_tape(std::ostream &os) const noexcept; + + /** @private Structural values. */ + std::unique_ptr tape{}; + + /** @private String values. + * + * Should be at least byte_capacity. + */ + std::unique_ptr string_buf{}; + /** @private Allocate memory to support + * input JSON documents of up to len bytes. + * + * When calling this function, you lose + * all the data. + * + * The memory allocation is strict: you + * can you use this function to increase + * or lower the amount of allocated memory. + * Passsing zero clears the memory. + */ + error_code allocate(size_t len) noexcept; + /** @private Capacity in bytes, in terms + * of how many bytes of input JSON we can + * support. + */ + size_t capacity() const noexcept; + + +private: + size_t allocated_capacity{0}; + friend class parser; +}; // class document + +} // namespace dom +} // namespace simdjson + +#endif // SIMDJSON_DOM_DOCUMENT_H +/* end file simdjson/dom/document.h */ +/* including simdjson/internal/tape_type.h: #include */ +/* begin file simdjson/internal/tape_type.h */ +#ifndef SIMDJSON_INTERNAL_TAPE_TYPE_H +#define SIMDJSON_INTERNAL_TAPE_TYPE_H + +namespace simdjson { +namespace internal { + +/** + * The possible types in the tape. + */ +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' +}; // enum class tape_type + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_TAPE_TYPE_H +/* end file simdjson/internal/tape_type.h */ + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_DEPENDENCIES_H +/* end file generic/stage2/dependencies.h */ + +/* including implementation.cpp: #include */ +/* begin file implementation.cpp */ +#ifndef SIMDJSON_SRC_IMPLEMENTATION_CPP +#define SIMDJSON_SRC_IMPLEMENTATION_CPP + +/* skipped duplicate #include */ +/* skipped duplicate #include */ +/* skipped duplicate #include */ +/* including internal/isadetection.h: #include */ +/* begin file internal/isadetection.h */ +/* From +https://github.com/endorno/pytorch/blob/master/torch/lib/TH/generic/simd/simd.h +Highly modified. + +Copyright (c) 2016- Facebook, Inc (Adam Paszke) +Copyright (c) 2014- Facebook, Inc (Soumith Chintala) +Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert) +Copyright (c) 2012-2014 Deepmind Technologies (Koray Kavukcuoglu) +Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu) +Copyright (c) 2011-2013 NYU (Clement Farabet) +Copyright (c) 2006-2010 NEC Laboratories America (Ronan Collobert, Leon Bottou, +Iain Melvin, Jason Weston) Copyright (c) 2006 Idiap Research Institute +(Samy Bengio) Copyright (c) 2001-2004 Idiap Research Institute (Ronan Collobert, +Samy Bengio, Johnny Mariethoz) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the names of Facebook, Deepmind Technologies, NYU, NEC Laboratories +America and IDIAP Research Institute nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef SIMDJSON_INTERNAL_ISADETECTION_H +#define SIMDJSON_INTERNAL_ISADETECTION_H + +/* skipped duplicate #include "simdjson/internal/instruction_set.h" */ + +#include +#include +#if defined(_MSC_VER) +#include +#elif defined(HAVE_GCC_GET_CPUID) && defined(USE_GCC_GET_CPUID) +#include +#endif + +namespace simdjson { +namespace internal { + +#if defined(__PPC64__) + +static inline uint32_t detect_supported_architectures() { + return instruction_set::ALTIVEC; +} + +#elif defined(__aarch64__) || defined(_M_ARM64) + +static inline uint32_t detect_supported_architectures() { + return instruction_set::NEON; +} + +#elif defined(__x86_64__) || defined(_M_AMD64) // x64 + + +namespace { +// Can be found on Intel ISA Reference for CPUID +constexpr uint32_t cpuid_avx2_bit = 1 << 5; ///< @private Bit 5 of EBX for EAX=0x7 +constexpr uint32_t cpuid_bmi1_bit = 1 << 3; ///< @private bit 3 of EBX for EAX=0x7 +constexpr uint32_t cpuid_bmi2_bit = 1 << 8; ///< @private bit 8 of EBX for EAX=0x7 +constexpr uint32_t cpuid_avx512f_bit = 1 << 16; ///< @private bit 16 of EBX for EAX=0x7 +constexpr uint32_t cpuid_avx512dq_bit = 1 << 17; ///< @private bit 17 of EBX for EAX=0x7 +constexpr uint32_t cpuid_avx512ifma_bit = 1 << 21; ///< @private bit 21 of EBX for EAX=0x7 +constexpr uint32_t cpuid_avx512pf_bit = 1 << 26; ///< @private bit 26 of EBX for EAX=0x7 +constexpr uint32_t cpuid_avx512er_bit = 1 << 27; ///< @private bit 27 of EBX for EAX=0x7 +constexpr uint32_t cpuid_avx512cd_bit = 1 << 28; ///< @private bit 28 of EBX for EAX=0x7 +constexpr uint32_t cpuid_avx512bw_bit = 1 << 30; ///< @private bit 30 of EBX for EAX=0x7 +constexpr uint32_t cpuid_avx512vl_bit = 1U << 31; ///< @private bit 31 of EBX for EAX=0x7 +constexpr uint32_t cpuid_avx512vbmi2_bit = 1 << 6; ///< @private bit 6 of ECX for EAX=0x7 +constexpr uint64_t cpuid_avx256_saved = uint64_t(1) << 2; ///< @private bit 2 = AVX +constexpr uint64_t cpuid_avx512_saved = uint64_t(7) << 5; ///< @private bits 5,6,7 = opmask, ZMM_hi256, hi16_ZMM +constexpr uint32_t cpuid_sse42_bit = 1 << 20; ///< @private bit 20 of ECX for EAX=0x1 +constexpr uint32_t cpuid_osxsave = (uint32_t(1) << 26) | (uint32_t(1) << 27); ///< @private bits 26+27 of ECX for EAX=0x1 +constexpr uint32_t cpuid_pclmulqdq_bit = 1 << 1; ///< @private bit 1 of ECX for EAX=0x1 +} + + + +static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, + uint32_t *edx) { +#if defined(_MSC_VER) + int cpu_info[4]; + __cpuidex(cpu_info, *eax, *ecx); + *eax = cpu_info[0]; + *ebx = cpu_info[1]; + *ecx = cpu_info[2]; + *edx = cpu_info[3]; +#elif defined(HAVE_GCC_GET_CPUID) && defined(USE_GCC_GET_CPUID) + uint32_t level = *eax; + __get_cpuid(level, eax, ebx, ecx, edx); +#else + uint32_t a = *eax, b, c = *ecx, d; + asm volatile("cpuid\n\t" : "+a"(a), "=b"(b), "+c"(c), "=d"(d)); + *eax = a; + *ebx = b; + *ecx = c; + *edx = d; +#endif +} + + +static inline uint64_t xgetbv() { +#if defined(_MSC_VER) + return _xgetbv(0); +#else + uint32_t xcr0_lo, xcr0_hi; + asm volatile("xgetbv\n\t" : "=a" (xcr0_lo), "=d" (xcr0_hi) : "c" (0)); + return xcr0_lo | (uint64_t(xcr0_hi) << 32); +#endif +} + +static inline uint32_t detect_supported_architectures() { + uint32_t eax, ebx, ecx, edx; + uint32_t host_isa = 0x0; + + // EBX for EAX=0x1 + eax = 0x1; + ecx = 0x0; + cpuid(&eax, &ebx, &ecx, &edx); + + if (ecx & cpuid_sse42_bit) { + host_isa |= instruction_set::SSE42; + } else { + return host_isa; // everything after is redundant + } + + if (ecx & cpuid_pclmulqdq_bit) { + host_isa |= instruction_set::PCLMULQDQ; + } + + + if ((ecx & cpuid_osxsave) != cpuid_osxsave) { + return host_isa; + } + + // xgetbv for checking if the OS saves registers + uint64_t xcr0 = xgetbv(); + + if ((xcr0 & cpuid_avx256_saved) == 0) { + return host_isa; + } + + // ECX for EAX=0x7 + eax = 0x7; + ecx = 0x0; + cpuid(&eax, &ebx, &ecx, &edx); + if (ebx & cpuid_avx2_bit) { + host_isa |= instruction_set::AVX2; + } + if (ebx & cpuid_bmi1_bit) { + host_isa |= instruction_set::BMI1; + } + + if (ebx & cpuid_bmi2_bit) { + host_isa |= instruction_set::BMI2; + } + + if (!((xcr0 & cpuid_avx512_saved) == cpuid_avx512_saved)) { + return host_isa; + } + + if (ebx & cpuid_avx512f_bit) { + host_isa |= instruction_set::AVX512F; + } + + if (ebx & cpuid_avx512dq_bit) { + host_isa |= instruction_set::AVX512DQ; + } + + if (ebx & cpuid_avx512ifma_bit) { + host_isa |= instruction_set::AVX512IFMA; + } + + if (ebx & cpuid_avx512pf_bit) { + host_isa |= instruction_set::AVX512PF; + } + + if (ebx & cpuid_avx512er_bit) { + host_isa |= instruction_set::AVX512ER; + } + + if (ebx & cpuid_avx512cd_bit) { + host_isa |= instruction_set::AVX512CD; + } + + if (ebx & cpuid_avx512bw_bit) { + host_isa |= instruction_set::AVX512BW; + } + + if (ebx & cpuid_avx512vl_bit) { + host_isa |= instruction_set::AVX512VL; + } + + if (ecx & cpuid_avx512vbmi2_bit) { + host_isa |= instruction_set::AVX512VBMI2; + } + + return host_isa; +} +#else // fallback + + +static inline uint32_t detect_supported_architectures() { + return instruction_set::DEFAULT; +} + + +#endif // end SIMD extension detection code + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_ISADETECTION_H +/* end file internal/isadetection.h */ + +#include + +namespace simdjson { + +bool implementation::supported_by_runtime_system() const { + uint32_t required_instruction_sets = this->required_instruction_sets(); + uint32_t supported_instruction_sets = internal::detect_supported_architectures(); + return ((supported_instruction_sets & required_instruction_sets) == required_instruction_sets); +} + +} // namespace simdjson + +/* defining SIMDJSON_CONDITIONAL_INCLUDE */ +#define SIMDJSON_CONDITIONAL_INCLUDE + +#if SIMDJSON_IMPLEMENTATION_ARM64 +/* including simdjson/arm64/implementation.h: #include */ +/* begin file simdjson/arm64/implementation.h */ +#ifndef SIMDJSON_ARM64_IMPLEMENTATION_H +#define SIMDJSON_ARM64_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation("arm64", "ARM NEON", internal::instruction_set::NEON) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_IMPLEMENTATION_H +/* end file simdjson/arm64/implementation.h */ +namespace simdjson { +namespace internal { +static const arm64::implementation* get_arm64_singleton() { + static const arm64::implementation arm64_singleton{}; + return &arm64_singleton; +} +} // namespace internal +} // namespace simdjson +#endif // SIMDJSON_IMPLEMENTATION_ARM64 + +#if SIMDJSON_IMPLEMENTATION_FALLBACK +/* including simdjson/fallback/implementation.h: #include */ +/* begin file simdjson/fallback/implementation.h */ +#ifndef SIMDJSON_FALLBACK_IMPLEMENTATION_H +#define SIMDJSON_FALLBACK_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation( + "fallback", + "Generic fallback implementation", + 0 + ) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_IMPLEMENTATION_H +/* end file simdjson/fallback/implementation.h */ +namespace simdjson { +namespace internal { +static const fallback::implementation* get_fallback_singleton() { + static const fallback::implementation fallback_singleton{}; + return &fallback_singleton; +} +} // namespace internal +} // namespace simdjson +#endif // SIMDJSON_IMPLEMENTATION_FALLBACK + + +#if SIMDJSON_IMPLEMENTATION_HASWELL +/* including simdjson/haswell/implementation.h: #include */ +/* begin file simdjson/haswell/implementation.h */ +#ifndef SIMDJSON_HASWELL_IMPLEMENTATION_H +#define SIMDJSON_HASWELL_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_HASWELL +namespace simdjson { +namespace haswell { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation( + "haswell", + "Intel/AMD AVX2", + internal::instruction_set::AVX2 | internal::instruction_set::PCLMULQDQ | internal::instruction_set::BMI1 | internal::instruction_set::BMI2 + ) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_IMPLEMENTATION_H +/* end file simdjson/haswell/implementation.h */ +namespace simdjson { +namespace internal { +static const haswell::implementation* get_haswell_singleton() { + static const haswell::implementation haswell_singleton{}; + return &haswell_singleton; +} +} // namespace internal +} // namespace simdjson +#endif + +#if SIMDJSON_IMPLEMENTATION_ICELAKE +/* including simdjson/icelake/implementation.h: #include */ +/* begin file simdjson/icelake/implementation.h */ +#ifndef SIMDJSON_ICELAKE_IMPLEMENTATION_H +#define SIMDJSON_ICELAKE_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_ICELAKE +namespace simdjson { +namespace icelake { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation( + "icelake", + "Intel/AMD AVX512", + internal::instruction_set::AVX2 | internal::instruction_set::PCLMULQDQ | internal::instruction_set::BMI1 | internal::instruction_set::BMI2 | internal::instruction_set::AVX512F | internal::instruction_set::AVX512DQ | internal::instruction_set::AVX512CD | internal::instruction_set::AVX512BW | internal::instruction_set::AVX512VL | internal::instruction_set::AVX512VBMI2 + ) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_IMPLEMENTATION_H +/* end file simdjson/icelake/implementation.h */ +namespace simdjson { +namespace internal { +static const icelake::implementation* get_icelake_singleton() { + static const icelake::implementation icelake_singleton{}; + return &icelake_singleton; +} +} // namespace internal +} // namespace simdjson +#endif + +#if SIMDJSON_IMPLEMENTATION_PPC64 +/* including simdjson/ppc64/implementation.h: #include */ +/* begin file simdjson/ppc64/implementation.h */ +#ifndef SIMDJSON_PPC64_IMPLEMENTATION_H +#define SIMDJSON_PPC64_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +/** + * Implementation for ALTIVEC (PPC64). + */ +namespace ppc64 { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() + : simdjson::implementation("ppc64", "PPC64 ALTIVEC", + internal::instruction_set::ALTIVEC) {} + + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, size_t max_length, + std::unique_ptr &dst) + const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, + uint8_t *dst, + size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, + size_t len) const noexcept final; +}; + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_IMPLEMENTATION_H +/* end file simdjson/ppc64/implementation.h */ +namespace simdjson { +namespace internal { +static const ppc64::implementation* get_ppc64_singleton() { + static const ppc64::implementation ppc64_singleton{}; + return &ppc64_singleton; +} +} // namespace internal +} // namespace simdjson +#endif // SIMDJSON_IMPLEMENTATION_PPC64 + +#if SIMDJSON_IMPLEMENTATION_WESTMERE +/* including simdjson/westmere/implementation.h: #include */ +/* begin file simdjson/westmere/implementation.h */ +#ifndef SIMDJSON_WESTMERE_IMPLEMENTATION_H +#define SIMDJSON_WESTMERE_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_WESTMERE +namespace simdjson { +namespace westmere { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation("westmere", "Intel/AMD SSE4.2", internal::instruction_set::SSE42 | internal::instruction_set::PCLMULQDQ) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_IMPLEMENTATION_H +/* end file simdjson/westmere/implementation.h */ +namespace simdjson { +namespace internal { +static const simdjson::westmere::implementation* get_westmere_singleton() { + static const simdjson::westmere::implementation westmere_singleton{}; + return &westmere_singleton; +} +} // namespace internal +} // namespace simdjson +#endif // SIMDJSON_IMPLEMENTATION_WESTMERE + +/* undefining SIMDJSON_CONDITIONAL_INCLUDE */ +#undef SIMDJSON_CONDITIONAL_INCLUDE + +namespace simdjson { +namespace internal { + +// Static array of known implementations. We're hoping these get baked into the executable +// without requiring a static initializer. + +/** + * @private Detects best supported implementation on first use, and sets it + */ +class detect_best_supported_implementation_on_first_use final : public implementation { +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(); } + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final { + return set_best()->create_dom_parser_implementation(capacity, max_length, dst); + } + simdjson_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); + } + simdjson_warn_unused bool validate_utf8(const char * buf, size_t len) const noexcept final override { + return set_best()->validate_utf8(buf, len); + } + simdjson_inline detect_best_supported_implementation_on_first_use() noexcept : implementation("best_supported_detector", "Detects the best supported implementation and sets it", 0) {} +private: + const implementation *set_best() const noexcept; +}; + +static const std::initializer_list& get_available_implementation_pointers() { + static const std::initializer_list available_implementation_pointers { +#if SIMDJSON_IMPLEMENTATION_ICELAKE + get_icelake_singleton(), +#endif +#if SIMDJSON_IMPLEMENTATION_HASWELL + get_haswell_singleton(), +#endif +#if SIMDJSON_IMPLEMENTATION_WESTMERE + get_westmere_singleton(), +#endif +#if SIMDJSON_IMPLEMENTATION_ARM64 + get_arm64_singleton(), +#endif +#if SIMDJSON_IMPLEMENTATION_PPC64 + get_ppc64_singleton(), +#endif +#if SIMDJSON_IMPLEMENTATION_FALLBACK + get_fallback_singleton(), +#endif + }; // available_implementation_pointers + return available_implementation_pointers; +} + +// So we can return UNSUPPORTED_ARCHITECTURE from the parser when there is no support +class unsupported_implementation final : public implementation { +public: + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t, + size_t, + std::unique_ptr& + ) const noexcept final { + return UNSUPPORTED_ARCHITECTURE; + } + simdjson_warn_unused error_code minify(const uint8_t *, size_t, uint8_t *, size_t &) const noexcept final override { + return UNSUPPORTED_ARCHITECTURE; + } + simdjson_warn_unused bool validate_utf8(const char *, size_t) const noexcept final override { + return false; // Just refuse to validate. Given that we have a fallback implementation + // it seems unlikely that unsupported_implementation will ever be used. If it is used, + // then it will flag all strings as invalid. The alternative is to return an error_code + // from which the user has to figure out whether the string is valid UTF-8... which seems + // like a lot of work just to handle the very unlikely case that we have an unsupported + // implementation. And, when it does happen (that we have an unsupported implementation), + // what are the chances that the programmer has a fallback? Given that *we* provide the + // fallback, it implies that the programmer would need a fallback for our fallback. + } + unsupported_implementation() : implementation("unsupported", "Unsupported CPU (no detected SIMD instructions)", 0) {} +}; + +const unsupported_implementation* get_unsupported_singleton() { + static const unsupported_implementation unsupported_singleton{}; + return &unsupported_singleton; +} + +size_t available_implementation_list::size() const noexcept { + return internal::get_available_implementation_pointers().size(); +} +const implementation * const *available_implementation_list::begin() const noexcept { + return internal::get_available_implementation_pointers().begin(); +} +const implementation * const *available_implementation_list::end() const noexcept { + return internal::get_available_implementation_pointers().end(); +} +const implementation *available_implementation_list::detect_best_supported() const noexcept { + // They are prelisted in priority order, so we just go down the list + uint32_t supported_instruction_sets = internal::detect_supported_architectures(); + for (const implementation *impl : internal::get_available_implementation_pointers()) { + uint32_t required_instruction_sets = impl->required_instruction_sets(); + if ((supported_instruction_sets & required_instruction_sets) == required_instruction_sets) { return impl; } + } + return get_unsupported_singleton(); // this should never happen? +} + +const implementation *detect_best_supported_implementation_on_first_use::set_best() const noexcept { + SIMDJSON_PUSH_DISABLE_WARNINGS + SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe + char *force_implementation_name = getenv("SIMDJSON_FORCE_IMPLEMENTATION"); + SIMDJSON_POP_DISABLE_WARNINGS + + if (force_implementation_name) { + auto force_implementation = get_available_implementations()[force_implementation_name]; + if (force_implementation) { + return get_active_implementation() = force_implementation; + } else { + // Note: abort() and stderr usage within the library is forbidden. + return get_active_implementation() = get_unsupported_singleton(); + } + } + return get_active_implementation() = get_available_implementations().detect_best_supported(); +} + +} // namespace internal + +SIMDJSON_DLLIMPORTEXPORT const internal::available_implementation_list& get_available_implementations() { + static const internal::available_implementation_list available_implementations{}; + return available_implementations; +} + +SIMDJSON_DLLIMPORTEXPORT internal::atomic_ptr& get_active_implementation() { + static const internal::detect_best_supported_implementation_on_first_use detect_best_supported_implementation_on_first_use_singleton; + static internal::atomic_ptr active_implementation{&detect_best_supported_implementation_on_first_use_singleton}; + return active_implementation; +} + +simdjson_warn_unused error_code minify(const char *buf, size_t len, char *dst, size_t &dst_len) noexcept { + return get_active_implementation()->minify(reinterpret_cast(buf), len, reinterpret_cast(dst), dst_len); +} +simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) noexcept { + return get_active_implementation()->validate_utf8(buf, len); +} +const implementation * builtin_implementation() { + static const implementation * builtin_impl = get_available_implementations()[SIMDJSON_STRINGIFY(SIMDJSON_BUILTIN_IMPLEMENTATION)]; + assert(builtin_impl); + return builtin_impl; +} + +} // namespace simdjson + +#endif // SIMDJSON_SRC_IMPLEMENTATION_CPP +/* end file implementation.cpp */ + +/* defining SIMDJSON_CONDITIONAL_INCLUDE */ +#define SIMDJSON_CONDITIONAL_INCLUDE + +#if SIMDJSON_IMPLEMENTATION_ARM64 +/* including arm64.cpp: #include */ +/* begin file arm64.cpp */ +#ifndef SIMDJSON_SRC_ARM64_CPP +#define SIMDJSON_SRC_ARM64_CPP + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +/* including simdjson/arm64.h: #include */ +/* begin file simdjson/arm64.h */ +#ifndef SIMDJSON_ARM64_H +#define SIMDJSON_ARM64_H + +/* including simdjson/arm64/begin.h: #include "simdjson/arm64/begin.h" */ +/* begin file simdjson/arm64/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "arm64" */ +#define SIMDJSON_IMPLEMENTATION arm64 +/* including simdjson/arm64/base.h: #include "simdjson/arm64/base.h" */ +/* begin file simdjson/arm64/base.h */ +#ifndef SIMDJSON_ARM64_BASE_H +#define SIMDJSON_ARM64_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Implementation for NEON (ARMv8). + */ +namespace arm64 { + +class implementation; + +namespace { +namespace simd { +template struct simd8; +template struct simd8x64; +} // namespace simd +} // unnamed namespace + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_BASE_H +/* end file simdjson/arm64/base.h */ +/* including simdjson/arm64/intrinsics.h: #include "simdjson/arm64/intrinsics.h" */ +/* begin file simdjson/arm64/intrinsics.h */ +#ifndef SIMDJSON_ARM64_INTRINSICS_H +#define SIMDJSON_ARM64_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This should be the correct header whether +// you use visual studio or other compilers. +#include + +static_assert(sizeof(uint8x16_t) <= simdjson::SIMDJSON_PADDING, "insufficient padding for arm64"); + +#endif // SIMDJSON_ARM64_INTRINSICS_H +/* end file simdjson/arm64/intrinsics.h */ +/* including simdjson/arm64/bitmanipulation.h: #include "simdjson/arm64/bitmanipulation.h" */ +/* begin file simdjson/arm64/bitmanipulation.h */ +#ifndef SIMDJSON_ARM64_BITMANIPULATION_H +#define SIMDJSON_ARM64_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num-1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int count_ones(uint64_t input_num) { + return vaddv_u8(vcnt_u8(vcreate_u8(input_num))); +} + + +#if defined(__GNUC__) // catches clang and gcc +/** + * ARM has a fast 64-bit "bit reversal function" that is handy. However, + * it is not generally available as an intrinsic function under Visual + * Studio (though this might be changing). Even under clang/gcc, we + * apparently need to invoke inline assembly. + */ +/* + * We use SIMDJSON_PREFER_REVERSE_BITS as a hint that algorithms that + * work well with bit reversal may use it. + */ +#define SIMDJSON_PREFER_REVERSE_BITS 1 + +/* reverse the bits */ +simdjson_inline uint64_t reverse_bits(uint64_t input_num) { + uint64_t rev_bits; + __asm("rbit %0, %1" : "=r"(rev_bits) : "r"(input_num)); + return rev_bits; +} + +/** + * Flips bit at index 63 - lz. Thus if you have 'leading_zeroes' leading zeroes, + * then this will set to zero the leading bit. It is possible for leading_zeroes to be + * greating or equal to 63 in which case we trigger undefined behavior, but the output + * of such undefined behavior is never used. + **/ +SIMDJSON_NO_SANITIZE_UNDEFINED +simdjson_inline uint64_t zero_leading_bit(uint64_t rev_bits, int leading_zeroes) { + return rev_bits ^ (uint64_t(0x8000000000000000) >> leading_zeroes); +} + +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + *result = value1 + value2; + return *result < value1; +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_BITMANIPULATION_H +/* end file simdjson/arm64/bitmanipulation.h */ +/* including simdjson/arm64/bitmask.h: #include "simdjson/arm64/bitmask.h" */ +/* begin file simdjson/arm64/bitmask.h */ +#ifndef SIMDJSON_ARM64_BITMASK_H +#define SIMDJSON_ARM64_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(uint64_t bitmask) { + ///////////// + // We could do this with PMULL, but it is apparently slow. + // + //#ifdef __ARM_FEATURE_CRYPTO // some ARM processors lack this extension + //return vmull_p64(-1ULL, bitmask); + //#else + // Analysis by @sebpop: + // When diffing the assembly for src/stage1_find_marks.cpp I see that the eors are all spread out + // in between other vector code, so effectively the extra cycles of the sequence do not matter + // because the GPR units are idle otherwise and the critical path is on the FP side. + // Also the PMULL requires two extra fmovs: GPR->FP (3 cycles in N1, 5 cycles in A72 ) + // and FP->GPR (2 cycles on N1 and 5 cycles on A72.) + /////////// + bitmask ^= bitmask << 1; + bitmask ^= bitmask << 2; + bitmask ^= bitmask << 4; + bitmask ^= bitmask << 8; + bitmask ^= bitmask << 16; + bitmask ^= bitmask << 32; + return bitmask; +} + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif +/* end file simdjson/arm64/bitmask.h */ +/* including simdjson/arm64/numberparsing_defs.h: #include "simdjson/arm64/numberparsing_defs.h" */ +/* begin file simdjson/arm64/numberparsing_defs.h */ +#ifndef SIMDJSON_ARM64_NUMBERPARSING_DEFS_H +#define SIMDJSON_ARM64_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +#if _M_ARM64 +// __umulh requires intrin.h +#include +#endif // _M_ARM64 + +namespace simdjson { +namespace arm64 { +namespace numberparsing { + +// we don't have SSE, so let us use a scalar function +// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + uint64_t val; + std::memcpy(&val, chars, sizeof(uint64_t)); + val = (val & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8; + val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16; + return uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32); +} + +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace arm64 +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_ARM64_NUMBERPARSING_DEFS_H +/* end file simdjson/arm64/numberparsing_defs.h */ +/* including simdjson/arm64/simd.h: #include "simdjson/arm64/simd.h" */ +/* begin file simdjson/arm64/simd.h */ +#ifndef SIMDJSON_ARM64_SIMD_H +#define SIMDJSON_ARM64_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace simd { + +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO +namespace { +// Start of private section with Visual Studio workaround + + +#ifndef simdjson_make_uint8x16_t +#define simdjson_make_uint8x16_t(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \ + x13, x14, x15, x16) \ + ([=]() { \ + uint8_t array[16] = {x1, x2, x3, x4, x5, x6, x7, x8, \ + x9, x10, x11, x12, x13, x14, x15, x16}; \ + return vld1q_u8(array); \ + }()) +#endif +#ifndef simdjson_make_int8x16_t +#define simdjson_make_int8x16_t(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \ + x13, x14, x15, x16) \ + ([=]() { \ + int8_t array[16] = {x1, x2, x3, x4, x5, x6, x7, x8, \ + x9, x10, x11, x12, x13, x14, x15, x16}; \ + return vld1q_s8(array); \ + }()) +#endif + +#ifndef simdjson_make_uint8x8_t +#define simdjson_make_uint8x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + uint8_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1_u8(array); \ + }()) +#endif +#ifndef simdjson_make_int8x8_t +#define simdjson_make_int8x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + int8_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1_s8(array); \ + }()) +#endif +#ifndef simdjson_make_uint16x8_t +#define simdjson_make_uint16x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + uint16_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1q_u16(array); \ + }()) +#endif +#ifndef simdjson_make_int16x8_t +#define simdjson_make_int16x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + int16_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1q_s16(array); \ + }()) +#endif + +// End of private section with Visual Studio workaround +} // namespace +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO + + + template + struct simd8; + + // + // Base class of simd8 and simd8, both of which use uint8x16_t internally. + // + template> + struct base_u8 { + uint8x16_t value; + static const int SIZE = sizeof(value); + + // Conversion from/to SIMD register + simdjson_inline base_u8(const uint8x16_t _value) : value(_value) {} + simdjson_inline operator const uint8x16_t&() const { return this->value; } + simdjson_inline operator uint8x16_t&() { return this->value; } + + // Bit operations + simdjson_inline simd8 operator|(const simd8 other) const { return vorrq_u8(*this, other); } + simdjson_inline simd8 operator&(const simd8 other) const { return vandq_u8(*this, other); } + simdjson_inline simd8 operator^(const simd8 other) const { return veorq_u8(*this, other); } + simdjson_inline simd8 bit_andnot(const simd8 other) const { return vbicq_u8(*this, other); } + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + simdjson_inline simd8& operator|=(const simd8 other) { auto this_cast = static_cast*>(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline simd8& operator&=(const simd8 other) { auto this_cast = static_cast*>(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline simd8& operator^=(const simd8 other) { auto this_cast = static_cast*>(this); *this_cast = *this_cast ^ other; return *this_cast; } + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return vceqq_u8(lhs, rhs); } + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return vextq_u8(prev_chunk, *this, 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base_u8 { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + static simdjson_inline simd8 splat(bool _value) { return vmovq_n_u8(uint8_t(-(!!_value))); } + + simdjson_inline simd8(const uint8x16_t _value) : base_u8(_value) {} + // False constructor + simdjson_inline simd8() : simd8(vdupq_n_u8(0)) {} + // Splat constructor + simdjson_inline simd8(bool _value) : simd8(splat(_value)) {} + + // We return uint32_t instead of uint16_t because that seems to be more efficient for most + // purposes (cutting it down to uint16_t costs performance in some compilers). + simdjson_inline uint32_t to_bitmask() const { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + const uint8x16_t bit_mask = simdjson_make_uint8x16_t(0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80); +#else + const uint8x16_t bit_mask = {0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80}; +#endif + auto minput = *this & bit_mask; + uint8x16_t tmp = vpaddq_u8(minput, minput); + tmp = vpaddq_u8(tmp, tmp); + tmp = vpaddq_u8(tmp, tmp); + return vgetq_lane_u16(vreinterpretq_u16_u8(tmp), 0); + } + simdjson_inline bool any() const { return vmaxvq_u8(*this) != 0; } + }; + + // Unsigned bytes + template<> + struct simd8: base_u8 { + static simdjson_inline uint8x16_t splat(uint8_t _value) { return vmovq_n_u8(_value); } + static simdjson_inline uint8x16_t zero() { return vdupq_n_u8(0); } + static simdjson_inline uint8x16_t load(const uint8_t* values) { return vld1q_u8(values); } + + simdjson_inline simd8(const uint8x16_t _value) : base_u8(_value) {} + // Zero constructor + simdjson_inline simd8() : simd8(zero()) {} + // Array constructor + simdjson_inline simd8(const uint8_t values[16]) : simd8(load(values)) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Member-by-member initialization +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(simdjson_make_uint8x16_t( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} +#else + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(uint8x16_t{ + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + }) {} +#endif + + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Store to array + simdjson_inline void store(uint8_t dst[16]) const { return vst1q_u8(dst, *this); } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return vqaddq_u8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return vqsubq_u8(*this, other); } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return vaddq_u8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return vsubq_u8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *this; } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *this; } + + // Order-specific operations + simdjson_inline uint8_t max_val() const { return vmaxvq_u8(*this); } + simdjson_inline uint8_t min_val() const { return vminvq_u8(*this); } + simdjson_inline simd8 max_val(const simd8 other) const { return vmaxq_u8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return vminq_u8(*this, other); } + simdjson_inline simd8 operator<=(const simd8 other) const { return vcleq_u8(*this, other); } + simdjson_inline simd8 operator>=(const simd8 other) const { return vcgeq_u8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return vcltq_u8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return vcgtq_u8(*this, other); } + // Same as >, but instead of guaranteeing all 1's == true, false = 0 and true = nonzero. For ARM, returns all 1's. + simdjson_inline simd8 gt_bits(const simd8 other) const { return simd8(*this > other); } + // Same as <, but instead of guaranteeing all 1's == true, false = 0 and true = nonzero. For ARM, returns all 1's. + simdjson_inline simd8 lt_bits(const simd8 other) const { return simd8(*this < other); } + + // Bit-specific operations + simdjson_inline simd8 any_bits_set(simd8 bits) const { return vtstq_u8(*this, bits); } + simdjson_inline bool any_bits_set_anywhere() const { return this->max_val() != 0; } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return (*this & bits).any_bits_set_anywhere(); } + template + simdjson_inline simd8 shr() const { return vshrq_n_u8(*this, N); } + template + simdjson_inline simd8 shl() const { return vshlq_n_u8(*this, N); } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return lookup_table.apply_lookup_16_to(*this); + } + + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 16 - count_ones(mask) bytes of the result are significant but 16 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint16_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + uint64x2_t shufmask64 = {thintable_epi8[mask1], thintable_epi8[mask2]}; + uint8x16_t shufmask = vreinterpretq_u8_u64(shufmask64); + // we increment by 0x08 the second half of the mask +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + uint8x16_t inc = simdjson_make_uint8x16_t(0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08); +#else + uint8x16_t inc = {0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; +#endif + shufmask = vaddq_u8(shufmask, inc); + // this is the version "nearly pruned" + uint8x16_t pruned = vqtbl1q_u8(*this, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + uint8x16_t compactmask = vld1q_u8(reinterpret_cast(pshufb_combine_table + pop1 * 8)); + uint8x16_t answer = vqtbl1q_u8(pruned, compactmask); + vst1q_u8(reinterpret_cast(output), answer); + } + + // Copies all bytes corresponding to a 0 in the low half of the mask (interpreted as a + // bitset) to output1, then those corresponding to a 0 in the high half to output2. + template + simdjson_inline void compress_halves(uint16_t mask, L *output1, L *output2) const { + using internal::thintable_epi8; + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + uint8x8_t compactmask1 = vcreate_u8(thintable_epi8[mask1]); + uint8x8_t compactmask2 = vcreate_u8(thintable_epi8[mask2]); + // we increment by 0x08 the second half of the mask +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + uint8x8_t inc = simdjson_make_uint8x8_t(0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08); +#else + uint8x8_t inc = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; +#endif + compactmask2 = vadd_u8(compactmask2, inc); + // store each result (with the second store possibly overlapping the first) + vst1_u8((uint8_t*)output1, vqtbl1_u8(*this, compactmask1)); + vst1_u8((uint8_t*)output2, vqtbl1_u8(*this, compactmask2)); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + + template + simdjson_inline simd8 apply_lookup_16_to(const simd8 original) { + return vqtbl1q_u8(*this, simd8(original)); + } + }; + + // Signed bytes + template<> + struct simd8 { + int8x16_t value; + + static simdjson_inline simd8 splat(int8_t _value) { return vmovq_n_s8(_value); } + static simdjson_inline simd8 zero() { return vdupq_n_s8(0); } + static simdjson_inline simd8 load(const int8_t values[16]) { return vld1q_s8(values); } + + // Conversion from/to SIMD register + simdjson_inline simd8(const int8x16_t _value) : value{_value} {} + simdjson_inline operator const int8x16_t&() const { return this->value; } + simdjson_inline operator int8x16_t&() { return this->value; } + + // Zero constructor + simdjson_inline simd8() : simd8(zero()) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {} + // Member-by-member initialization +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(simdjson_make_int8x16_t( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} +#else + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(int8x16_t{ + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + }) {} +#endif + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Store to array + simdjson_inline void store(int8_t dst[16]) const { return vst1q_s8(dst, *this); } + + // Explicit conversion to/from unsigned + // + // Under Visual Studio/ARM64 uint8x16_t and int8x16_t are apparently the same type. + // In theory, we could check this occurrence with std::same_as and std::enabled_if but it is C++14 + // and relatively ugly and hard to read. +#ifndef SIMDJSON_REGULAR_VISUAL_STUDIO + simdjson_inline explicit simd8(const uint8x16_t other): simd8(vreinterpretq_s8_u8(other)) {} +#endif + simdjson_inline explicit operator simd8() const { return vreinterpretq_u8_s8(this->value); } + + // Math + simdjson_inline simd8 operator+(const simd8 other) const { return vaddq_s8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return vsubq_s8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *this; } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *this; } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return vmaxq_s8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return vminq_s8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return vcgtq_s8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return vcltq_s8(*this, other); } + simdjson_inline simd8 operator==(const simd8 other) const { return vceqq_s8(*this, other); } + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return vextq_s8(prev_chunk, *this, 16 - N); + } + + // Perform a lookup assuming no value is larger than 16 + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return lookup_table.apply_lookup_16_to(*this); + } + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + + template + simdjson_inline simd8 apply_lookup_16_to(const simd8 original) { + return vqtbl1q_s8(*this, simd8(original)); + } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, "ARM kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, const simd8 chunk2, const simd8 chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+16), simd8::load(ptr+32), simd8::load(ptr+48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + this->chunks[2].store(ptr+sizeof(simd8)*2); + this->chunks[3].store(ptr+sizeof(simd8)*3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | (this->chunks[2] | this->chunks[3]); + } + + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + uint64_t popcounts = vget_lane_u64(vreinterpret_u64_u8(vcnt_u8(vcreate_u8(~mask))), 0); + // compute the prefix sum of the popcounts of each byte + uint64_t offsets = popcounts * 0x0101010101010101; + this->chunks[0].compress_halves(uint16_t(mask), output, &output[popcounts & 0xFF]); + this->chunks[1].compress_halves(uint16_t(mask >> 16), &output[(offsets >> 8) & 0xFF], &output[(offsets >> 16) & 0xFF]); + this->chunks[2].compress_halves(uint16_t(mask >> 32), &output[(offsets >> 24) & 0xFF], &output[(offsets >> 32) & 0xFF]); + this->chunks[3].compress_halves(uint16_t(mask >> 48), &output[(offsets >> 40) & 0xFF], &output[(offsets >> 48) & 0xFF]); + return offsets >> 56; + } + + simdjson_inline uint64_t to_bitmask() const { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + const uint8x16_t bit_mask = simdjson_make_uint8x16_t( + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 + ); +#else + const uint8x16_t bit_mask = { + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 + }; +#endif + // Add each of the elements next to each other, successively, to stuff each 8 byte mask into one. + uint8x16_t sum0 = vpaddq_u8(this->chunks[0] & bit_mask, this->chunks[1] & bit_mask); + uint8x16_t sum1 = vpaddq_u8(this->chunks[2] & bit_mask, this->chunks[3] & bit_mask); + sum0 = vpaddq_u8(sum0, sum1); + sum0 = vpaddq_u8(sum0, sum0); + return vgetq_lane_u64(vreinterpretq_u64_u8(sum0), 0); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask, + this->chunks[2] == mask, + this->chunks[3] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask, + this->chunks[2] <= mask, + this->chunks[3] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_SIMD_H +/* end file simdjson/arm64/simd.h */ +/* including simdjson/arm64/stringparsing_defs.h: #include "simdjson/arm64/stringparsing_defs.h" */ +/* begin file simdjson/arm64/stringparsing_defs.h */ +#ifndef SIMDJSON_ARM64_STRINGPARSING_DEFS_H +#define SIMDJSON_ARM64_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/simd.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return bs_bits != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 31 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v0(src); + simd8 v1(src + sizeof(v0)); + v0.store(dst); + v1.store(dst + sizeof(v0)); + + // Getting a 64-bit bitmask is much cheaper than multiple 16-bit bitmasks on ARM; therefore, we + // smash them together into a 64-byte mask and get the bitmask from there. + uint64_t bs_and_quote = simd8x64(v0 == '\\', v1 == '\\', v0 == '"', v1 == '"').to_bitmask(); + return { + uint32_t(bs_and_quote), // bs_bits + uint32_t(bs_and_quote >> 32) // quote_bits + }; +} + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_STRINGPARSING_DEFS_H +/* end file simdjson/arm64/stringparsing_defs.h */ + +#define SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT 1 +/* end file simdjson/arm64/begin.h */ +/* including simdjson/generic/amalgamated.h for arm64: #include "simdjson/generic/amalgamated.h" */ +/* begin file simdjson/generic/amalgamated.h for arm64 */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_DEPENDENCIES_H) +#error simdjson/generic/dependencies.h must be included before simdjson/generic/amalgamated.h! +#endif + +/* including simdjson/generic/base.h for arm64: #include "simdjson/generic/base.h" */ +/* begin file simdjson/generic/base.h for arm64 */ +#ifndef SIMDJSON_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): // If we haven't got an implementation yet, we're in the editor, editing a generic file! Just */ +/* amalgamation skipped (editor-only): // use the most advanced one we can so the most possible stuff can be tested. */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation_detection.h" */ +/* amalgamation skipped (editor-only): #if SIMDJSON_IMPLEMENTATION_ICELAKE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_HASWELL */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_WESTMERE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_ARM64 */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_PPC64 */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_FALLBACK */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/begin.h" */ +/* amalgamation skipped (editor-only): #else */ +/* amalgamation skipped (editor-only): #error "All possible implementations (including fallback) have been disabled! simdjson will not run." */ +/* amalgamation skipped (editor-only): #endif */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { + +struct open_container; +class dom_parser_implementation; + +/** + * The type of a JSON number + */ +enum class number_type { + floating_point_number=1, /// a binary64 number + signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + unsigned_integer /// a positive integer larger or equal to 1<<63 +}; + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_BASE_H +/* end file simdjson/generic/base.h for arm64 */ +/* including simdjson/generic/jsoncharutils.h for arm64: #include "simdjson/generic/jsoncharutils.h" */ +/* begin file simdjson/generic/jsoncharutils.h for arm64 */ +#ifndef SIMDJSON_GENERIC_JSONCHARUTILS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_JSONCHARUTILS_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/jsoncharutils_tables.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace jsoncharutils { + +// return non-zero if not a structural or whitespace char +// zero otherwise +simdjson_inline uint32_t is_not_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace_negated[c]; +} + +simdjson_inline uint32_t is_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace[c]; +} + +// returns a value with the high 16 bits set if not valid +// otherwise returns the conversion of the 4 hex digits at src into the bottom +// 16 bits of the 32-bit return register +// +// see +// https://lemire.me/blog/2019/04/17/parsing-short-hexadecimal-strings-efficiently/ +static inline uint32_t hex_to_u32_nocheck( + const uint8_t *src) { // strictly speaking, static inline is a C-ism + uint32_t v1 = internal::digit_to_val32[630 + src[0]]; + uint32_t v2 = internal::digit_to_val32[420 + src[1]]; + uint32_t v3 = internal::digit_to_val32[210 + src[2]]; + uint32_t v4 = internal::digit_to_val32[0 + src[3]]; + return v1 | v2 | v3 | v4; +} + +// given a code point cp, writes to c +// the utf-8 code, outputting the length in +// bytes, if the length is zero, the code point +// is invalid +// +// This can possibly be made faster using pdep +// and clz and table lookups, but JSON documents +// have few escaped code points, and the following +// function looks cheap. +// +// Note: we assume that surrogates are treated separately +// +simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) { + if (cp <= 0x7F) { + c[0] = uint8_t(cp); + return 1; // ascii + } + if (cp <= 0x7FF) { + c[0] = uint8_t((cp >> 6) + 192); + c[1] = uint8_t((cp & 63) + 128); + return 2; // universal plane + // Surrogates are treated elsewhere... + //} //else if (0xd800 <= cp && cp <= 0xdfff) { + // return 0; // surrogates // could put assert here + } else if (cp <= 0xFFFF) { + c[0] = uint8_t((cp >> 12) + 224); + c[1] = uint8_t(((cp >> 6) & 63) + 128); + c[2] = uint8_t((cp & 63) + 128); + return 3; + } else if (cp <= 0x10FFFF) { // if you know you have a valid code point, this + // is not needed + c[0] = uint8_t((cp >> 18) + 240); + c[1] = uint8_t(((cp >> 12) & 63) + 128); + c[2] = uint8_t(((cp >> 6) & 63) + 128); + c[3] = uint8_t((cp & 63) + 128); + return 4; + } + // will return 0 when the code point was too large. + return 0; // bad r +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +} // namespace jsoncharutils +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_JSONCHARUTILS_H +/* end file simdjson/generic/jsoncharutils.h for arm64 */ +/* including simdjson/generic/atomparsing.h for arm64: #include "simdjson/generic/atomparsing.h" */ +/* begin file simdjson/generic/atomparsing.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ATOMPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ATOMPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace arm64 { +namespace { +/// @private +namespace atomparsing { + +// The string_to_uint32 is exclusively used to map literal strings to 32-bit values. +// We use memcpy instead of a pointer cast to avoid undefined behaviors since we cannot +// be certain that the character pointer will be properly aligned. +// You might think that using memcpy makes this function expensive, but you'd be wrong. +// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false"); +// to the compile-time constant 1936482662. +simdjson_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; } + + +// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive. +// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about. +simdjson_warn_unused +simdjson_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) { + uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++) + static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes"); + std::memcpy(&srcval, src, sizeof(uint32_t)); + return srcval ^ string_to_uint32(atom); +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src) { + return (str4ncmp(src, "true") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_true_atom(src); } + else if (len == 4) { return !str4ncmp(src, "true"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src) { + return (str4ncmp(src+1, "alse") | jsoncharutils::is_not_structural_or_whitespace(src[5])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src, size_t len) { + if (len > 5) { return is_valid_false_atom(src); } + else if (len == 5) { return !str4ncmp(src+1, "alse"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src) { + return (str4ncmp(src, "null") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_null_atom(src); } + else if (len == 4) { return !str4ncmp(src, "null"); } + else { return false; } +} + +} // namespace atomparsing +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ATOMPARSING_H +/* end file simdjson/generic/atomparsing.h for arm64 */ +/* including simdjson/generic/dom_parser_implementation.h for arm64: #include "simdjson/generic/dom_parser_implementation.h" */ +/* begin file simdjson/generic/dom_parser_implementation.h for arm64 */ +#ifndef SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { + +// expectation: sizeof(open_container) = 64/8. +struct open_container { + uint32_t tape_index; // where, on the tape, does the scope ([,{) begins + uint32_t count; // how many elements in the scope +}; // struct open_container + +static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits"); + +class dom_parser_implementation final : public internal::dom_parser_implementation { +public: + /** Tape location of each open { or [ */ + std::unique_ptr open_containers{}; + /** Whether each open container is a [ or { */ + std::unique_ptr is_array{}; + /** Buffer passed to stage 1 */ + const uint8_t *buf{}; + /** Length passed to stage 1 */ + size_t len{0}; + /** Document passed to stage 2 */ + dom::document *doc{}; + + inline dom_parser_implementation() noexcept; + inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; + inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; + dom_parser_implementation(const dom_parser_implementation &) = delete; + dom_parser_implementation &operator=(const dom_parser_implementation &) = delete; + + simdjson_warn_unused error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage1(const uint8_t *buf, size_t len, stage1_mode partial) noexcept final; + simdjson_warn_unused error_code stage2(dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage2_next(dom::document &doc) noexcept final; + simdjson_warn_unused uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept final; + simdjson_warn_unused uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept final; + inline simdjson_warn_unused error_code set_capacity(size_t capacity) noexcept final; + inline simdjson_warn_unused error_code set_max_depth(size_t max_depth) noexcept final; +private: + simdjson_inline simdjson_warn_unused error_code set_capacity_stage1(size_t capacity); + +}; + +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { +namespace arm64 { + +inline dom_parser_implementation::dom_parser_implementation() noexcept = default; +inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; +inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; + +// Leaving these here so they can be inlined if so desired +inline simdjson_warn_unused error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept { + if(capacity > SIMDJSON_MAXSIZE_BYTES) { return CAPACITY; } + // Stage 1 index output + size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7; + structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] ); + if (!structural_indexes) { _capacity = 0; return MEMALLOC; } + structural_indexes[0] = 0; + n_structural_indexes = 0; + + _capacity = capacity; + return SUCCESS; +} + +inline simdjson_warn_unused error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept { + // Stage 2 stacks + open_containers.reset(new (std::nothrow) open_container[max_depth]); + is_array.reset(new (std::nothrow) bool[max_depth]); + if (!is_array || !open_containers) { _max_depth = 0; return MEMALLOC; } + + _max_depth = max_depth; + return SUCCESS; +} + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file simdjson/generic/dom_parser_implementation.h for arm64 */ +/* including simdjson/generic/implementation_simdjson_result_base.h for arm64: #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base.h for arm64 */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { + +// This is a near copy of include/error.h's implementation_simdjson_result_base, except it doesn't use std::pair +// so we can avoid inlining errors +// TODO reconcile these! +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + * + * This is a base class for implementations that want to add functions to the result type for + * chaining. + * + * Override like: + * + * struct simdjson_result : public internal::implementation_simdjson_result_base { + * simdjson_result() noexcept : internal::implementation_simdjson_result_base() {} + * simdjson_result(error_code error) noexcept : internal::implementation_simdjson_result_base(error) {} + * simdjson_result(T &&value) noexcept : internal::implementation_simdjson_result_base(std::forward(value)) {} + * simdjson_result(T &&value, error_code error) noexcept : internal::implementation_simdjson_result_base(value, error) {} + * // Your extra methods here + * } + * + * Then any method returning simdjson_result will be chainable with your methods. + */ +template +struct implementation_simdjson_result_base { + + /** + * Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline implementation_simdjson_result_base() noexcept = default; + + /** + * Create a new error result. + */ + simdjson_inline implementation_simdjson_result_base(error_code error) noexcept; + + /** + * Create a new successful result. + */ + simdjson_inline implementation_simdjson_result_base(T &&value) noexcept; + + /** + * Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline implementation_simdjson_result_base(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); + + +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T& value_unsafe() & noexcept; + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; +protected: + /** users should never directly access first and second. **/ + T first{}; /** Users should never directly access 'first'. **/ + error_code second{UNINITIALIZED}; /** Users should never directly access 'second'. **/ +}; // struct implementation_simdjson_result_base + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H +/* end file simdjson/generic/implementation_simdjson_result_base.h for arm64 */ +/* including simdjson/generic/numberparsing.h for arm64: #include "simdjson/generic/numberparsing.h" */ +/* begin file simdjson/generic/numberparsing.h for arm64 */ +#ifndef SIMDJSON_GENERIC_NUMBERPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_NUMBERPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include +#include + +namespace simdjson { +namespace arm64 { +namespace numberparsing { + +#ifdef JSON_TEST_NUMBERS +#define INVALID_NUMBER(SRC) (found_invalid_number((SRC)), NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (found_integer((VALUE), (SRC)), (WRITER).append_s64((VALUE))) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (found_unsigned_integer((VALUE), (SRC)), (WRITER).append_u64((VALUE))) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (found_float((VALUE), (SRC)), (WRITER).append_double((VALUE))) +#else +#define INVALID_NUMBER(SRC) (NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (WRITER).append_s64((VALUE)) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (WRITER).append_u64((VALUE)) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (WRITER).append_double((VALUE)) +#endif + +namespace { + +// Convert a mantissa, an exponent and a sign bit into an ieee64 double. +// The real_exponent needs to be in [0, 2046] (technically real_exponent = 2047 would be acceptable). +// The mantissa should be in [0,1<<53). The bit at index (1ULL << 52) while be zeroed. +simdjson_inline double to_double(uint64_t mantissa, uint64_t real_exponent, bool negative) { + double d; + mantissa &= ~(1ULL << 52); + mantissa |= real_exponent << 52; + mantissa |= ((static_cast(negative)) << 63); + std::memcpy(&d, &mantissa, sizeof(d)); + return d; +} + +// Attempts to compute i * 10^(power) exactly; and if "negative" is +// true, negate the result. +// This function will only work in some cases, when it does not work, success is +// set to false. This should work *most of the time* (like 99% of the time). +// We assume that power is in the [smallest_power, +// largest_power] interval: the caller is responsible for this check. +simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative, double &d) { + // we start with a fast path + // It was described in + // Clinger WD. How to read floating point numbers accurately. + // ACM SIGPLAN Notices. 1990 +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + // We cannot be certain that x/y is rounded to nearest. + if (0 <= power && power <= 22 && i <= 9007199254740991) +#else + if (-22 <= power && power <= 22 && i <= 9007199254740991) +#endif + { + // convert the integer into a double. This is lossless since + // 0 <= i <= 2^53 - 1. + d = double(i); + // + // The general idea is as follows. + // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then + // 1) Both s and p can be represented exactly as 64-bit floating-point + // values + // (binary64). + // 2) Because s and p can be represented exactly as floating-point values, + // then s * p + // and s / p will produce correctly rounded values. + // + if (power < 0) { + d = d / simdjson::internal::power_of_ten[-power]; + } else { + d = d * simdjson::internal::power_of_ten[power]; + } + if (negative) { + d = -d; + } + return true; + } + // When 22 < power && power < 22 + 16, we could + // hope for another, secondary fast path. It was + // described by David M. Gay in "Correctly rounded + // binary-decimal and decimal-binary conversions." (1990) + // If you need to compute i * 10^(22 + x) for x < 16, + // first compute i * 10^x, if you know that result is exact + // (e.g., when i * 10^x < 2^53), + // then you can still proceed and do (i * 10^x) * 10^22. + // Is this worth your time? + // You need 22 < power *and* power < 22 + 16 *and* (i * 10^(x-22) < 2^53) + // for this second fast path to work. + // If you you have 22 < power *and* power < 22 + 16, and then you + // optimistically compute "i * 10^(x-22)", there is still a chance that you + // have wasted your time if i * 10^(x-22) >= 2^53. It makes the use cases of + // this optimization maybe less common than we would like. Source: + // http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + // also used in RapidJSON: https://rapidjson.org/strtod_8h_source.html + + // The fast path has now failed, so we are failing back on the slower path. + + // In the slow path, we need to adjust i so that it is > 1<<63 which is always + // possible, except if i == 0, so we handle i == 0 separately. + if(i == 0) { + d = negative ? -0.0 : 0.0; + return true; + } + + + // The exponent is 1024 + 63 + power + // + floor(log(5**power)/log(2)). + // The 1024 comes from the ieee64 standard. + // The 63 comes from the fact that we use a 64-bit word. + // + // Computing floor(log(5**power)/log(2)) could be + // slow. Instead we use a fast function. + // + // For power in (-400,350), we have that + // (((152170 + 65536) * power ) >> 16); + // is equal to + // floor(log(5**power)/log(2)) + power when power >= 0 + // and it is equal to + // ceil(log(5**-power)/log(2)) + power when power < 0 + // + // The 65536 is (1<<16) and corresponds to + // (65536 * power) >> 16 ---> power + // + // ((152170 * power ) >> 16) is equal to + // floor(log(5**power)/log(2)) + // + // Note that this is not magic: 152170/(1<<16) is + // approximatively equal to log(5)/log(2). + // The 1<<16 value is a power of two; we could use a + // larger power of 2 if we wanted to. + // + int64_t exponent = (((152170 + 65536) * power) >> 16) + 1024 + 63; + + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(i); + i <<= lz; + + + // We are going to need to do some 64-bit arithmetic to get a precise product. + // We use a table lookup approach. + // It is safe because + // power >= smallest_power + // and power <= largest_power + // We recover the mantissa of the power, it has a leading 1. It is always + // rounded down. + // + // We want the most significant 64 bits of the product. We know + // this will be non-zero because the most significant bit of i is + // 1. + const uint32_t index = 2 * uint32_t(power - simdjson::internal::smallest_power); + // Optimization: It may be that materializing the index as a variable might confuse some compilers and prevent effective complex-addressing loads. (Done for code clarity.) + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); + // Both i and power_of_five_128[index] have their most significant bit set to 1 which + // implies that the either the most or the second most significant bit of the product + // is 1. We pack values in this manner for efficiency reasons: it maximizes the use + // we make of the product. It also makes it easy to reason about the product: there + // is 0 or 1 leading zero in the product. + + // Unless the least significant 9 bits of the high (64-bit) part of the full + // product are all 1s, then we know that the most significant 55 bits are + // exact and no further work is needed. Having 55 bits is necessary because + // we need 53 bits for the mantissa but we have to have one rounding bit and + // we can waste a bit if the most significant bit of the product is zero. + if((firstproduct.high & 0x1FF) == 0x1FF) { + // We want to compute i * 5^q, but only care about the top 55 bits at most. + // Consider the scenario where q>=0. Then 5^q may not fit in 64-bits. Doing + // the full computation is wasteful. So we do what is called a "truncated + // multiplication". + // We take the most significant 64-bits, and we put them in + // power_of_five_128[index]. Usually, that's good enough to approximate i * 5^q + // to the desired approximation using one multiplication. Sometimes it does not suffice. + // Then we store the next most significant 64 bits in power_of_five_128[index + 1], and + // then we get a better approximation to i * 5^q. + // + // That's for when q>=0. The logic for q<0 is somewhat similar but it is somewhat + // more complicated. + // + // There is an extra layer of complexity in that we need more than 55 bits of + // accuracy in the round-to-even scenario. + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if(secondproduct.high > firstproduct.low) { firstproduct.high++; } + // As it has been proven by Noble Mushtak and Daniel Lemire in "Fast Number Parsing Without + // Fallback" (https://arxiv.org/abs/2212.06644), at this point we are sure that the product + // is sufficiently accurate, and more computation is not needed. + } + uint64_t lower = firstproduct.low; + uint64_t upper = firstproduct.high; + // The final mantissa should be 53 bits with a leading 1. + // We shift it so that it occupies 54 bits with a leading 1. + /////// + uint64_t upperbit = upper >> 63; + uint64_t mantissa = upper >> (upperbit + 9); + lz += int(1 ^ upperbit); + + // Here we have mantissa < (1<<54). + int64_t real_exponent = exponent - lz; + if (simdjson_unlikely(real_exponent <= 0)) { // we have a subnormal? + // Here have that real_exponent <= 0 so -real_exponent >= 0 + if(-real_exponent + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure. + d = negative ? -0.0 : 0.0; + return true; + } + // next line is safe because -real_exponent + 1 < 0 + mantissa >>= -real_exponent + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0. + mantissa += (mantissa & 1); // round up + mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + real_exponent = (mantissa < (uint64_t(1) << 52)) ? 0 : 1; + d = to_double(mantissa, real_exponent, negative); + return true; + } + // We have to round to even. The "to even" part + // is only a problem when we are right in between two floats + // which we guard against. + // If we have lots of trailing zeros, we may fall right between two + // floating-point values. + // + // The round-to-even cases take the form of a number 2m+1 which is in (2^53,2^54] + // times a power of two. That is, it is right between a number with binary significand + // m and another number with binary significand m+1; and it must be the case + // that it cannot be represented by a float itself. + // + // We must have that w * 10 ^q == (2m+1) * 2^p for some power of two 2^p. + // Recall that 10^q = 5^q * 2^q. + // When q >= 0, we must have that (2m+1) is divible by 5^q, so 5^q <= 2^54. We have that + // 5^23 <= 2^54 and it is the last power of five to qualify, so q <= 23. + // When q<0, we have w >= (2m+1) x 5^{-q}. We must have that w<2^{64} so + // (2m+1) x 5^{-q} < 2^{64}. We have that 2m+1>2^{53}. Hence, we must have + // 2^{53} x 5^{-q} < 2^{64}. + // Hence we have 5^{-q} < 2^{11}$ or q>= -4. + // + // We require lower <= 1 and not lower == 0 because we could not prove that + // that lower == 0 is implied; but we could prove that lower <= 1 is a necessary and sufficient test. + if (simdjson_unlikely((lower <= 1) && (power >= -4) && (power <= 23) && ((mantissa & 3) == 1))) { + if((mantissa << (upperbit + 64 - 53 - 2)) == upper) { + mantissa &= ~1; // flip it so that we do not round up + } + } + + mantissa += mantissa & 1; + mantissa >>= 1; + + // Here we have mantissa < (1<<53), unless there was an overflow + if (mantissa >= (1ULL << 53)) { + ////////// + // This will happen when parsing values such as 7.2057594037927933e+16 + //////// + mantissa = (1ULL << 52); + real_exponent++; + } + mantissa &= ~(1ULL << 52); + // we have to check that real_exponent is in range, otherwise we bail out + if (simdjson_unlikely(real_exponent > 2046)) { + // We have an infinite value!!! We could actually throw an error here if we could. + return false; + } + d = to_double(mantissa, real_exponent, negative); + return true; +} + +// We call a fallback floating-point parser that might be slow. Note +// it will accept JSON numbers, but the JSON spec. is more restrictive so +// before you call parse_float_fallback, you need to have validated the input +// string with the JSON grammar. +// It will return an error (false) if the parsed number is infinite. +// The string parsing itself always succeeds. We know that there is at least +// one digit. +static bool parse_float_fallback(const uint8_t *ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +static bool parse_float_fallback(const uint8_t *ptr, const uint8_t *end_ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr), reinterpret_cast(end_ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +// check quickly whether the next 8 chars are made of digits +// at a glance, it looks better than Mula's +// http://0x80.pl/articles/swar-digits-validate.html +simdjson_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) { + uint64_t val; + // this can read up to 7 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(7 <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be bigger than 7"); + std::memcpy(&val, chars, 8); + // a branchy method might be faster: + // return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030) + // && (( (val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0 ) == + // 0x3030303030303030); + return (((val & 0xF0F0F0F0F0F0F0F0) | + (((val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4)) == + 0x3333333333333333); +} + +template +SIMDJSON_NO_SANITIZE_UNDEFINED // We deliberately allow overflow here and check later +simdjson_inline bool parse_digit(const uint8_t c, I &i) { + const uint8_t digit = static_cast(c - '0'); + if (digit > 9) { + return false; + } + // PERF NOTE: multiplication by 10 is cheaper than arbitrary integer multiplication + i = 10 * i + digit; // might overflow, we will handle the overflow later + return true; +} + +simdjson_inline error_code parse_decimal_after_separator(simdjson_unused const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) { + // we continue with the fiction that we have an integer. If the + // floating point number is representable as x * 10^z for some integer + // z that fits in 53 bits, then we will be able to convert back the + // the integer into a float in a lossless manner. + const uint8_t *const first_after_period = p; + +#ifdef SIMDJSON_SWAR_NUMBER_PARSING +#if SIMDJSON_SWAR_NUMBER_PARSING + // this helps if we have lots of decimals! + // this turns out to be frequent enough. + if (is_made_of_eight_digits_fast(p)) { + i = i * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + } +#endif // SIMDJSON_SWAR_NUMBER_PARSING +#endif // #ifdef SIMDJSON_SWAR_NUMBER_PARSING + // Unrolling the first digit makes a small difference on some implementations (e.g. westmere) + if (parse_digit(*p, i)) { ++p; } + while (parse_digit(*p, i)) { p++; } + exponent = first_after_period - p; + // Decimal without digits (123.) is illegal + if (exponent == 0) { + return INVALID_NUMBER(src); + } + return SUCCESS; +} + +simdjson_inline error_code parse_exponent(simdjson_unused const uint8_t *const src, const uint8_t *&p, int64_t &exponent) { + // Exp Sign: -123.456e[-]78 + bool neg_exp = ('-' == *p); + if (neg_exp || '+' == *p) { p++; } // Skip + as well + + // Exponent: -123.456e-[78] + auto start_exp = p; + int64_t exp_number = 0; + while (parse_digit(*p, exp_number)) { ++p; } + // It is possible for parse_digit to overflow. + // In particular, it could overflow to INT64_MIN, and we cannot do - INT64_MIN. + // Thus we *must* check for possible overflow before we negate exp_number. + + // Performance notes: it may seem like combining the two "simdjson_unlikely checks" below into + // a single simdjson_unlikely path would be faster. The reasoning is sound, but the compiler may + // not oblige and may, in fact, generate two distinct paths in any case. It might be + // possible to do uint64_t(p - start_exp - 1) >= 18 but it could end up trading off + // instructions for a simdjson_likely branch, an unconclusive gain. + + // If there were no digits, it's an error. + if (simdjson_unlikely(p == start_exp)) { + return INVALID_NUMBER(src); + } + // We have a valid positive exponent in exp_number at this point, except that + // it may have overflowed. + + // If there were more than 18 digits, we may have overflowed the integer. We have to do + // something!!!! + if (simdjson_unlikely(p > start_exp+18)) { + // Skip leading zeroes: 1e000000000000000000001 is technically valid and doesn't overflow + while (*start_exp == '0') { start_exp++; } + // 19 digits could overflow int64_t and is kind of absurd anyway. We don't + // support exponents smaller than -999,999,999,999,999,999 and bigger + // than 999,999,999,999,999,999. + // We can truncate. + // Note that 999999999999999999 is assuredly too large. The maximal ieee64 value before + // infinity is ~1.8e308. The smallest subnormal is ~5e-324. So, actually, we could + // truncate at 324. + // Note that there is no reason to fail per se at this point in time. + // E.g., 0e999999999999999999999 is a fine number. + if (p > start_exp+18) { exp_number = 999999999999999999; } + } + // At this point, we know that exp_number is a sane, positive, signed integer. + // It is <= 999,999,999,999,999,999. As long as 'exponent' is in + // [-8223372036854775808, 8223372036854775808], we won't overflow. Because 'exponent' + // is bounded in magnitude by the size of the JSON input, we are fine in this universe. + // To sum it up: the next line should never overflow. + exponent += (neg_exp ? -exp_number : exp_number); + return SUCCESS; +} + +simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t digit_count) { + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + const uint8_t *start = start_digits; + while ((*start == '0') || (*start == '.')) { ++start; } + // we over-decrement by one when there is a '.' + return digit_count - size_t(start - start_digits); +} + +} // unnamed namespace + +/** @private */ +static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) { + if (parse_float_fallback(src, answer)) { + return SUCCESS; + } + return INVALID_NUMBER(src); +} + +/** @private */ +template +simdjson_inline error_code write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer) { + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon in practice. + // + // 9999999999999999999 < 2**64 so we can accommodate 19 digits. + // If we have a decimal separator, then digit_count - 1 is the number of digits, but we + // may not have a decimal separator! + if (simdjson_unlikely(digit_count > 19 && significant_digits(start_digits, digit_count) > 19)) { + // Ok, chances are good that we had an overflow! + // this is almost never going to get called!!! + // we start anew, going slowly!!! + // This will happen in the following examples: + // 10000000000000000000000000000000000000000000e+308 + // 3.1415926535897932384626433832795028841971693993751 + // + // NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer + // reference to it, it would force it to be stored in memory, preventing the compiler from + // picking it apart and putting into registers. i.e. if we pass it as reference, + // it gets slow. + double d; + error_code error = slow_float_parsing(src, &d); + writer.append_double(d); + return error; + } + // NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other + // way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331 + // To future reader: we'd love if someone found a better way, or at least could explain this result! + if (simdjson_unlikely(exponent < simdjson::internal::smallest_power) || (exponent > simdjson::internal::largest_power)) { + // + // Important: smallest_power is such that it leads to a zero value. + // Observe that 18446744073709551615e-343 == 0, i.e. (2**64 - 1) e -343 is zero + // so something x 10^-343 goes to zero, but not so with something x 10^-342. + static_assert(simdjson::internal::smallest_power <= -342, "smallest_power is not small enough"); + // + if((exponent < simdjson::internal::smallest_power) || (i == 0)) { + // E.g. Parse "-0.0e-999" into the same value as "-0.0". See https://en.wikipedia.org/wiki/Signed_zero + WRITE_DOUBLE(negative ? -0.0 : 0.0, src, writer); + return SUCCESS; + } else { // (exponent > largest_power) and (i != 0) + // We have, for sure, an infinite value and simdjson refuses to parse infinite values. + return INVALID_NUMBER(src); + } + } + double d; + if (!compute_float_64(exponent, i, negative, d)) { + // we are almost never going to get here. + if (!parse_float_fallback(src, &d)) { return INVALID_NUMBER(src); } + } + WRITE_DOUBLE(d, src, writer); + return SUCCESS; +} + +// for performance analysis, it is sometimes useful to skip parsing +#ifdef SIMDJSON_SKIPNUMBERPARSING + +template +simdjson_inline error_code parse_number(const uint8_t *const, W &writer) { + writer.append_s64(0); // always write zero + return SUCCESS; // always succeeds +} + +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { return number_type::signed_integer; } +#else + +// parse the number at src +// define JSON_TEST_NUMBERS for unit testing +// +// It is assumed that the number is followed by a structural ({,},],[) character +// or a white space character. If that is not the case (e.g., when the JSON +// document is made of a single number), then it is necessary to copy the +// content and append a space before calling this function. +// +// Our objective is accurate parsing (ULP of 0) at high speed. +template +simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) { + + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + if (digit_count == 0 || ('0' == *start_digits && digit_count > 1)) { return INVALID_NUMBER(src); } + + // + // Handle floats if there is a . or e (or both) + // + int64_t exponent = 0; + bool is_float = false; + if ('.' == *p) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) ); + digit_count = int(p - start_digits); // used later to guard against overflows + } + if (('e' == *p) || ('E' == *p)) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_exponent(src, p, exponent) ); + } + if (is_float) { + const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p); + SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) ); + if (dirty_end) { return INVALID_NUMBER(src); } + return SUCCESS; + } + + // The longest negative 64-bit number is 19 digits. + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + size_t longest_digit_count = negative ? 19 : 20; + if (digit_count > longest_digit_count) { return INVALID_NUMBER(src); } + if (digit_count == longest_digit_count) { + if (negative) { + // Anything negative above INT64_MAX+1 is invalid + if (i > uint64_t(INT64_MAX)+1) { return INVALID_NUMBER(src); } + WRITE_INTEGER(~i+1, src, writer); + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + } else if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INVALID_NUMBER(src); } + } + + // Write unsigned if it doesn't fit in a signed integer. + if (i > uint64_t(INT64_MAX)) { + WRITE_UNSIGNED(i, src, writer); + } else { + WRITE_INTEGER(negative ? (~i+1) : i, src, writer); + } + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; +} + +// Inlineable functions +namespace { + +// This table can be used to characterize the final character of an integer +// string. For JSON structural character and allowable white space characters, +// we return SUCCESS. For 'e', '.' and 'E', we return INCORRECT_TYPE. Otherwise +// we return NUMBER_ERROR. +// Optimization note: we could easily reduce the size of the table by half (to 128) +// at the cost of an extra branch. +// Optimization note: we want the values to use at most 8 bits (not, e.g., 32 bits): +static_assert(error_code(uint8_t(NUMBER_ERROR))== NUMBER_ERROR, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(SUCCESS))== SUCCESS, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(INCORRECT_TYPE))== INCORRECT_TYPE, "bad NUMBER_ERROR cast"); + +const uint8_t integer_string_finisher[256] = { + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, INCORRECT_TYPE, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, SUCCESS, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR}; + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + + +// Parse any number from 0 to 18,446,744,073,709,551,615 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src, const uint8_t * const src_end) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if ((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { + const uint8_t *p = src + 1; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (*p != '"') { return NUMBER_ERROR; } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + // Note: we use src[1] and not src[0] because src[0] is the quote character in this + // instance. + if (src[1] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src, const uint8_t * const src_end) noexcept { + // + // Check for minus sign + // + if(src == src_end) { return NUMBER_ERROR; } + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = src; + uint64_t i = 0; + while (parse_digit(*src, i)) { src++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(src - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*src)) { + // return (*src == '.' || *src == 'e' || *src == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(*src != '"') { return NUMBER_ERROR; } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { + return (*src == '-'); +} + +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { return true; } + return false; +} + +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { + // We have an integer. + // If the number is negative and valid, it must be a signed integer. + if(negative) { return number_type::signed_integer; } + // We want values larger or equal to 9223372036854775808 to be unsigned + // integers, and the other values to be signed integers. + int digit_count = int(p - src); + if(digit_count >= 19) { + const uint8_t * smaller_big_integer = reinterpret_cast("9223372036854775808"); + if((digit_count >= 20) || (memcmp(src, smaller_big_integer, 19) >= 0)) { + return number_type::unsigned_integer; + } + } + return number_type::signed_integer; + } + // Hopefully, we have 'e' or 'E' or '.'. + return number_type::floating_point_number; +} + +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src, const uint8_t * const src_end) noexcept { + if(src == src_end) { return NUMBER_ERROR; } + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + if(p == src_end) { return NUMBER_ERROR; } + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while ((p != src_end) && parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely((p != src_end) && (*p == '.'))) { + p++; + const uint8_t *start_decimal_digits = p; + if ((p == src_end) || !parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = start_digits-src > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if ((p != src_end) && (*p == 'e' || *p == 'E')) { + p++; + if(p == src_end) { return NUMBER_ERROR; } + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while ((p != src_end) && parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (*p != '"') { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +} // unnamed namespace +#endif // SIMDJSON_SKIPNUMBERPARSING + +} // namespace numberparsing + +inline std::ostream& operator<<(std::ostream& out, number_type type) noexcept { + switch (type) { + case number_type::signed_integer: out << "integer in [-9223372036854775808,9223372036854775808)"; break; + case number_type::unsigned_integer: out << "unsigned integer in [9223372036854775808,18446744073709551616)"; break; + case number_type::floating_point_number: out << "floating-point number (binary64)"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_NUMBERPARSING_H +/* end file simdjson/generic/numberparsing.h for arm64 */ + +/* including simdjson/generic/implementation_simdjson_result_base-inl.h for arm64: #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { + +// +// internal::implementation_simdjson_result_base inline implementation +// + +template +simdjson_inline void implementation_simdjson_result_base::tie(T &value, error_code &error) && noexcept { + error = this->second; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +simdjson_warn_unused simdjson_inline error_code implementation_simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; +} + +template +simdjson_inline error_code implementation_simdjson_result_base::error() const noexcept { + return this->second; +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& implementation_simdjson_result_base::value() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline T&& implementation_simdjson_result_base::take_value() && noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& implementation_simdjson_result_base::value_unsafe() const& noexcept { + return this->first; +} + +template +simdjson_inline T& implementation_simdjson_result_base::value_unsafe() & noexcept { + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value_unsafe() && noexcept { + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value, error_code error) noexcept + : first{std::forward(value)}, second{error} {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(error_code error) noexcept + : implementation_simdjson_result_base(T{}, error) {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value) noexcept + : implementation_simdjson_result_base(std::forward(value), SUCCESS) {} + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H +/* end file simdjson/generic/implementation_simdjson_result_base-inl.h for arm64 */ +/* end file simdjson/generic/amalgamated.h for arm64 */ +/* including simdjson/arm64/end.h: #include "simdjson/arm64/end.h" */ +/* begin file simdjson/arm64/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#undef SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT +/* undefining SIMDJSON_IMPLEMENTATION from "arm64" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/arm64/end.h */ + +#endif // SIMDJSON_ARM64_H +/* end file simdjson/arm64.h */ +/* including simdjson/arm64/implementation.h: #include */ +/* begin file simdjson/arm64/implementation.h */ +#ifndef SIMDJSON_ARM64_IMPLEMENTATION_H +#define SIMDJSON_ARM64_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation("arm64", "ARM NEON", internal::instruction_set::NEON) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_IMPLEMENTATION_H +/* end file simdjson/arm64/implementation.h */ + +/* including simdjson/arm64/begin.h: #include */ +/* begin file simdjson/arm64/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "arm64" */ +#define SIMDJSON_IMPLEMENTATION arm64 +/* including simdjson/arm64/base.h: #include "simdjson/arm64/base.h" */ +/* begin file simdjson/arm64/base.h */ +#ifndef SIMDJSON_ARM64_BASE_H +#define SIMDJSON_ARM64_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Implementation for NEON (ARMv8). + */ +namespace arm64 { + +class implementation; + +namespace { +namespace simd { +template struct simd8; +template struct simd8x64; +} // namespace simd +} // unnamed namespace + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_BASE_H +/* end file simdjson/arm64/base.h */ +/* including simdjson/arm64/intrinsics.h: #include "simdjson/arm64/intrinsics.h" */ +/* begin file simdjson/arm64/intrinsics.h */ +#ifndef SIMDJSON_ARM64_INTRINSICS_H +#define SIMDJSON_ARM64_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This should be the correct header whether +// you use visual studio or other compilers. +#include + +static_assert(sizeof(uint8x16_t) <= simdjson::SIMDJSON_PADDING, "insufficient padding for arm64"); + +#endif // SIMDJSON_ARM64_INTRINSICS_H +/* end file simdjson/arm64/intrinsics.h */ +/* including simdjson/arm64/bitmanipulation.h: #include "simdjson/arm64/bitmanipulation.h" */ +/* begin file simdjson/arm64/bitmanipulation.h */ +#ifndef SIMDJSON_ARM64_BITMANIPULATION_H +#define SIMDJSON_ARM64_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num-1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int count_ones(uint64_t input_num) { + return vaddv_u8(vcnt_u8(vcreate_u8(input_num))); +} + + +#if defined(__GNUC__) // catches clang and gcc +/** + * ARM has a fast 64-bit "bit reversal function" that is handy. However, + * it is not generally available as an intrinsic function under Visual + * Studio (though this might be changing). Even under clang/gcc, we + * apparently need to invoke inline assembly. + */ +/* + * We use SIMDJSON_PREFER_REVERSE_BITS as a hint that algorithms that + * work well with bit reversal may use it. + */ +#define SIMDJSON_PREFER_REVERSE_BITS 1 + +/* reverse the bits */ +simdjson_inline uint64_t reverse_bits(uint64_t input_num) { + uint64_t rev_bits; + __asm("rbit %0, %1" : "=r"(rev_bits) : "r"(input_num)); + return rev_bits; +} + +/** + * Flips bit at index 63 - lz. Thus if you have 'leading_zeroes' leading zeroes, + * then this will set to zero the leading bit. It is possible for leading_zeroes to be + * greating or equal to 63 in which case we trigger undefined behavior, but the output + * of such undefined behavior is never used. + **/ +SIMDJSON_NO_SANITIZE_UNDEFINED +simdjson_inline uint64_t zero_leading_bit(uint64_t rev_bits, int leading_zeroes) { + return rev_bits ^ (uint64_t(0x8000000000000000) >> leading_zeroes); +} + +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + *result = value1 + value2; + return *result < value1; +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_BITMANIPULATION_H +/* end file simdjson/arm64/bitmanipulation.h */ +/* including simdjson/arm64/bitmask.h: #include "simdjson/arm64/bitmask.h" */ +/* begin file simdjson/arm64/bitmask.h */ +#ifndef SIMDJSON_ARM64_BITMASK_H +#define SIMDJSON_ARM64_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(uint64_t bitmask) { + ///////////// + // We could do this with PMULL, but it is apparently slow. + // + //#ifdef __ARM_FEATURE_CRYPTO // some ARM processors lack this extension + //return vmull_p64(-1ULL, bitmask); + //#else + // Analysis by @sebpop: + // When diffing the assembly for src/stage1_find_marks.cpp I see that the eors are all spread out + // in between other vector code, so effectively the extra cycles of the sequence do not matter + // because the GPR units are idle otherwise and the critical path is on the FP side. + // Also the PMULL requires two extra fmovs: GPR->FP (3 cycles in N1, 5 cycles in A72 ) + // and FP->GPR (2 cycles on N1 and 5 cycles on A72.) + /////////// + bitmask ^= bitmask << 1; + bitmask ^= bitmask << 2; + bitmask ^= bitmask << 4; + bitmask ^= bitmask << 8; + bitmask ^= bitmask << 16; + bitmask ^= bitmask << 32; + return bitmask; +} + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif +/* end file simdjson/arm64/bitmask.h */ +/* including simdjson/arm64/numberparsing_defs.h: #include "simdjson/arm64/numberparsing_defs.h" */ +/* begin file simdjson/arm64/numberparsing_defs.h */ +#ifndef SIMDJSON_ARM64_NUMBERPARSING_DEFS_H +#define SIMDJSON_ARM64_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +#if _M_ARM64 +// __umulh requires intrin.h +#include +#endif // _M_ARM64 + +namespace simdjson { +namespace arm64 { +namespace numberparsing { + +// we don't have SSE, so let us use a scalar function +// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + uint64_t val; + std::memcpy(&val, chars, sizeof(uint64_t)); + val = (val & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8; + val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16; + return uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32); +} + +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace arm64 +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_ARM64_NUMBERPARSING_DEFS_H +/* end file simdjson/arm64/numberparsing_defs.h */ +/* including simdjson/arm64/simd.h: #include "simdjson/arm64/simd.h" */ +/* begin file simdjson/arm64/simd.h */ +#ifndef SIMDJSON_ARM64_SIMD_H +#define SIMDJSON_ARM64_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace simd { + +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO +namespace { +// Start of private section with Visual Studio workaround + + +#ifndef simdjson_make_uint8x16_t +#define simdjson_make_uint8x16_t(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \ + x13, x14, x15, x16) \ + ([=]() { \ + uint8_t array[16] = {x1, x2, x3, x4, x5, x6, x7, x8, \ + x9, x10, x11, x12, x13, x14, x15, x16}; \ + return vld1q_u8(array); \ + }()) +#endif +#ifndef simdjson_make_int8x16_t +#define simdjson_make_int8x16_t(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \ + x13, x14, x15, x16) \ + ([=]() { \ + int8_t array[16] = {x1, x2, x3, x4, x5, x6, x7, x8, \ + x9, x10, x11, x12, x13, x14, x15, x16}; \ + return vld1q_s8(array); \ + }()) +#endif + +#ifndef simdjson_make_uint8x8_t +#define simdjson_make_uint8x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + uint8_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1_u8(array); \ + }()) +#endif +#ifndef simdjson_make_int8x8_t +#define simdjson_make_int8x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + int8_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1_s8(array); \ + }()) +#endif +#ifndef simdjson_make_uint16x8_t +#define simdjson_make_uint16x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + uint16_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1q_u16(array); \ + }()) +#endif +#ifndef simdjson_make_int16x8_t +#define simdjson_make_int16x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + int16_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1q_s16(array); \ + }()) +#endif + +// End of private section with Visual Studio workaround +} // namespace +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO + + + template + struct simd8; + + // + // Base class of simd8 and simd8, both of which use uint8x16_t internally. + // + template> + struct base_u8 { + uint8x16_t value; + static const int SIZE = sizeof(value); + + // Conversion from/to SIMD register + simdjson_inline base_u8(const uint8x16_t _value) : value(_value) {} + simdjson_inline operator const uint8x16_t&() const { return this->value; } + simdjson_inline operator uint8x16_t&() { return this->value; } + + // Bit operations + simdjson_inline simd8 operator|(const simd8 other) const { return vorrq_u8(*this, other); } + simdjson_inline simd8 operator&(const simd8 other) const { return vandq_u8(*this, other); } + simdjson_inline simd8 operator^(const simd8 other) const { return veorq_u8(*this, other); } + simdjson_inline simd8 bit_andnot(const simd8 other) const { return vbicq_u8(*this, other); } + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + simdjson_inline simd8& operator|=(const simd8 other) { auto this_cast = static_cast*>(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline simd8& operator&=(const simd8 other) { auto this_cast = static_cast*>(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline simd8& operator^=(const simd8 other) { auto this_cast = static_cast*>(this); *this_cast = *this_cast ^ other; return *this_cast; } + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return vceqq_u8(lhs, rhs); } + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return vextq_u8(prev_chunk, *this, 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base_u8 { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + static simdjson_inline simd8 splat(bool _value) { return vmovq_n_u8(uint8_t(-(!!_value))); } + + simdjson_inline simd8(const uint8x16_t _value) : base_u8(_value) {} + // False constructor + simdjson_inline simd8() : simd8(vdupq_n_u8(0)) {} + // Splat constructor + simdjson_inline simd8(bool _value) : simd8(splat(_value)) {} + + // We return uint32_t instead of uint16_t because that seems to be more efficient for most + // purposes (cutting it down to uint16_t costs performance in some compilers). + simdjson_inline uint32_t to_bitmask() const { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + const uint8x16_t bit_mask = simdjson_make_uint8x16_t(0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80); +#else + const uint8x16_t bit_mask = {0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80}; +#endif + auto minput = *this & bit_mask; + uint8x16_t tmp = vpaddq_u8(minput, minput); + tmp = vpaddq_u8(tmp, tmp); + tmp = vpaddq_u8(tmp, tmp); + return vgetq_lane_u16(vreinterpretq_u16_u8(tmp), 0); + } + simdjson_inline bool any() const { return vmaxvq_u8(*this) != 0; } + }; + + // Unsigned bytes + template<> + struct simd8: base_u8 { + static simdjson_inline uint8x16_t splat(uint8_t _value) { return vmovq_n_u8(_value); } + static simdjson_inline uint8x16_t zero() { return vdupq_n_u8(0); } + static simdjson_inline uint8x16_t load(const uint8_t* values) { return vld1q_u8(values); } + + simdjson_inline simd8(const uint8x16_t _value) : base_u8(_value) {} + // Zero constructor + simdjson_inline simd8() : simd8(zero()) {} + // Array constructor + simdjson_inline simd8(const uint8_t values[16]) : simd8(load(values)) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Member-by-member initialization +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(simdjson_make_uint8x16_t( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} +#else + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(uint8x16_t{ + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + }) {} +#endif + + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Store to array + simdjson_inline void store(uint8_t dst[16]) const { return vst1q_u8(dst, *this); } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return vqaddq_u8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return vqsubq_u8(*this, other); } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return vaddq_u8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return vsubq_u8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *this; } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *this; } + + // Order-specific operations + simdjson_inline uint8_t max_val() const { return vmaxvq_u8(*this); } + simdjson_inline uint8_t min_val() const { return vminvq_u8(*this); } + simdjson_inline simd8 max_val(const simd8 other) const { return vmaxq_u8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return vminq_u8(*this, other); } + simdjson_inline simd8 operator<=(const simd8 other) const { return vcleq_u8(*this, other); } + simdjson_inline simd8 operator>=(const simd8 other) const { return vcgeq_u8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return vcltq_u8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return vcgtq_u8(*this, other); } + // Same as >, but instead of guaranteeing all 1's == true, false = 0 and true = nonzero. For ARM, returns all 1's. + simdjson_inline simd8 gt_bits(const simd8 other) const { return simd8(*this > other); } + // Same as <, but instead of guaranteeing all 1's == true, false = 0 and true = nonzero. For ARM, returns all 1's. + simdjson_inline simd8 lt_bits(const simd8 other) const { return simd8(*this < other); } + + // Bit-specific operations + simdjson_inline simd8 any_bits_set(simd8 bits) const { return vtstq_u8(*this, bits); } + simdjson_inline bool any_bits_set_anywhere() const { return this->max_val() != 0; } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return (*this & bits).any_bits_set_anywhere(); } + template + simdjson_inline simd8 shr() const { return vshrq_n_u8(*this, N); } + template + simdjson_inline simd8 shl() const { return vshlq_n_u8(*this, N); } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return lookup_table.apply_lookup_16_to(*this); + } + + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 16 - count_ones(mask) bytes of the result are significant but 16 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint16_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + uint64x2_t shufmask64 = {thintable_epi8[mask1], thintable_epi8[mask2]}; + uint8x16_t shufmask = vreinterpretq_u8_u64(shufmask64); + // we increment by 0x08 the second half of the mask +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + uint8x16_t inc = simdjson_make_uint8x16_t(0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08); +#else + uint8x16_t inc = {0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; +#endif + shufmask = vaddq_u8(shufmask, inc); + // this is the version "nearly pruned" + uint8x16_t pruned = vqtbl1q_u8(*this, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + uint8x16_t compactmask = vld1q_u8(reinterpret_cast(pshufb_combine_table + pop1 * 8)); + uint8x16_t answer = vqtbl1q_u8(pruned, compactmask); + vst1q_u8(reinterpret_cast(output), answer); + } + + // Copies all bytes corresponding to a 0 in the low half of the mask (interpreted as a + // bitset) to output1, then those corresponding to a 0 in the high half to output2. + template + simdjson_inline void compress_halves(uint16_t mask, L *output1, L *output2) const { + using internal::thintable_epi8; + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + uint8x8_t compactmask1 = vcreate_u8(thintable_epi8[mask1]); + uint8x8_t compactmask2 = vcreate_u8(thintable_epi8[mask2]); + // we increment by 0x08 the second half of the mask +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + uint8x8_t inc = simdjson_make_uint8x8_t(0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08); +#else + uint8x8_t inc = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; +#endif + compactmask2 = vadd_u8(compactmask2, inc); + // store each result (with the second store possibly overlapping the first) + vst1_u8((uint8_t*)output1, vqtbl1_u8(*this, compactmask1)); + vst1_u8((uint8_t*)output2, vqtbl1_u8(*this, compactmask2)); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + + template + simdjson_inline simd8 apply_lookup_16_to(const simd8 original) { + return vqtbl1q_u8(*this, simd8(original)); + } + }; + + // Signed bytes + template<> + struct simd8 { + int8x16_t value; + + static simdjson_inline simd8 splat(int8_t _value) { return vmovq_n_s8(_value); } + static simdjson_inline simd8 zero() { return vdupq_n_s8(0); } + static simdjson_inline simd8 load(const int8_t values[16]) { return vld1q_s8(values); } + + // Conversion from/to SIMD register + simdjson_inline simd8(const int8x16_t _value) : value{_value} {} + simdjson_inline operator const int8x16_t&() const { return this->value; } + simdjson_inline operator int8x16_t&() { return this->value; } + + // Zero constructor + simdjson_inline simd8() : simd8(zero()) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {} + // Member-by-member initialization +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(simdjson_make_int8x16_t( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} +#else + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(int8x16_t{ + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + }) {} +#endif + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Store to array + simdjson_inline void store(int8_t dst[16]) const { return vst1q_s8(dst, *this); } + + // Explicit conversion to/from unsigned + // + // Under Visual Studio/ARM64 uint8x16_t and int8x16_t are apparently the same type. + // In theory, we could check this occurrence with std::same_as and std::enabled_if but it is C++14 + // and relatively ugly and hard to read. +#ifndef SIMDJSON_REGULAR_VISUAL_STUDIO + simdjson_inline explicit simd8(const uint8x16_t other): simd8(vreinterpretq_s8_u8(other)) {} +#endif + simdjson_inline explicit operator simd8() const { return vreinterpretq_u8_s8(this->value); } + + // Math + simdjson_inline simd8 operator+(const simd8 other) const { return vaddq_s8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return vsubq_s8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *this; } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *this; } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return vmaxq_s8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return vminq_s8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return vcgtq_s8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return vcltq_s8(*this, other); } + simdjson_inline simd8 operator==(const simd8 other) const { return vceqq_s8(*this, other); } + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return vextq_s8(prev_chunk, *this, 16 - N); + } + + // Perform a lookup assuming no value is larger than 16 + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return lookup_table.apply_lookup_16_to(*this); + } + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + + template + simdjson_inline simd8 apply_lookup_16_to(const simd8 original) { + return vqtbl1q_s8(*this, simd8(original)); + } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, "ARM kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, const simd8 chunk2, const simd8 chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+16), simd8::load(ptr+32), simd8::load(ptr+48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + this->chunks[2].store(ptr+sizeof(simd8)*2); + this->chunks[3].store(ptr+sizeof(simd8)*3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | (this->chunks[2] | this->chunks[3]); + } + + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + uint64_t popcounts = vget_lane_u64(vreinterpret_u64_u8(vcnt_u8(vcreate_u8(~mask))), 0); + // compute the prefix sum of the popcounts of each byte + uint64_t offsets = popcounts * 0x0101010101010101; + this->chunks[0].compress_halves(uint16_t(mask), output, &output[popcounts & 0xFF]); + this->chunks[1].compress_halves(uint16_t(mask >> 16), &output[(offsets >> 8) & 0xFF], &output[(offsets >> 16) & 0xFF]); + this->chunks[2].compress_halves(uint16_t(mask >> 32), &output[(offsets >> 24) & 0xFF], &output[(offsets >> 32) & 0xFF]); + this->chunks[3].compress_halves(uint16_t(mask >> 48), &output[(offsets >> 40) & 0xFF], &output[(offsets >> 48) & 0xFF]); + return offsets >> 56; + } + + simdjson_inline uint64_t to_bitmask() const { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + const uint8x16_t bit_mask = simdjson_make_uint8x16_t( + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 + ); +#else + const uint8x16_t bit_mask = { + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 + }; +#endif + // Add each of the elements next to each other, successively, to stuff each 8 byte mask into one. + uint8x16_t sum0 = vpaddq_u8(this->chunks[0] & bit_mask, this->chunks[1] & bit_mask); + uint8x16_t sum1 = vpaddq_u8(this->chunks[2] & bit_mask, this->chunks[3] & bit_mask); + sum0 = vpaddq_u8(sum0, sum1); + sum0 = vpaddq_u8(sum0, sum0); + return vgetq_lane_u64(vreinterpretq_u64_u8(sum0), 0); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask, + this->chunks[2] == mask, + this->chunks[3] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask, + this->chunks[2] <= mask, + this->chunks[3] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_SIMD_H +/* end file simdjson/arm64/simd.h */ +/* including simdjson/arm64/stringparsing_defs.h: #include "simdjson/arm64/stringparsing_defs.h" */ +/* begin file simdjson/arm64/stringparsing_defs.h */ +#ifndef SIMDJSON_ARM64_STRINGPARSING_DEFS_H +#define SIMDJSON_ARM64_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/simd.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return bs_bits != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 31 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v0(src); + simd8 v1(src + sizeof(v0)); + v0.store(dst); + v1.store(dst + sizeof(v0)); + + // Getting a 64-bit bitmask is much cheaper than multiple 16-bit bitmasks on ARM; therefore, we + // smash them together into a 64-byte mask and get the bitmask from there. + uint64_t bs_and_quote = simd8x64(v0 == '\\', v1 == '\\', v0 == '"', v1 == '"').to_bitmask(); + return { + uint32_t(bs_and_quote), // bs_bits + uint32_t(bs_and_quote >> 32) // quote_bits + }; +} + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_STRINGPARSING_DEFS_H +/* end file simdjson/arm64/stringparsing_defs.h */ + +#define SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT 1 +/* end file simdjson/arm64/begin.h */ +/* including generic/amalgamated.h for arm64: #include */ +/* begin file generic/amalgamated.h for arm64 */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_SRC_GENERIC_DEPENDENCIES_H) +#error generic/dependencies.h must be included before generic/amalgamated.h! +#endif + +/* including generic/base.h for arm64: #include */ +/* begin file generic/base.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { + +struct json_character_block; + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_BASE_H +/* end file generic/base.h for arm64 */ +/* including generic/dom_parser_implementation.h for arm64: #include */ +/* begin file generic/dom_parser_implementation.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// Interface a dom parser implementation must fulfill +namespace simdjson { +namespace arm64 { +namespace { + +simdjson_inline simd8 must_be_2_3_continuation(const simd8 prev2, const simd8 prev3); +simdjson_inline bool is_ascii(const simd8x64& input); + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file generic/dom_parser_implementation.h for arm64 */ +/* including generic/json_character_block.h for arm64: #include */ +/* begin file generic/json_character_block.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { + +struct json_character_block { + static simdjson_inline json_character_block classify(const simd::simd8x64& in); + + simdjson_inline uint64_t whitespace() const noexcept { return _whitespace; } + simdjson_inline uint64_t op() const noexcept { return _op; } + simdjson_inline uint64_t scalar() const noexcept { return ~(op() | whitespace()); } + + uint64_t _whitespace; + uint64_t _op; +}; + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H +/* end file generic/json_character_block.h for arm64 */ +/* end file generic/amalgamated.h for arm64 */ +/* including generic/stage1/amalgamated.h for arm64: #include */ +/* begin file generic/stage1/amalgamated.h for arm64 */ +// Stuff other things depend on +/* including generic/stage1/base.h for arm64: #include */ +/* begin file generic/stage1/base.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace stage1 { + +class bit_indexer; +template +struct buf_block_reader; +struct json_block; +class json_minifier; +class json_scanner; +struct json_string_block; +class json_string_scanner; +class json_structural_indexer; + +} // namespace stage1 + +namespace utf8_validation { +struct utf8_checker; +} // namespace utf8_validation + +using utf8_validation::utf8_checker; + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_BASE_H +/* end file generic/stage1/base.h for arm64 */ +/* including generic/stage1/buf_block_reader.h for arm64: #include */ +/* begin file generic/stage1/buf_block_reader.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace arm64 { +namespace { +namespace stage1 { + +// Walks through a buffer in block-sized increments, loading the last part with spaces +template +struct buf_block_reader { +public: + simdjson_inline buf_block_reader(const uint8_t *_buf, size_t _len); + simdjson_inline size_t block_index(); + simdjson_inline bool has_full_block() const; + simdjson_inline const uint8_t *full_block() const; + /** + * Get the last block, padded with spaces. + * + * There will always be a last block, with at least 1 byte, unless len == 0 (in which case this + * function fills the buffer with spaces and returns 0. In particular, if len == STEP_SIZE there + * will be 0 full_blocks and 1 remainder block with STEP_SIZE bytes and no spaces for padding. + * + * @return the number of effective characters in the last block. + */ + simdjson_inline size_t get_remainder(uint8_t *dst) const; + simdjson_inline void advance(); +private: + const uint8_t *buf; + const size_t len; + const size_t lenminusstep; + size_t idx; +}; + +// Routines to print masks and text for debugging bitmask operations +simdjson_unused static char * format_input_text_64(const uint8_t *text) { + static char buf[sizeof(simd8x64) + 1]; + for (size_t i=0; i); i++) { + buf[i] = int8_t(text[i]) < ' ' ? '_' : int8_t(text[i]); + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +// Routines to print masks and text for debugging bitmask operations +simdjson_unused static char * format_input_text(const simd8x64& in) { + static char buf[sizeof(simd8x64) + 1]; + in.store(reinterpret_cast(buf)); + for (size_t i=0; i); i++) { + if (buf[i] < ' ') { buf[i] = '_'; } + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +simdjson_unused static char * format_input_text(const simd8x64& in, uint64_t mask) { + static char buf[sizeof(simd8x64) + 1]; + in.store(reinterpret_cast(buf)); + for (size_t i=0; i); i++) { + if (buf[i] <= ' ') { buf[i] = '_'; } + if (!(mask & (size_t(1) << i))) { buf[i] = ' '; } + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +simdjson_unused static char * format_mask(uint64_t mask) { + static char buf[sizeof(simd8x64) + 1]; + for (size_t i=0; i<64; i++) { + buf[i] = (mask & (size_t(1) << i)) ? 'X' : ' '; + } + buf[64] = '\0'; + return buf; +} + +template +simdjson_inline buf_block_reader::buf_block_reader(const uint8_t *_buf, size_t _len) : buf{_buf}, len{_len}, lenminusstep{len < STEP_SIZE ? 0 : len - STEP_SIZE}, idx{0} {} + +template +simdjson_inline size_t buf_block_reader::block_index() { return idx; } + +template +simdjson_inline bool buf_block_reader::has_full_block() const { + return idx < lenminusstep; +} + +template +simdjson_inline const uint8_t *buf_block_reader::full_block() const { + return &buf[idx]; +} + +template +simdjson_inline size_t buf_block_reader::get_remainder(uint8_t *dst) const { + if(len == idx) { return 0; } // memcpy(dst, null, 0) will trigger an error with some sanitizers + std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it's more efficient to write out 8 or 16 bytes at once. + std::memcpy(dst, buf + idx, len - idx); + return len - idx; +} + +template +simdjson_inline void buf_block_reader::advance() { + idx += STEP_SIZE; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H +/* end file generic/stage1/buf_block_reader.h for arm64 */ +/* including generic/stage1/json_escape_scanner.h for arm64: #include */ +/* begin file generic/stage1/json_escape_scanner.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_ESCAPE_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_ESCAPE_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace stage1 { + +/** + * Scans for escape characters in JSON, taking care with multiple backslashes (\\n vs. \n). + */ +struct json_escape_scanner { + /** The actual escape characters (the backslashes themselves). */ + uint64_t next_is_escaped = 0ULL; + + struct escaped_and_escape { + /** + * Mask of escaped characters. + * + * ``` + * \n \\n \\\n \\\\n \ + * 0100100010100101000 + * n \ \ n \ \ + * ``` + */ + uint64_t escaped; + /** + * Mask of escape characters. + * + * ``` + * \n \\n \\\n \\\\n \ + * 1001000101001010001 + * \ \ \ \ \ \ \ + * ``` + */ + uint64_t escape; + }; + + /** + * Get a mask of both escape and escaped characters (the characters following a backslash). + * + * @param potential_escape A mask of the character that can escape others (but could be + * escaped itself). e.g. block.eq('\\') + */ + simdjson_really_inline escaped_and_escape next(uint64_t backslash) noexcept { + +#if !SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT + if (!backslash) { return {next_escaped_without_backslashes(), 0}; } +#endif + + // | | Mask (shows characters instead of 1's) | Depth | Instructions | + // |--------------------------------|----------------------------------------|-------|---------------------| + // | string | `\\n_\\\n___\\\n___\\\\___\\\\__\\\` | | | + // | | ` even odd even odd odd` | | | + // | potential_escape | ` \ \\\ \\\ \\\\ \\\\ \\\` | 1 | 1 (backslash & ~first_is_escaped) + // | escape_and_terminal_code | ` \n \ \n \ \n \ \ \ \ \ \` | 5 | 5 (next_escape_and_terminal_code()) + // | escaped | `\ \ n \ n \ \ \ \ \ ` X | 6 | 7 (escape_and_terminal_code ^ (potential_escape | first_is_escaped)) + // | escape | ` \ \ \ \ \ \ \ \ \ \` | 6 | 8 (escape_and_terminal_code & backslash) + // | first_is_escaped | `\ ` | 7 (*) | 9 (escape >> 63) () + // (*) this is not needed until the next iteration + uint64_t escape_and_terminal_code = next_escape_and_terminal_code(backslash & ~this->next_is_escaped); + uint64_t escaped = escape_and_terminal_code ^ (backslash | this->next_is_escaped); + uint64_t escape = escape_and_terminal_code & backslash; + this->next_is_escaped = escape >> 63; + return {escaped, escape}; + } + +private: + static constexpr const uint64_t ODD_BITS = 0xAAAAAAAAAAAAAAAAULL; + + simdjson_really_inline uint64_t next_escaped_without_backslashes() noexcept { + uint64_t escaped = this->next_is_escaped; + this->next_is_escaped = 0; + return escaped; + } + + /** + * Returns a mask of the next escape characters (masking out escaped backslashes), along with + * any non-backslash escape codes. + * + * \n \\n \\\n \\\\n returns: + * \n \ \ \n \ \ + * 11 100 1011 10100 + * + * You are expected to mask out the first bit yourself if the previous block had a trailing + * escape. + * + * & the result with potential_escape to get just the escape characters. + * ^ the result with (potential_escape | first_is_escaped) to get escaped characters. + */ + static simdjson_really_inline uint64_t next_escape_and_terminal_code(uint64_t potential_escape) noexcept { + // If we were to just shift and mask out any odd bits, we'd actually get a *half* right answer: + // any even-aligned backslash runs would be correct! Odd-aligned backslash runs would be + // inverted (\\\ would be 010 instead of 101). + // + // ``` + // string: | ____\\\\_\\\\_____ | + // maybe_escaped | ODD | \ \ \ \ | + // even-aligned ^^^ ^^^^ odd-aligned + // ``` + // + // Taking that into account, our basic strategy is: + // + // 1. Use subtraction to produce a mask with 1's for even-aligned runs and 0's for + // odd-aligned runs. + // 2. XOR all odd bits, which masks out the odd bits in even-aligned runs, and brings IN the + // odd bits in odd-aligned runs. + // 3. & with backslash to clean up any stray bits. + // runs are set to 0, and then XORing with "odd": + // + // | | Mask (shows characters instead of 1's) | Instructions | + // |--------------------------------|----------------------------------------|---------------------| + // | string | `\\n_\\\n___\\\n___\\\\___\\\\__\\\` | + // | | ` even odd even odd odd` | + // | maybe_escaped | ` n \\n \\n \\\_ \\\_ \\` X | 1 (potential_escape << 1) + // | maybe_escaped_and_odd | ` \n_ \\n _ \\\n_ _ \\\__ _\\\_ \\\` | 1 (maybe_escaped | odd) + // | even_series_codes_and_odd | ` n_\\\ _ n_ _\\\\ _ _ ` | 1 (maybe_escaped_and_odd - potential_escape) + // | escape_and_terminal_code | ` \n \ \n \ \n \ \ \ \ \ \` | 1 (^ odd) + // + + // Escaped characters are characters following an escape. + uint64_t maybe_escaped = potential_escape << 1; + + // To distinguish odd from even escape sequences, therefore, we turn on any *starting* + // escapes that are on an odd byte. (We actually bring in all odd bits, for speed.) + // - Odd runs of backslashes are 0000, and the code at the end ("n" in \n or \\n) is 1. + // - Odd runs of backslashes are 1111, and the code at the end ("n" in \n or \\n) is 0. + // - All other odd bytes are 1, and even bytes are 0. + uint64_t maybe_escaped_and_odd_bits = maybe_escaped | ODD_BITS; + uint64_t even_series_codes_and_odd_bits = maybe_escaped_and_odd_bits - potential_escape; + + // Now we flip all odd bytes back with xor. This: + // - Makes odd runs of backslashes go from 0000 to 1010 + // - Makes even runs of backslashes go from 1111 to 1010 + // - Sets actually-escaped codes to 1 (the n in \n and \\n: \n = 11, \\n = 100) + // - Resets all other bytes to 0 + return even_series_codes_and_odd_bits ^ ODD_BITS; + } +}; + +} // namespace stage1 +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H +/* end file generic/stage1/json_escape_scanner.h for arm64 */ +/* including generic/stage1/json_string_scanner.h for arm64: #include */ +/* begin file generic/stage1/json_string_scanner.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace stage1 { + +struct json_string_block { + // We spell out the constructors in the hope of resolving inlining issues with Visual Studio 2017 + simdjson_really_inline json_string_block(uint64_t escaped, uint64_t quote, uint64_t in_string) : + _escaped(escaped), _quote(quote), _in_string(in_string) {} + + // Escaped characters (characters following an escape() character) + simdjson_really_inline uint64_t escaped() const { return _escaped; } + // Real (non-backslashed) quotes + simdjson_really_inline uint64_t quote() const { return _quote; } + // Only characters inside the string (not including the quotes) + simdjson_really_inline uint64_t string_content() const { return _in_string & ~_quote; } + // Return a mask of whether the given characters are inside a string (only works on non-quotes) + simdjson_really_inline uint64_t non_quote_inside_string(uint64_t mask) const { return mask & _in_string; } + // Return a mask of whether the given characters are inside a string (only works on non-quotes) + simdjson_really_inline uint64_t non_quote_outside_string(uint64_t mask) const { return mask & ~_in_string; } + // Tail of string (everything except the start quote) + simdjson_really_inline uint64_t string_tail() const { return _in_string ^ _quote; } + + // escaped characters (backslashed--does not include the hex characters after \u) + uint64_t _escaped; + // real quotes (non-escaped ones) + uint64_t _quote; + // string characters (includes start quote but not end quote) + uint64_t _in_string; +}; + +// Scans blocks for string characters, storing the state necessary to do so +class json_string_scanner { +public: + simdjson_really_inline json_string_block next(const simd::simd8x64& in); + // Returns either UNCLOSED_STRING or SUCCESS + simdjson_really_inline error_code finish(); + +private: + // Scans for escape characters + json_escape_scanner escape_scanner{}; + // Whether the last iteration was still inside a string (all 1's = true, all 0's = false). + uint64_t prev_in_string = 0ULL; +}; + +// +// Return a mask of all string characters plus end quotes. +// +// prev_escaped is overflow saying whether the next character is escaped. +// prev_in_string is overflow saying whether we're still in a string. +// +// Backslash sequences outside of quotes will be detected in stage 2. +// +simdjson_really_inline json_string_block json_string_scanner::next(const simd::simd8x64& in) { + const uint64_t backslash = in.eq('\\'); + const uint64_t escaped = escape_scanner.next(backslash).escaped; + const uint64_t quote = in.eq('"') & ~escaped; + + // + // prefix_xor flips on bits inside the string (and flips off the end quote). + // + // Then we xor with prev_in_string: if we were in a string already, its effect is flipped + // (characters inside strings are outside, and characters outside strings are inside). + // + const uint64_t in_string = prefix_xor(quote) ^ prev_in_string; + + // + // Check if we're still in a string at the end of the box so the next block will know + // + prev_in_string = uint64_t(static_cast(in_string) >> 63); + + // Use ^ to turn the beginning quote off, and the end quote on. + + // We are returning a function-local object so either we get a move constructor + // or we get copy elision. + return json_string_block(escaped, quote, in_string); +} + +simdjson_really_inline error_code json_string_scanner::finish() { + if (prev_in_string) { + return UNCLOSED_STRING; + } + return SUCCESS; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H +/* end file generic/stage1/json_string_scanner.h for arm64 */ +/* including generic/stage1/utf8_lookup4_algorithm.h for arm64: #include */ +/* begin file generic/stage1/utf8_lookup4_algorithm.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace utf8_validation { + +using namespace simd; + + simdjson_inline simd8 check_special_cases(const simd8 input, const simd8 prev1) { +// Bit 0 = Too Short (lead byte/ASCII followed by lead byte/ASCII) +// Bit 1 = Too Long (ASCII followed by continuation) +// Bit 2 = Overlong 3-byte +// Bit 4 = Surrogate +// Bit 5 = Overlong 2-byte +// Bit 7 = Two Continuations + constexpr const uint8_t TOO_SHORT = 1<<0; // 11______ 0_______ + // 11______ 11______ + constexpr const uint8_t TOO_LONG = 1<<1; // 0_______ 10______ + constexpr const uint8_t OVERLONG_3 = 1<<2; // 11100000 100_____ + constexpr const uint8_t SURROGATE = 1<<4; // 11101101 101_____ + constexpr const uint8_t OVERLONG_2 = 1<<5; // 1100000_ 10______ + constexpr const uint8_t TWO_CONTS = 1<<7; // 10______ 10______ + constexpr const uint8_t TOO_LARGE = 1<<3; // 11110100 1001____ + // 11110100 101_____ + // 11110101 1001____ + // 11110101 101_____ + // 1111011_ 1001____ + // 1111011_ 101_____ + // 11111___ 1001____ + // 11111___ 101_____ + constexpr const uint8_t TOO_LARGE_1000 = 1<<6; + // 11110101 1000____ + // 1111011_ 1000____ + // 11111___ 1000____ + constexpr const uint8_t OVERLONG_4 = 1<<6; // 11110000 1000____ + + const simd8 byte_1_high = prev1.shr<4>().lookup_16( + // 0_______ ________ + TOO_LONG, TOO_LONG, TOO_LONG, TOO_LONG, + TOO_LONG, TOO_LONG, TOO_LONG, TOO_LONG, + // 10______ ________ + TWO_CONTS, TWO_CONTS, TWO_CONTS, TWO_CONTS, + // 1100____ ________ + TOO_SHORT | OVERLONG_2, + // 1101____ ________ + TOO_SHORT, + // 1110____ ________ + TOO_SHORT | OVERLONG_3 | SURROGATE, + // 1111____ ________ + TOO_SHORT | TOO_LARGE | TOO_LARGE_1000 | OVERLONG_4 + ); + constexpr const uint8_t CARRY = TOO_SHORT | TOO_LONG | TWO_CONTS; // These all have ____ in byte 1 . + const simd8 byte_1_low = (prev1 & 0x0F).lookup_16( + // ____0000 ________ + CARRY | OVERLONG_3 | OVERLONG_2 | OVERLONG_4, + // ____0001 ________ + CARRY | OVERLONG_2, + // ____001_ ________ + CARRY, + CARRY, + + // ____0100 ________ + CARRY | TOO_LARGE, + // ____0101 ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + // ____011_ ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + + // ____1___ ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + // ____1101 ________ + CARRY | TOO_LARGE | TOO_LARGE_1000 | SURROGATE, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000 + ); + const simd8 byte_2_high = input.shr<4>().lookup_16( + // ________ 0_______ + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT, + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT, + + // ________ 1000____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | OVERLONG_3 | TOO_LARGE_1000 | OVERLONG_4, + // ________ 1001____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | OVERLONG_3 | TOO_LARGE, + // ________ 101_____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | SURROGATE | TOO_LARGE, + TOO_LONG | OVERLONG_2 | TWO_CONTS | SURROGATE | TOO_LARGE, + + // ________ 11______ + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT + ); + return (byte_1_high & byte_1_low & byte_2_high); + } + simdjson_inline simd8 check_multibyte_lengths(const simd8 input, + const simd8 prev_input, const simd8 sc) { + simd8 prev2 = input.prev<2>(prev_input); + simd8 prev3 = input.prev<3>(prev_input); + simd8 must23 = simd8(must_be_2_3_continuation(prev2, prev3)); + simd8 must23_80 = must23 & uint8_t(0x80); + return must23_80 ^ sc; + } + + // + // Return nonzero if there are incomplete multibyte characters at the end of the block: + // e.g. if there is a 4-byte character, but it's 3 bytes from the end. + // + simdjson_inline simd8 is_incomplete(const simd8 input) { + // If the previous input's last 3 bytes match this, they're too short (they ended at EOF): + // ... 1111____ 111_____ 11______ +#if SIMDJSON_IMPLEMENTATION_ICELAKE + static const uint8_t max_array[64] = { + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 0xf0u-1, 0xe0u-1, 0xc0u-1 + }; +#else + static const uint8_t max_array[32] = { + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 0xf0u-1, 0xe0u-1, 0xc0u-1 + }; +#endif + const simd8 max_value(&max_array[sizeof(max_array)-sizeof(simd8)]); + return input.gt_bits(max_value); + } + + struct utf8_checker { + // If this is nonzero, there has been a UTF-8 error. + simd8 error; + // The last input we received + simd8 prev_input_block; + // Whether the last input we received was incomplete (used for ASCII fast path) + simd8 prev_incomplete; + + // + // Check whether the current bytes are valid UTF-8. + // + simdjson_inline void check_utf8_bytes(const simd8 input, const simd8 prev_input) { + // Flip prev1...prev3 so we can easily determine if they are 2+, 3+ or 4+ lead bytes + // (2, 3, 4-byte leads become large positive numbers instead of small negative numbers) + simd8 prev1 = input.prev<1>(prev_input); + simd8 sc = check_special_cases(input, prev1); + this->error |= check_multibyte_lengths(input, prev_input, sc); + } + + // The only problem that can happen at EOF is that a multibyte character is too short + // or a byte value too large in the last bytes: check_special_cases only checks for bytes + // too large in the first of two bytes. + simdjson_inline void check_eof() { + // If the previous block had incomplete UTF-8 characters at the end, an ASCII block can't + // possibly finish them. + this->error |= this->prev_incomplete; + } + + simdjson_inline void check_next_input(const simd8x64& input) { + if(simdjson_likely(is_ascii(input))) { + this->error |= this->prev_incomplete; + } else { + // you might think that a for-loop would work, but under Visual Studio, it is not good enough. + static_assert((simd8x64::NUM_CHUNKS == 1) + ||(simd8x64::NUM_CHUNKS == 2) + || (simd8x64::NUM_CHUNKS == 4), + "We support one, two or four chunks per 64-byte block."); + SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 1) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + } else SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 2) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + this->check_utf8_bytes(input.chunks[1], input.chunks[0]); + } else SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 4) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + this->check_utf8_bytes(input.chunks[1], input.chunks[0]); + this->check_utf8_bytes(input.chunks[2], input.chunks[1]); + this->check_utf8_bytes(input.chunks[3], input.chunks[2]); + } + this->prev_incomplete = is_incomplete(input.chunks[simd8x64::NUM_CHUNKS-1]); + this->prev_input_block = input.chunks[simd8x64::NUM_CHUNKS-1]; + } + } + // do not forget to call check_eof! + simdjson_inline error_code errors() { + return this->error.any_bits_set_anywhere() ? error_code::UTF8_ERROR : error_code::SUCCESS; + } + + }; // struct utf8_checker +} // namespace utf8_validation + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H +/* end file generic/stage1/utf8_lookup4_algorithm.h for arm64 */ +/* including generic/stage1/json_scanner.h for arm64: #include */ +/* begin file generic/stage1/json_scanner.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace stage1 { + +/** + * A block of scanned json, with information on operators and scalars. + * + * We seek to identify pseudo-structural characters. Anything that is inside + * a string must be omitted (hence & ~_string.string_tail()). + * Otherwise, pseudo-structural characters come in two forms. + * 1. We have the structural characters ([,],{,},:, comma). The + * term 'structural character' is from the JSON RFC. + * 2. We have the 'scalar pseudo-structural characters'. + * Scalars are quotes, and any character except structural characters and white space. + * + * To identify the scalar pseudo-structural characters, we must look at what comes + * before them: it must be a space, a quote or a structural characters. + * Starting with simdjson v0.3, we identify them by + * negation: we identify everything that is followed by a non-quote scalar, + * and we negate that. Whatever remains must be a 'scalar pseudo-structural character'. + */ +struct json_block { +public: + // We spell out the constructors in the hope of resolving inlining issues with Visual Studio 2017 + simdjson_inline json_block(json_string_block&& string, json_character_block characters, uint64_t follows_potential_nonquote_scalar) : + _string(std::move(string)), _characters(characters), _follows_potential_nonquote_scalar(follows_potential_nonquote_scalar) {} + simdjson_inline json_block(json_string_block string, json_character_block characters, uint64_t follows_potential_nonquote_scalar) : + _string(string), _characters(characters), _follows_potential_nonquote_scalar(follows_potential_nonquote_scalar) {} + + /** + * The start of structurals. + * In simdjson prior to v0.3, these were called the pseudo-structural characters. + **/ + simdjson_inline uint64_t structural_start() const noexcept { return potential_structural_start() & ~_string.string_tail(); } + /** All JSON whitespace (i.e. not in a string) */ + simdjson_inline uint64_t whitespace() const noexcept { return non_quote_outside_string(_characters.whitespace()); } + + // Helpers + + /** Whether the given characters are inside a string (only works on non-quotes) */ + simdjson_inline uint64_t non_quote_inside_string(uint64_t mask) const noexcept { return _string.non_quote_inside_string(mask); } + /** Whether the given characters are outside a string (only works on non-quotes) */ + simdjson_inline uint64_t non_quote_outside_string(uint64_t mask) const noexcept { return _string.non_quote_outside_string(mask); } + + // string and escape characters + json_string_block _string; + // whitespace, structural characters ('operators'), scalars + json_character_block _characters; + // whether the previous character was a scalar + uint64_t _follows_potential_nonquote_scalar; +private: + // Potential structurals (i.e. disregarding strings) + + /** + * structural elements ([,],{,},:, comma) plus scalar starts like 123, true and "abc". + * They may reside inside a string. + **/ + simdjson_inline uint64_t potential_structural_start() const noexcept { return _characters.op() | potential_scalar_start(); } + /** + * The start of non-operator runs, like 123, true and "abc". + * It main reside inside a string. + **/ + simdjson_inline uint64_t potential_scalar_start() const noexcept { + // The term "scalar" refers to anything except structural characters and white space + // (so letters, numbers, quotes). + // Whenever it is preceded by something that is not a structural element ({,},[,],:, ") nor a white-space + // then we know that it is irrelevant structurally. + return _characters.scalar() & ~follows_potential_scalar(); + } + /** + * Whether the given character is immediately after a non-operator like 123, true. + * The characters following a quote are not included. + */ + simdjson_inline uint64_t follows_potential_scalar() const noexcept { + // _follows_potential_nonquote_scalar: is defined as marking any character that follows a character + // that is not a structural element ({,},[,],:, comma) nor a quote (") and that is not a + // white space. + // It is understood that within quoted region, anything at all could be marked (irrelevant). + return _follows_potential_nonquote_scalar; + } +}; + +/** + * Scans JSON for important bits: structural characters or 'operators', strings, and scalars. + * + * The scanner starts by calculating two distinct things: + * - string characters (taking \" into account) + * - structural characters or 'operators' ([]{},:, comma) + * and scalars (runs of non-operators like 123, true and "abc") + * + * To minimize data dependency (a key component of the scanner's speed), it finds these in parallel: + * in particular, the operator/scalar bit will find plenty of things that are actually part of + * strings. When we're done, json_block will fuse the two together by masking out tokens that are + * part of a string. + */ +class json_scanner { +public: + json_scanner() = default; + simdjson_inline json_block next(const simd::simd8x64& in); + // Returns either UNCLOSED_STRING or SUCCESS + simdjson_inline error_code finish(); + +private: + // Whether the last character of the previous iteration is part of a scalar token + // (anything except whitespace or a structural character/'operator'). + uint64_t prev_scalar = 0ULL; + json_string_scanner string_scanner{}; +}; + + +// +// Check if the current character immediately follows a matching character. +// +// For example, this checks for quotes with backslashes in front of them: +// +// const uint64_t backslashed_quote = in.eq('"') & immediately_follows(in.eq('\'), prev_backslash); +// +simdjson_inline uint64_t follows(const uint64_t match, uint64_t &overflow) { + const uint64_t result = match << 1 | overflow; + overflow = match >> 63; + return result; +} + +simdjson_inline json_block json_scanner::next(const simd::simd8x64& in) { + json_string_block strings = string_scanner.next(in); + // identifies the white-space and the structural characters + json_character_block characters = json_character_block::classify(in); + // The term "scalar" refers to anything except structural characters and white space + // (so letters, numbers, quotes). + // We want follows_scalar to mark anything that follows a non-quote scalar (so letters and numbers). + // + // A terminal quote should either be followed by a structural character (comma, brace, bracket, colon) + // or nothing. However, we still want ' "a string"true ' to mark the 't' of 'true' as a potential + // pseudo-structural character just like we would if we had ' "a string" true '; otherwise we + // may need to add an extra check when parsing strings. + // + // Performance: there are many ways to skin this cat. + const uint64_t nonquote_scalar = characters.scalar() & ~strings.quote(); + uint64_t follows_nonquote_scalar = follows(nonquote_scalar, prev_scalar); + // We are returning a function-local object so either we get a move constructor + // or we get copy elision. + return json_block( + strings,// strings is a function-local object so either it moves or the copy is elided. + characters, + follows_nonquote_scalar + ); +} + +simdjson_inline error_code json_scanner::finish() { + return string_scanner.finish(); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H +/* end file generic/stage1/json_scanner.h for arm64 */ + +// All other declarations +/* including generic/stage1/find_next_document_index.h for arm64: #include */ +/* begin file generic/stage1/find_next_document_index.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace stage1 { + +/** + * This algorithm is used to quickly identify the last structural position that + * makes up a complete document. + * + * It does this by going backwards and finding the last *document boundary* (a + * place where one value follows another without a comma between them). If the + * last document (the characters after the boundary) has an equal number of + * start and end brackets, it is considered complete. + * + * Simply put, we iterate over the structural characters, starting from + * the end. We consider that we found the end of a JSON document when the + * first element of the pair is NOT one of these characters: '{' '[' ':' ',' + * and when the second element is NOT one of these characters: '}' ']' ':' ','. + * + * This simple comparison works most of the time, but it does not cover cases + * where the batch's structural indexes contain a perfect amount of documents. + * In such a case, we do not have access to the structural index which follows + * the last document, therefore, we do not have access to the second element in + * the pair, and that means we cannot identify the last document. To fix this + * issue, we keep a count of the open and closed curly/square braces we found + * while searching for the pair. When we find a pair AND the count of open and + * closed curly/square braces is the same, we know that we just passed a + * complete document, therefore the last json buffer location is the end of the + * batch. + */ +simdjson_inline uint32_t find_next_document_index(dom_parser_implementation &parser) { + // Variant: do not count separately, just figure out depth + if(parser.n_structural_indexes == 0) { return 0; } + auto arr_cnt = 0; + auto obj_cnt = 0; + for (auto i = parser.n_structural_indexes - 1; i > 0; i--) { + auto idxb = parser.structural_indexes[i]; + switch (parser.buf[idxb]) { + case ':': + case ',': + continue; + case '}': + obj_cnt--; + continue; + case ']': + arr_cnt--; + continue; + case '{': + obj_cnt++; + break; + case '[': + arr_cnt++; + break; + } + auto idxa = parser.structural_indexes[i - 1]; + switch (parser.buf[idxa]) { + case '{': + case '[': + case ':': + case ',': + continue; + } + // Last document is complete, so the next document will appear after! + if (!arr_cnt && !obj_cnt) { + return parser.n_structural_indexes; + } + // Last document is incomplete; mark the document at i + 1 as the next one + return i; + } + // If we made it to the end, we want to finish counting to see if we have a full document. + switch (parser.buf[parser.structural_indexes[0]]) { + case '}': + obj_cnt--; + break; + case ']': + arr_cnt--; + break; + case '{': + obj_cnt++; + break; + case '[': + arr_cnt++; + break; + } + if (!arr_cnt && !obj_cnt) { + // We have a complete document. + return parser.n_structural_indexes; + } + return 0; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H +/* end file generic/stage1/find_next_document_index.h for arm64 */ +/* including generic/stage1/json_minifier.h for arm64: #include */ +/* begin file generic/stage1/json_minifier.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses in stage1 +// It is intended to be included multiple times and compiled multiple times +// We assume the file in which it is included already includes +// "simdjson/stage1.h" (this simplifies amalgation) + +namespace simdjson { +namespace arm64 { +namespace { +namespace stage1 { + +class json_minifier { +public: + template + static error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept; + +private: + simdjson_inline json_minifier(uint8_t *_dst) + : dst{_dst} + {} + template + simdjson_inline void step(const uint8_t *block_buf, buf_block_reader &reader) noexcept; + simdjson_inline void next(const simd::simd8x64& in, const json_block& block); + simdjson_inline error_code finish(uint8_t *dst_start, size_t &dst_len); + json_scanner scanner{}; + uint8_t *dst; +}; + +simdjson_inline void json_minifier::next(const simd::simd8x64& in, const json_block& block) { + uint64_t mask = block.whitespace(); + dst += in.compress(mask, dst); +} + +simdjson_inline error_code json_minifier::finish(uint8_t *dst_start, size_t &dst_len) { + error_code error = scanner.finish(); + if (error) { dst_len = 0; return error; } + dst_len = dst - dst_start; + return SUCCESS; +} + +template<> +simdjson_inline void json_minifier::step<128>(const uint8_t *block_buf, buf_block_reader<128> &reader) noexcept { + simd::simd8x64 in_1(block_buf); + simd::simd8x64 in_2(block_buf+64); + json_block block_1 = scanner.next(in_1); + json_block block_2 = scanner.next(in_2); + this->next(in_1, block_1); + this->next(in_2, block_2); + reader.advance(); +} + +template<> +simdjson_inline void json_minifier::step<64>(const uint8_t *block_buf, buf_block_reader<64> &reader) noexcept { + simd::simd8x64 in_1(block_buf); + json_block block_1 = scanner.next(in_1); + this->next(block_buf, block_1); + reader.advance(); +} + +template +error_code json_minifier::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept { + buf_block_reader reader(buf, len); + json_minifier minifier(dst); + + // Index the first n-1 blocks + while (reader.has_full_block()) { + minifier.step(reader.full_block(), reader); + } + + // Index the last (remainder) block, padded with spaces + uint8_t block[STEP_SIZE]; + size_t remaining_bytes = reader.get_remainder(block); + if (remaining_bytes > 0) { + // We do not want to write directly to the output stream. Rather, we write + // to a local buffer (for safety). + uint8_t out_block[STEP_SIZE]; + uint8_t * const guarded_dst{minifier.dst}; + minifier.dst = out_block; + minifier.step(block, reader); + size_t to_write = minifier.dst - out_block; + // In some cases, we could be enticed to consider the padded spaces + // as part of the string. This is fine as long as we do not write more + // than we consumed. + if(to_write > remaining_bytes) { to_write = remaining_bytes; } + memcpy(guarded_dst, out_block, to_write); + minifier.dst = guarded_dst + to_write; + } + return minifier.finish(dst, dst_len); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H +/* end file generic/stage1/json_minifier.h for arm64 */ +/* including generic/stage1/json_structural_indexer.h for arm64: #include */ +/* begin file generic/stage1/json_structural_indexer.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses in stage1 +// It is intended to be included multiple times and compiled multiple times +// We assume the file in which it is included already includes +// "simdjson/stage1.h" (this simplifies amalgation) + +namespace simdjson { +namespace arm64 { +namespace { +namespace stage1 { + +class bit_indexer { +public: + uint32_t *tail; + + simdjson_inline bit_indexer(uint32_t *index_buf) : tail(index_buf) {} + +#if SIMDJSON_PREFER_REVERSE_BITS + /** + * ARM lacks a fast trailing zero instruction, but it has a fast + * bit reversal instruction and a fast leading zero instruction. + * Thus it may be profitable to reverse the bits (once) and then + * to rely on a sequence of instructions that call the leading + * zero instruction. + * + * Performance notes: + * The chosen routine is not optimal in terms of data dependency + * since zero_leading_bit might require two instructions. However, + * it tends to minimize the total number of instructions which is + * beneficial. + */ + simdjson_inline void write_index(uint32_t idx, uint64_t& rev_bits, int i) { + int lz = leading_zeroes(rev_bits); + this->tail[i] = static_cast(idx) + lz; + rev_bits = zero_leading_bit(rev_bits, lz); + } +#else + /** + * Under recent x64 systems, we often have both a fast trailing zero + * instruction and a fast 'clear-lower-bit' instruction so the following + * algorithm can be competitive. + */ + + simdjson_inline void write_index(uint32_t idx, uint64_t& bits, int i) { + this->tail[i] = idx + trailing_zeroes(bits); + bits = clear_lowest_bit(bits); + } +#endif // SIMDJSON_PREFER_REVERSE_BITS + + template + simdjson_inline int write_indexes(uint32_t idx, uint64_t& bits) { + write_index(idx, bits, START); + SIMDJSON_IF_CONSTEXPR (N > 1) { + write_indexes<(N-1>0?START+1:START), (N-1>=0?N-1:1)>(idx, bits); + } + return START+N; + } + + template + simdjson_inline int write_indexes_stepped(uint32_t idx, uint64_t& bits, int cnt) { + write_indexes(idx, bits); + SIMDJSON_IF_CONSTEXPR ((START+STEP) < END) { + if (simdjson_unlikely((START+STEP) < cnt)) { + write_indexes_stepped<(START+STEP(idx, bits, cnt); + } + } + return ((END-START) % STEP) == 0 ? END : (END-START) - ((END-START) % STEP) + STEP; + } + + // flatten out values in 'bits' assuming that they are are to have values of idx + // plus their position in the bitvector, and store these indexes at + // base_ptr[base] incrementing base as we go + // will potentially store extra values beyond end of valid bits, so base_ptr + // needs to be large enough to handle this + // + // If the kernel sets SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER, then it + // will provide its own version of the code. +#ifdef SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + simdjson_inline void write(uint32_t idx, uint64_t bits); +#else + simdjson_inline void write(uint32_t idx, uint64_t bits) { + // In some instances, the next branch is expensive because it is mispredicted. + // Unfortunately, in other cases, + // it helps tremendously. + if (bits == 0) + return; + + int cnt = static_cast(count_ones(bits)); + +#if SIMDJSON_PREFER_REVERSE_BITS + bits = reverse_bits(bits); +#endif +#ifdef SIMDJSON_STRUCTURAL_INDEXER_STEP + static constexpr const int STEP = SIMDJSON_STRUCTURAL_INDEXER_STEP; +#else + static constexpr const int STEP = 4; +#endif + static constexpr const int STEP_UNTIL = 24; + + write_indexes_stepped<0, STEP_UNTIL, STEP>(idx, bits, cnt); + SIMDJSON_IF_CONSTEXPR (STEP_UNTIL < 64) { + if (simdjson_unlikely(STEP_UNTIL < cnt)) { + for (int i=STEP_UNTIL; itail += cnt; + } +#endif // SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + +}; + +class json_structural_indexer { +public: + /** + * Find the important bits of JSON in a 128-byte chunk, and add them to structural_indexes. + * + * @param partial Setting the partial parameter to true allows the find_structural_bits to + * tolerate unclosed strings. 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 + static error_code index(const uint8_t *buf, size_t len, dom_parser_implementation &parser, stage1_mode partial) noexcept; + +private: + simdjson_inline json_structural_indexer(uint32_t *structural_indexes); + template + simdjson_inline void step(const uint8_t *block, buf_block_reader &reader) noexcept; + simdjson_inline void next(const simd::simd8x64& in, const json_block& block, size_t idx); + simdjson_inline error_code finish(dom_parser_implementation &parser, size_t idx, size_t len, stage1_mode partial); + + json_scanner scanner{}; + utf8_checker checker{}; + bit_indexer indexer; + uint64_t prev_structurals = 0; + uint64_t unescaped_chars_error = 0; +}; + +simdjson_inline json_structural_indexer::json_structural_indexer(uint32_t *structural_indexes) : indexer{structural_indexes} {} + +// Skip the last character if it is partial +simdjson_inline size_t trim_partial_utf8(const uint8_t *buf, size_t len) { + if (simdjson_unlikely(len < 3)) { + switch (len) { + case 2: + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + if (buf[len-2] >= 0xe0) { return len-2; } // 3- and 4-byte characters with only 2 bytes left + return len; + case 1: + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + return len; + case 0: + return len; + } + } + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + if (buf[len-2] >= 0xe0) { return len-2; } // 3- and 4-byte characters with only 1 byte left + if (buf[len-3] >= 0xf0) { return len-3; } // 4-byte characters with only 3 bytes left + return len; +} + +// +// PERF NOTES: +// We pipe 2 inputs through these stages: +// 1. Load JSON into registers. This takes a long time and is highly parallelizable, so we load +// 2 inputs' worth at once so that by the time step 2 is looking for them input, it's available. +// 2. Scan the JSON for critical data: strings, scalars and operators. This is the critical path. +// The output of step 1 depends entirely on this information. These functions don't quite use +// up enough CPU: the second half of the functions is highly serial, only using 1 execution core +// at a time. The second input's scans has some dependency on the first ones finishing it, but +// they can make a lot of progress before they need that information. +// 3. Step 1 doesn't use enough capacity, so we run some extra stuff while we're waiting for that +// to finish: utf-8 checks and generating the output from the last iteration. +// +// The reason we run 2 inputs at a time, is steps 2 and 3 are *still* not enough to soak up all +// available capacity with just one input. Running 2 at a time seems to give the CPU a good enough +// workout. +// +template +error_code json_structural_indexer::index(const uint8_t *buf, size_t len, dom_parser_implementation &parser, stage1_mode partial) noexcept { + if (simdjson_unlikely(len > parser.capacity())) { return CAPACITY; } + // We guard the rest of the code so that we can assume that len > 0 throughout. + if (len == 0) { return EMPTY; } + if (is_streaming(partial)) { + len = trim_partial_utf8(buf, len); + // If you end up with an empty window after trimming + // the partial UTF-8 bytes, then chances are good that you + // have an UTF-8 formatting error. + if(len == 0) { return UTF8_ERROR; } + } + buf_block_reader reader(buf, len); + json_structural_indexer indexer(parser.structural_indexes.get()); + + // Read all but the last block + while (reader.has_full_block()) { + indexer.step(reader.full_block(), reader); + } + // Take care of the last block (will always be there unless file is empty which is + // not supposed to happen.) + uint8_t block[STEP_SIZE]; + if (simdjson_unlikely(reader.get_remainder(block) == 0)) { return UNEXPECTED_ERROR; } + indexer.step(block, reader); + return indexer.finish(parser, reader.block_index(), len, partial); +} + +template<> +simdjson_inline void json_structural_indexer::step<128>(const uint8_t *block, buf_block_reader<128> &reader) noexcept { + simd::simd8x64 in_1(block); + simd::simd8x64 in_2(block+64); + json_block block_1 = scanner.next(in_1); + json_block block_2 = scanner.next(in_2); + this->next(in_1, block_1, reader.block_index()); + this->next(in_2, block_2, reader.block_index()+64); + reader.advance(); +} + +template<> +simdjson_inline void json_structural_indexer::step<64>(const uint8_t *block, buf_block_reader<64> &reader) noexcept { + simd::simd8x64 in_1(block); + json_block block_1 = scanner.next(in_1); + this->next(in_1, block_1, reader.block_index()); + reader.advance(); +} + +simdjson_inline void json_structural_indexer::next(const simd::simd8x64& in, const json_block& block, size_t idx) { + uint64_t unescaped = in.lteq(0x1F); +#if SIMDJSON_UTF8VALIDATION + checker.check_next_input(in); +#endif + indexer.write(uint32_t(idx-64), prev_structurals); // Output *last* iteration's structurals to the parser + prev_structurals = block.structural_start(); + unescaped_chars_error |= block.non_quote_inside_string(unescaped); +} + +simdjson_inline error_code json_structural_indexer::finish(dom_parser_implementation &parser, size_t idx, size_t len, stage1_mode partial) { + // Write out the final iteration's structurals + indexer.write(uint32_t(idx-64), prev_structurals); + error_code error = scanner.finish(); + // We deliberately break down the next expression so that it is + // human readable. + const bool should_we_exit = is_streaming(partial) ? + ((error != SUCCESS) && (error != UNCLOSED_STRING)) // when partial we tolerate UNCLOSED_STRING + : (error != SUCCESS); // if partial is false, we must have SUCCESS + const bool have_unclosed_string = (error == UNCLOSED_STRING); + if (simdjson_unlikely(should_we_exit)) { return error; } + + if (unescaped_chars_error) { + return UNESCAPED_CHARS; + } + parser.n_structural_indexes = uint32_t(indexer.tail - parser.structural_indexes.get()); + /*** + * The On Demand API requires special padding. + * + * This is related to https://github.com/simdjson/simdjson/issues/906 + * Basically, we want to make sure that if the parsing continues beyond the last (valid) + * structural character, it quickly stops. + * Only three structural characters can be repeated without triggering an error in JSON: [,] and }. + * We repeat the padding character (at 'len'). We don't know what it is, but if the parsing + * continues, then it must be [,] or }. + * Suppose it is ] or }. We backtrack to the first character, what could it be that would + * not trigger an error? It could be ] or } but no, because you can't start a document that way. + * It can't be a comma, a colon or any simple value. So the only way we could continue is + * if the repeated character is [. But if so, the document must start with [. But if the document + * starts with [, it should end with ]. If we enforce that rule, then we would get + * ][[ which is invalid. + * + * This is illustrated with the test array_iterate_unclosed_error() on the following input: + * R"({ "a": [,,)" + **/ + parser.structural_indexes[parser.n_structural_indexes] = uint32_t(len); // used later in partial == stage1_mode::streaming_final + parser.structural_indexes[parser.n_structural_indexes + 1] = uint32_t(len); + parser.structural_indexes[parser.n_structural_indexes + 2] = 0; + parser.next_structural_index = 0; + // a valid JSON file cannot have zero structural indexes - we should have found something + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { + return EMPTY; + } + if (simdjson_unlikely(parser.structural_indexes[parser.n_structural_indexes - 1] > len)) { + return UNEXPECTED_ERROR; + } + if (partial == stage1_mode::streaming_partial) { + // If we have an unclosed string, then the last structural + // will be the quote and we want to make sure to omit it. + if(have_unclosed_string) { + parser.n_structural_indexes--; + // a valid JSON file cannot have zero structural indexes - we should have found something + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { return CAPACITY; } + } + // We truncate the input to the end of the last complete document (or zero). + auto new_structural_indexes = find_next_document_index(parser); + if (new_structural_indexes == 0 && parser.n_structural_indexes > 0) { + if(parser.structural_indexes[0] == 0) { + // If the buffer is partial and we started at index 0 but the document is + // incomplete, it's too big to parse. + return CAPACITY; + } else { + // It is possible that the document could be parsed, we just had a lot + // of white space. + parser.n_structural_indexes = 0; + return EMPTY; + } + } + + parser.n_structural_indexes = new_structural_indexes; + } else if (partial == stage1_mode::streaming_final) { + if(have_unclosed_string) { parser.n_structural_indexes--; } + // We truncate the input to the end of the last complete document (or zero). + // Because partial == stage1_mode::streaming_final, it means that we may + // silently ignore trailing garbage. Though it sounds bad, we do it + // deliberately because many people who have streams of JSON documents + // will truncate them for processing. E.g., imagine that you are uncompressing + // the data from a size file or receiving it in chunks from the network. You + // may not know where exactly the last document will be. Meanwhile the + // document_stream instances allow people to know the JSON documents they are + // parsing (see the iterator.source() method). + parser.n_structural_indexes = find_next_document_index(parser); + // We store the initial n_structural_indexes so that the client can see + // whether we used truncation. If initial_n_structural_indexes == parser.n_structural_indexes, + // then this will query parser.structural_indexes[parser.n_structural_indexes] which is len, + // otherwise, it will copy some prior index. + parser.structural_indexes[parser.n_structural_indexes + 1] = parser.structural_indexes[parser.n_structural_indexes]; + // This next line is critical, do not change it unless you understand what you are + // doing. + parser.structural_indexes[parser.n_structural_indexes] = uint32_t(len); + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { + // We tolerate an unclosed string at the very end of the stream. Indeed, users + // often load their data in bulk without being careful and they want us to ignore + // the trailing garbage. + return EMPTY; + } + } + checker.check_eof(); + return checker.errors(); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +// Clear CUSTOM_BIT_INDEXER so other implementations can set it if they need to. +#undef SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H +/* end file generic/stage1/json_structural_indexer.h for arm64 */ +/* including generic/stage1/utf8_validator.h for arm64: #include */ +/* begin file generic/stage1/utf8_validator.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace stage1 { + +/** + * Validates that the string is actual UTF-8. + */ +template +bool generic_validate_utf8(const uint8_t * input, size_t length) { + checker c{}; + buf_block_reader<64> reader(input, length); + while (reader.has_full_block()) { + simd::simd8x64 in(reader.full_block()); + c.check_next_input(in); + reader.advance(); + } + uint8_t block[64]{}; + reader.get_remainder(block); + simd::simd8x64 in(block); + c.check_next_input(in); + reader.advance(); + c.check_eof(); + return c.errors() == error_code::SUCCESS; +} + +bool generic_validate_utf8(const char * input, size_t length) { + return generic_validate_utf8(reinterpret_cast(input),length); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H +/* end file generic/stage1/utf8_validator.h for arm64 */ +/* end file generic/stage1/amalgamated.h for arm64 */ +/* including generic/stage2/amalgamated.h for arm64: #include */ +/* begin file generic/stage2/amalgamated.h for arm64 */ +// Stuff other things depend on +/* including generic/stage2/base.h for arm64: #include */ +/* begin file generic/stage2/base.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace stage2 { + +class json_iterator; +class structural_iterator; +struct tape_builder; +struct tape_writer; + +} // namespace stage2 +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_BASE_H +/* end file generic/stage2/base.h for arm64 */ +/* including generic/stage2/tape_writer.h for arm64: #include */ +/* begin file generic/stage2/tape_writer.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace arm64 { +namespace { +namespace stage2 { + +struct tape_writer { + /** The next place to write to tape */ + uint64_t *next_tape_loc; + + /** Write a signed 64-bit value to tape. */ + simdjson_inline void append_s64(int64_t value) noexcept; + + /** Write an unsigned 64-bit value to tape. */ + simdjson_inline void append_u64(uint64_t value) noexcept; + + /** Write a double value to tape. */ + simdjson_inline void append_double(double value) noexcept; + + /** + * Append a tape entry (an 8-bit type,and 56 bits worth of value). + */ + simdjson_inline void append(uint64_t val, internal::tape_type t) noexcept; + + /** + * Skip the current tape entry without writing. + * + * Used to skip the start of the container, since we'll come back later to fill it in when the + * container ends. + */ + simdjson_inline void skip() noexcept; + + /** + * Skip the number of tape entries necessary to write a large u64 or i64. + */ + simdjson_inline void skip_large_integer() noexcept; + + /** + * Skip the number of tape entries necessary to write a double. + */ + simdjson_inline void skip_double() noexcept; + + /** + * Write a value to a known location on tape. + * + * Used to go back and write out the start of a container after the container ends. + */ + simdjson_inline static void write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept; + +private: + /** + * Append both the tape entry, and a supplementary value following it. Used for types that need + * all 64 bits, such as double and uint64_t. + */ + template + simdjson_inline void append2(uint64_t val, T val2, internal::tape_type t) noexcept; +}; // struct tape_writer + +simdjson_inline void tape_writer::append_s64(int64_t value) noexcept { + append2(0, value, internal::tape_type::INT64); +} + +simdjson_inline void tape_writer::append_u64(uint64_t value) noexcept { + append(0, internal::tape_type::UINT64); + *next_tape_loc = value; + next_tape_loc++; +} + +/** Write a double value to tape. */ +simdjson_inline void tape_writer::append_double(double value) noexcept { + append2(0, value, internal::tape_type::DOUBLE); +} + +simdjson_inline void tape_writer::skip() noexcept { + next_tape_loc++; +} + +simdjson_inline void tape_writer::skip_large_integer() noexcept { + next_tape_loc += 2; +} + +simdjson_inline void tape_writer::skip_double() noexcept { + next_tape_loc += 2; +} + +simdjson_inline void tape_writer::append(uint64_t val, internal::tape_type t) noexcept { + *next_tape_loc = val | ((uint64_t(char(t))) << 56); + next_tape_loc++; +} + +template +simdjson_inline void tape_writer::append2(uint64_t val, T val2, internal::tape_type t) noexcept { + append(val, t); + static_assert(sizeof(val2) == sizeof(*next_tape_loc), "Type is not 64 bits!"); + memcpy(next_tape_loc, &val2, sizeof(val2)); + next_tape_loc++; +} + +simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept { + tape_loc = val | ((uint64_t(char(t))) << 56); +} + +} // namespace stage2 +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H +/* end file generic/stage2/tape_writer.h for arm64 */ +/* including generic/stage2/logger.h for arm64: #include */ +/* begin file generic/stage2/logger.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_LOGGER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_LOGGER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + + +// This is for an internal-only stage 2 specific logger. +// Set LOG_ENABLED = true to log what stage 2 is doing! +namespace simdjson { +namespace arm64 { +namespace { +namespace logger { + + static constexpr const char * DASHES = "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"; + +#if SIMDJSON_VERBOSE_LOGGING + static constexpr const bool LOG_ENABLED = true; +#else + static constexpr const bool LOG_ENABLED = false; +#endif + static constexpr const int LOG_EVENT_LEN = 20; + static constexpr const int LOG_BUFFER_LEN = 30; + static constexpr const int LOG_SMALL_BUFFER_LEN = 10; + static constexpr const int LOG_INDEX_LEN = 5; + + static int log_depth; // Not threadsafe. Log only. + + // Helper to turn unprintable or newline characters into spaces + static simdjson_inline char printable_char(char c) { + if (c >= 0x20) { + return c; + } else { + return ' '; + } + } + + // Print the header and set up log_start + static simdjson_inline void log_start() { + if (LOG_ENABLED) { + log_depth = 0; + printf("\n"); + printf("| %-*s | %-*s | %-*s | %-*s | Detail |\n", LOG_EVENT_LEN, "Event", LOG_BUFFER_LEN, "Buffer", LOG_SMALL_BUFFER_LEN, "Next", 5, "Next#"); + printf("|%.*s|%.*s|%.*s|%.*s|--------|\n", LOG_EVENT_LEN+2, DASHES, LOG_BUFFER_LEN+2, DASHES, LOG_SMALL_BUFFER_LEN+2, DASHES, 5+2, DASHES); + } + } + + simdjson_unused static simdjson_inline void log_string(const char *message) { + if (LOG_ENABLED) { + printf("%s\n", message); + } + } + + // Logs a single line from the stage 2 DOM parser + template + static simdjson_inline void log_line(S &structurals, const char *title_prefix, const char *title, const char *detail) { + if (LOG_ENABLED) { + printf("| %*s%s%-*s ", log_depth*2, "", title_prefix, LOG_EVENT_LEN - log_depth*2 - int(strlen(title_prefix)), title); + auto current_index = structurals.at_beginning() ? nullptr : structurals.next_structural-1; + auto next_index = structurals.next_structural; + auto current = current_index ? &structurals.buf[*current_index] : reinterpret_cast(" "); + auto next = &structurals.buf[*next_index]; + { + // Print the next N characters in the buffer. + printf("| "); + // Otherwise, print the characters starting from the buffer position. + // Print spaces for unprintable or newline characters. + for (int i=0;i */ +/* begin file generic/stage2/json_iterator.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace stage2 { + +class json_iterator { +public: + const uint8_t* const buf; + uint32_t *next_structural; + dom_parser_implementation &dom_parser; + uint32_t depth{0}; + + /** + * Walk the JSON document. + * + * The visitor receives callbacks when values are encountered. All callbacks pass the iterator as + * the first parameter; some callbacks have other parameters as well: + * + * - visit_document_start() - at the beginning. + * - visit_document_end() - at the end (if things were successful). + * + * - visit_array_start() - at the start `[` of a non-empty array. + * - visit_array_end() - at the end `]` of a non-empty array. + * - visit_empty_array() - when an empty array is encountered. + * + * - visit_object_end() - at the start `]` of a non-empty object. + * - visit_object_start() - at the end `]` of a non-empty object. + * - visit_empty_object() - when an empty object is encountered. + * - visit_key(const uint8_t *key) - when a key in an object field is encountered. key is + * guaranteed to point at the first quote of the string (`"key"`). + * - visit_primitive(const uint8_t *value) - when a value is a string, number, boolean or null. + * - visit_root_primitive(iter, uint8_t *value) - when the top-level value is a string, number, boolean or null. + * + * - increment_count(iter) - each time a value is found in an array or object. + */ + template + simdjson_warn_unused simdjson_inline error_code walk_document(V &visitor) noexcept; + + /** + * Create an iterator capable of walking a JSON document. + * + * The document must have already passed through stage 1. + */ + simdjson_inline json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index); + + /** + * Look at the next token. + * + * Tokens can be strings, numbers, booleans, null, or operators (`[{]},:`)). + * + * They may include invalid JSON as well (such as `1.2.3` or `ture`). + */ + simdjson_inline const uint8_t *peek() const noexcept; + /** + * Advance to the next token. + * + * Tokens can be strings, numbers, booleans, null, or operators (`[{]},:`)). + * + * They may include invalid JSON as well (such as `1.2.3` or `ture`). + */ + simdjson_inline const uint8_t *advance() noexcept; + /** + * Get the remaining length of the document, from the start of the current token. + */ + simdjson_inline size_t remaining_len() const noexcept; + /** + * Check if we are at the end of the document. + * + * If this is true, there are no more tokens. + */ + simdjson_inline bool at_eof() const noexcept; + /** + * Check if we are at the beginning of the document. + */ + simdjson_inline bool at_beginning() const noexcept; + simdjson_inline uint8_t last_structural() const noexcept; + + /** + * Log that a value has been found. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_value(const char *type) const noexcept; + /** + * Log the start of a multipart value. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_start_value(const char *type) const noexcept; + /** + * Log the end of a multipart value. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_end_value(const char *type) const noexcept; + /** + * Log an error. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_error(const char *error) const noexcept; + + template + simdjson_warn_unused simdjson_inline error_code visit_root_primitive(V &visitor, const uint8_t *value) noexcept; + template + simdjson_warn_unused simdjson_inline error_code visit_primitive(V &visitor, const uint8_t *value) noexcept; +}; + +template +simdjson_warn_unused simdjson_inline error_code json_iterator::walk_document(V &visitor) noexcept { + logger::log_start(); + + // + // Start the document + // + if (at_eof()) { return EMPTY; } + log_start_value("document"); + SIMDJSON_TRY( visitor.visit_document_start(*this) ); + + // + // Read first value + // + { + auto value = advance(); + + // Make sure the outer object or array is closed before continuing; otherwise, there are ways we + // could get into memory corruption. See https://github.com/simdjson/simdjson/issues/906 + if (!STREAMING) { + switch (*value) { + case '{': if (last_structural() != '}') { log_value("starting brace unmatched"); return TAPE_ERROR; }; break; + case '[': if (last_structural() != ']') { log_value("starting bracket unmatched"); return TAPE_ERROR; }; break; + } + } + + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_root_primitive(*this, value) ); break; + } + } + goto document_end; + +// +// Object parser states +// +object_begin: + log_start_value("object"); + depth++; + if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; } + dom_parser.is_array[depth] = false; + SIMDJSON_TRY( visitor.visit_object_start(*this) ); + + { + auto key = advance(); + if (*key != '"') { log_error("Object does not start with a key"); return TAPE_ERROR; } + SIMDJSON_TRY( visitor.increment_count(*this) ); + SIMDJSON_TRY( visitor.visit_key(*this, key) ); + } + +object_field: + if (simdjson_unlikely( *advance() != ':' )) { log_error("Missing colon after key in object"); return TAPE_ERROR; } + { + auto value = advance(); + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break; + } + } + +object_continue: + switch (*advance()) { + case ',': + SIMDJSON_TRY( visitor.increment_count(*this) ); + { + auto key = advance(); + if (simdjson_unlikely( *key != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; } + SIMDJSON_TRY( visitor.visit_key(*this, key) ); + } + goto object_field; + case '}': log_end_value("object"); SIMDJSON_TRY( visitor.visit_object_end(*this) ); goto scope_end; + default: log_error("No comma between object fields"); return TAPE_ERROR; + } + +scope_end: + depth--; + if (depth == 0) { goto document_end; } + if (dom_parser.is_array[depth]) { goto array_continue; } + goto object_continue; + +// +// Array parser states +// +array_begin: + log_start_value("array"); + depth++; + if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; } + dom_parser.is_array[depth] = true; + SIMDJSON_TRY( visitor.visit_array_start(*this) ); + SIMDJSON_TRY( visitor.increment_count(*this) ); + +array_value: + { + auto value = advance(); + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break; + } + } + +array_continue: + switch (*advance()) { + case ',': SIMDJSON_TRY( visitor.increment_count(*this) ); goto array_value; + case ']': log_end_value("array"); SIMDJSON_TRY( visitor.visit_array_end(*this) ); goto scope_end; + default: log_error("Missing comma between array values"); return TAPE_ERROR; + } + +document_end: + log_end_value("document"); + SIMDJSON_TRY( visitor.visit_document_end(*this) ); + + dom_parser.next_structural_index = uint32_t(next_structural - &dom_parser.structural_indexes[0]); + + // If we didn't make it to the end, it's an error + if ( !STREAMING && dom_parser.next_structural_index != dom_parser.n_structural_indexes ) { + log_error("More than one JSON value at the root of the document, or extra characters at the end of the JSON!"); + return TAPE_ERROR; + } + + return SUCCESS; + +} // walk_document() + +simdjson_inline json_iterator::json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index) + : buf{_dom_parser.buf}, + next_structural{&_dom_parser.structural_indexes[start_structural_index]}, + dom_parser{_dom_parser} { +} + +simdjson_inline const uint8_t *json_iterator::peek() const noexcept { + return &buf[*(next_structural)]; +} +simdjson_inline const uint8_t *json_iterator::advance() noexcept { + return &buf[*(next_structural++)]; +} +simdjson_inline size_t json_iterator::remaining_len() const noexcept { + return dom_parser.len - *(next_structural-1); +} + +simdjson_inline bool json_iterator::at_eof() const noexcept { + return next_structural == &dom_parser.structural_indexes[dom_parser.n_structural_indexes]; +} +simdjson_inline bool json_iterator::at_beginning() const noexcept { + return next_structural == dom_parser.structural_indexes.get(); +} +simdjson_inline uint8_t json_iterator::last_structural() const noexcept { + return buf[dom_parser.structural_indexes[dom_parser.n_structural_indexes - 1]]; +} + +simdjson_inline void json_iterator::log_value(const char *type) const noexcept { + logger::log_line(*this, "", type, ""); +} + +simdjson_inline void json_iterator::log_start_value(const char *type) const noexcept { + logger::log_line(*this, "+", type, ""); + if (logger::LOG_ENABLED) { logger::log_depth++; } +} + +simdjson_inline void json_iterator::log_end_value(const char *type) const noexcept { + if (logger::LOG_ENABLED) { logger::log_depth--; } + logger::log_line(*this, "-", type, ""); +} + +simdjson_inline void json_iterator::log_error(const char *error) const noexcept { + logger::log_line(*this, "", "ERROR", error); +} + +template +simdjson_warn_unused simdjson_inline error_code json_iterator::visit_root_primitive(V &visitor, const uint8_t *value) noexcept { + switch (*value) { + case '"': return visitor.visit_root_string(*this, value); + case 't': return visitor.visit_root_true_atom(*this, value); + case 'f': return visitor.visit_root_false_atom(*this, value); + case 'n': return visitor.visit_root_null_atom(*this, value); + case '-': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return visitor.visit_root_number(*this, value); + default: + log_error("Document starts with a non-value character"); + return TAPE_ERROR; + } +} +template +simdjson_warn_unused simdjson_inline error_code json_iterator::visit_primitive(V &visitor, const uint8_t *value) noexcept { + // Use the fact that most scalars are going to be either strings or numbers. + if(*value == '"') { + return visitor.visit_string(*this, value); + } else if (((*value - '0') < 10) || (*value == '-')) { + return visitor.visit_number(*this, value); + } + // true, false, null are uncommon. + switch (*value) { + case 't': return visitor.visit_true_atom(*this, value); + case 'f': return visitor.visit_false_atom(*this, value); + case 'n': return visitor.visit_null_atom(*this, value); + default: + log_error("Non-value found when value was expected!"); + return TAPE_ERROR; + } +} + +} // namespace stage2 +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H +/* end file generic/stage2/json_iterator.h for arm64 */ +/* including generic/stage2/stringparsing.h for arm64: #include */ +/* begin file generic/stage2/stringparsing.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses +// It is intended to be included multiple times and compiled multiple times + +namespace simdjson { +namespace arm64 { +namespace { +/// @private +namespace stringparsing { + +// begin copypasta +// These chars yield themselves: " \ / +// b -> backspace, f -> formfeed, n -> newline, r -> cr, t -> horizontal tab +// u not handled in this table as it's complex +static const uint8_t escape_map[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0x22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2f, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x4. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5c, 0, 0, 0, // 0x5. + 0, 0, 0x08, 0, 0, 0, 0x0c, 0, 0, 0, 0, 0, 0, 0, 0x0a, 0, // 0x6. + 0, 0, 0x0d, 0, 0x09, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x7. + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +// handle a unicode codepoint +// write appropriate values into dest +// src will advance 6 bytes or 12 bytes +// dest will advance a variable amount (return via pointer) +// return true if the unicode codepoint was valid +// We work in little-endian then swap at write time +simdjson_warn_unused +simdjson_inline bool handle_unicode_codepoint(const uint8_t **src_ptr, + uint8_t **dst_ptr, bool allow_replacement) { + // Use the default Unicode Character 'REPLACEMENT CHARACTER' (U+FFFD) + constexpr uint32_t substitution_code_point = 0xfffd; + // jsoncharutils::hex_to_u32_nocheck fills high 16 bits of the return value with 1s if the + // conversion isn't valid; we defer the check for this to inside the + // multilingual plane check + uint32_t code_point = jsoncharutils::hex_to_u32_nocheck(*src_ptr + 2); + *src_ptr += 6; + + // If we found a high surrogate, we must + // check for low surrogate for characters + // outside the Basic + // Multilingual Plane. + if (code_point >= 0xd800 && code_point < 0xdc00) { + const uint8_t *src_data = *src_ptr; + /* Compiler optimizations convert this to a single 16-bit load and compare on most platforms */ + if (((src_data[0] << 8) | src_data[1]) != ((static_cast ('\\') << 8) | static_cast ('u'))) { + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } else { + uint32_t code_point_2 = jsoncharutils::hex_to_u32_nocheck(src_data + 2); + + // We have already checked that the high surrogate is valid and + // (code_point - 0xd800) < 1024. + // + // Check that code_point_2 is in the range 0xdc00..0xdfff + // and that code_point_2 was parsed from valid hex. + uint32_t low_bit = code_point_2 - 0xdc00; + if (low_bit >> 10) { + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } else { + code_point = (((code_point - 0xd800) << 10) | low_bit) + 0x10000; + *src_ptr += 6; + } + + } + } else if (code_point >= 0xdc00 && code_point <= 0xdfff) { + // If we encounter a low surrogate (not preceded by a high surrogate) + // then we have an error. + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } + size_t offset = jsoncharutils::codepoint_to_utf8(code_point, *dst_ptr); + *dst_ptr += offset; + return offset > 0; +} + + +// handle a unicode codepoint using the wobbly convention +// https://simonsapin.github.io/wtf-8/ +// write appropriate values into dest +// src will advance 6 bytes or 12 bytes +// dest will advance a variable amount (return via pointer) +// return true if the unicode codepoint was valid +// We work in little-endian then swap at write time +simdjson_warn_unused +simdjson_inline bool handle_unicode_codepoint_wobbly(const uint8_t **src_ptr, + uint8_t **dst_ptr) { + // It is not ideal that this function is nearly identical to handle_unicode_codepoint. + // + // jsoncharutils::hex_to_u32_nocheck fills high 16 bits of the return value with 1s if the + // conversion isn't valid; we defer the check for this to inside the + // multilingual plane check + uint32_t code_point = jsoncharutils::hex_to_u32_nocheck(*src_ptr + 2); + *src_ptr += 6; + // If we found a high surrogate, we must + // check for low surrogate for characters + // outside the Basic + // Multilingual Plane. + if (code_point >= 0xd800 && code_point < 0xdc00) { + const uint8_t *src_data = *src_ptr; + /* Compiler optimizations convert this to a single 16-bit load and compare on most platforms */ + if (((src_data[0] << 8) | src_data[1]) == ((static_cast ('\\') << 8) | static_cast ('u'))) { + uint32_t code_point_2 = jsoncharutils::hex_to_u32_nocheck(src_data + 2); + uint32_t low_bit = code_point_2 - 0xdc00; + if ((low_bit >> 10) == 0) { + code_point = + (((code_point - 0xd800) << 10) | low_bit) + 0x10000; + *src_ptr += 6; + } + } + } + + size_t offset = jsoncharutils::codepoint_to_utf8(code_point, *dst_ptr); + *dst_ptr += offset; + return offset > 0; +} + + +/** + * Unescape a valid UTF-8 string from src to dst, stopping at a final unescaped quote. There + * must be an unescaped quote terminating the string. It returns the final output + * position as pointer. In case of error (e.g., the string has bad escaped codes), + * then null_nullptrptr is returned. It is assumed that the output buffer is large + * enough. E.g., if src points at 'joe"', then dst needs to have four free bytes + + * SIMDJSON_PADDING bytes. + */ +simdjson_warn_unused simdjson_inline uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) { + while (1) { + // Copy the next n bytes, and find the backslash and quote in them. + auto bs_quote = backslash_and_quote::copy_and_find(src, dst); + // If the next thing is the end quote, copy and return + if (bs_quote.has_quote_first()) { + // we encountered quotes first. Move dst to point to quotes and exit + return dst + bs_quote.quote_index(); + } + if (bs_quote.has_backslash()) { + /* find out where the backspace is */ + auto bs_dist = bs_quote.backslash_index(); + uint8_t escape_char = src[bs_dist + 1]; + /* we encountered backslash first. Handle backslash */ + if (escape_char == 'u') { + /* move src/dst up to the start; they will be further adjusted + within the unicode codepoint handling code. */ + src += bs_dist; + dst += bs_dist; + if (!handle_unicode_codepoint(&src, &dst, allow_replacement)) { + return nullptr; + } + } else { + /* simple 1:1 conversion. Will eat bs_dist+2 characters in input and + * write bs_dist+1 characters to output + * note this may reach beyond the part of the buffer we've actually + * seen. I think this is ok */ + uint8_t escape_result = escape_map[escape_char]; + if (escape_result == 0u) { + return nullptr; /* bogus escape value is an error */ + } + dst[bs_dist] = escape_result; + src += bs_dist + 2; + dst += bs_dist + 1; + } + } else { + /* they are the same. Since they can't co-occur, it means we + * encountered neither. */ + src += backslash_and_quote::BYTES_PROCESSED; + dst += backslash_and_quote::BYTES_PROCESSED; + } + } +} + +simdjson_warn_unused simdjson_inline uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) { + // It is not ideal that this function is nearly identical to parse_string. + while (1) { + // Copy the next n bytes, and find the backslash and quote in them. + auto bs_quote = backslash_and_quote::copy_and_find(src, dst); + // If the next thing is the end quote, copy and return + if (bs_quote.has_quote_first()) { + // we encountered quotes first. Move dst to point to quotes and exit + return dst + bs_quote.quote_index(); + } + if (bs_quote.has_backslash()) { + /* find out where the backspace is */ + auto bs_dist = bs_quote.backslash_index(); + uint8_t escape_char = src[bs_dist + 1]; + /* we encountered backslash first. Handle backslash */ + if (escape_char == 'u') { + /* move src/dst up to the start; they will be further adjusted + within the unicode codepoint handling code. */ + src += bs_dist; + dst += bs_dist; + if (!handle_unicode_codepoint_wobbly(&src, &dst)) { + return nullptr; + } + } else { + /* simple 1:1 conversion. Will eat bs_dist+2 characters in input and + * write bs_dist+1 characters to output + * note this may reach beyond the part of the buffer we've actually + * seen. I think this is ok */ + uint8_t escape_result = escape_map[escape_char]; + if (escape_result == 0u) { + return nullptr; /* bogus escape value is an error */ + } + dst[bs_dist] = escape_result; + src += bs_dist + 2; + dst += bs_dist + 1; + } + } else { + /* they are the same. Since they can't co-occur, it means we + * encountered neither. */ + src += backslash_and_quote::BYTES_PROCESSED; + dst += backslash_and_quote::BYTES_PROCESSED; + } + } +} + +} // namespace stringparsing +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H +/* end file generic/stage2/stringparsing.h for arm64 */ +/* including generic/stage2/structural_iterator.h for arm64: #include */ +/* begin file generic/stage2/structural_iterator.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace stage2 { + +class structural_iterator { +public: + const uint8_t* const buf; + uint32_t *next_structural; + dom_parser_implementation &dom_parser; + + // Start a structural + simdjson_inline structural_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index) + : buf{_dom_parser.buf}, + next_structural{&_dom_parser.structural_indexes[start_structural_index]}, + dom_parser{_dom_parser} { + } + // Get the buffer position of the current structural character + simdjson_inline const uint8_t* current() { + return &buf[*(next_structural-1)]; + } + // Get the current structural character + simdjson_inline char current_char() { + return buf[*(next_structural-1)]; + } + // Get the next structural character without advancing + simdjson_inline char peek_next_char() { + return buf[*next_structural]; + } + simdjson_inline const uint8_t* peek() { + return &buf[*next_structural]; + } + simdjson_inline const uint8_t* advance() { + return &buf[*(next_structural++)]; + } + simdjson_inline char advance_char() { + return buf[*(next_structural++)]; + } + simdjson_inline size_t remaining_len() { + return dom_parser.len - *(next_structural-1); + } + + simdjson_inline bool at_end() { + return next_structural == &dom_parser.structural_indexes[dom_parser.n_structural_indexes]; + } + simdjson_inline bool at_beginning() { + return next_structural == dom_parser.structural_indexes.get(); + } +}; + +} // namespace stage2 +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H +/* end file generic/stage2/structural_iterator.h for arm64 */ +/* including generic/stage2/tape_builder.h for arm64: #include */ +/* begin file generic/stage2/tape_builder.h for arm64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + + +namespace simdjson { +namespace arm64 { +namespace { +namespace stage2 { + +struct tape_builder { + template + simdjson_warn_unused static simdjson_inline error_code parse_document( + dom_parser_implementation &dom_parser, + dom::document &doc) noexcept; + + /** Called when a non-empty document starts. */ + simdjson_warn_unused simdjson_inline error_code visit_document_start(json_iterator &iter) noexcept; + /** Called when a non-empty document ends without error. */ + simdjson_warn_unused simdjson_inline error_code visit_document_end(json_iterator &iter) noexcept; + + /** Called when a non-empty array starts. */ + simdjson_warn_unused simdjson_inline error_code visit_array_start(json_iterator &iter) noexcept; + /** Called when a non-empty array ends. */ + simdjson_warn_unused simdjson_inline error_code visit_array_end(json_iterator &iter) noexcept; + /** Called when an empty array is found. */ + simdjson_warn_unused simdjson_inline error_code visit_empty_array(json_iterator &iter) noexcept; + + /** Called when a non-empty object starts. */ + simdjson_warn_unused simdjson_inline error_code visit_object_start(json_iterator &iter) noexcept; + /** + * Called when a key in a field is encountered. + * + * primitive, visit_object_start, visit_empty_object, visit_array_start, or visit_empty_array + * will be called after this with the field value. + */ + simdjson_warn_unused simdjson_inline error_code visit_key(json_iterator &iter, const uint8_t *key) noexcept; + /** Called when a non-empty object ends. */ + simdjson_warn_unused simdjson_inline error_code visit_object_end(json_iterator &iter) noexcept; + /** Called when an empty object is found. */ + simdjson_warn_unused simdjson_inline error_code visit_empty_object(json_iterator &iter) noexcept; + + /** + * Called when a string, number, boolean or null is found. + */ + simdjson_warn_unused simdjson_inline error_code visit_primitive(json_iterator &iter, const uint8_t *value) noexcept; + /** + * Called when a string, number, boolean or null is found at the top level of a document (i.e. + * when there is no array or object and the entire document is a single string, number, boolean or + * null. + * + * This is separate from primitive() because simdjson's normal primitive parsing routines assume + * there is at least one more token after the value, which is only true in an array or object. + */ + simdjson_warn_unused simdjson_inline error_code visit_root_primitive(json_iterator &iter, const uint8_t *value) noexcept; + + simdjson_warn_unused simdjson_inline error_code visit_string(json_iterator &iter, const uint8_t *value, bool key = false) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_number(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_true_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_false_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_null_atom(json_iterator &iter, const uint8_t *value) noexcept; + + simdjson_warn_unused simdjson_inline error_code visit_root_string(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_number(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_true_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_false_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_null_atom(json_iterator &iter, const uint8_t *value) noexcept; + + /** Called each time a new field or element in an array or object is found. */ + simdjson_warn_unused simdjson_inline error_code increment_count(json_iterator &iter) noexcept; + + /** Next location to write to tape */ + tape_writer tape; +private: + /** Next write location in the string buf for stage 2 parsing */ + uint8_t *current_string_buf_loc; + + simdjson_inline tape_builder(dom::document &doc) noexcept; + + simdjson_inline uint32_t next_tape_index(json_iterator &iter) const noexcept; + simdjson_inline void start_container(json_iterator &iter) noexcept; + simdjson_warn_unused simdjson_inline error_code end_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept; + simdjson_warn_unused simdjson_inline error_code empty_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept; + simdjson_inline uint8_t *on_start_string(json_iterator &iter) noexcept; + simdjson_inline void on_end_string(uint8_t *dst) noexcept; +}; // struct tape_builder + +template +simdjson_warn_unused simdjson_inline error_code tape_builder::parse_document( + dom_parser_implementation &dom_parser, + dom::document &doc) noexcept { + dom_parser.doc = &doc; + json_iterator iter(dom_parser, STREAMING ? dom_parser.next_structural_index : 0); + tape_builder builder(doc); + return iter.walk_document(builder); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_primitive(json_iterator &iter, const uint8_t *value) noexcept { + return iter.visit_root_primitive(*this, value); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_primitive(json_iterator &iter, const uint8_t *value) noexcept { + return iter.visit_primitive(*this, value); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_empty_object(json_iterator &iter) noexcept { + return empty_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_empty_array(json_iterator &iter) noexcept { + return empty_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_document_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_object_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_array_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_object_end(json_iterator &iter) noexcept { + return end_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_array_end(json_iterator &iter) noexcept { + return end_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_document_end(json_iterator &iter) noexcept { + constexpr uint32_t start_tape_index = 0; + tape.append(start_tape_index, internal::tape_type::ROOT); + tape_writer::write(iter.dom_parser.doc->tape[start_tape_index], next_tape_index(iter), internal::tape_type::ROOT); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_key(json_iterator &iter, const uint8_t *key) noexcept { + return visit_string(iter, key, true); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::increment_count(json_iterator &iter) noexcept { + iter.dom_parser.open_containers[iter.depth].count++; // we have a key value pair in the object at parser.dom_parser.depth - 1 + return SUCCESS; +} + +simdjson_inline tape_builder::tape_builder(dom::document &doc) noexcept : tape{doc.tape.get()}, current_string_buf_loc{doc.string_buf.get()} {} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_string(json_iterator &iter, const uint8_t *value, bool key) noexcept { + iter.log_value(key ? "key" : "string"); + uint8_t *dst = on_start_string(iter); + dst = stringparsing::parse_string(value+1, dst, false); // We do not allow replacement when the escape characters are invalid. + if (dst == nullptr) { + iter.log_error("Invalid escape in string"); + return STRING_ERROR; + } + on_end_string(dst); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(json_iterator &iter, const uint8_t *value) noexcept { + return visit_string(iter, value); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("number"); + return numberparsing::parse_number(value, tape); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept { + // + // We need to make a copy to make sure that the string is space terminated. + // This is not about padding the input, which should already padded up + // to len + SIMDJSON_PADDING. However, we have no control at this stage + // on how the padding was done. What if the input string was padded with nulls? + // It is quite common for an input string to have an extra null character (C string). + // We do not want to allow 9\0 (where \0 is the null character) inside a JSON + // document, but the string "9\0" by itself is fine. So we make a copy and + // pad the input with spaces when we know that there is just one input element. + // This copy is relatively expensive, but it will almost never be called in + // practice unless you are in the strange scenario where you have many JSON + // documents made of single atoms. + // + std::unique_ptrcopy(new (std::nothrow) uint8_t[iter.remaining_len() + SIMDJSON_PADDING]); + if (copy.get() == nullptr) { return MEMALLOC; } + std::memcpy(copy.get(), value, iter.remaining_len()); + std::memset(copy.get() + iter.remaining_len(), ' ', SIMDJSON_PADDING); + error_code error = visit_number(iter, copy.get()); + return error; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_true_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("true"); + if (!atomparsing::is_valid_true_atom(value)) { return T_ATOM_ERROR; } + tape.append(0, internal::tape_type::TRUE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_true_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("true"); + if (!atomparsing::is_valid_true_atom(value, iter.remaining_len())) { return T_ATOM_ERROR; } + tape.append(0, internal::tape_type::TRUE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_false_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("false"); + if (!atomparsing::is_valid_false_atom(value)) { return F_ATOM_ERROR; } + tape.append(0, internal::tape_type::FALSE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_false_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("false"); + if (!atomparsing::is_valid_false_atom(value, iter.remaining_len())) { return F_ATOM_ERROR; } + tape.append(0, internal::tape_type::FALSE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_null_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("null"); + if (!atomparsing::is_valid_null_atom(value)) { return N_ATOM_ERROR; } + tape.append(0, internal::tape_type::NULL_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_null_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("null"); + if (!atomparsing::is_valid_null_atom(value, iter.remaining_len())) { return N_ATOM_ERROR; } + tape.append(0, internal::tape_type::NULL_VALUE); + return SUCCESS; +} + +// private: + +simdjson_inline uint32_t tape_builder::next_tape_index(json_iterator &iter) const noexcept { + return uint32_t(tape.next_tape_loc - iter.dom_parser.doc->tape.get()); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::empty_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept { + auto start_index = next_tape_index(iter); + tape.append(start_index+2, start); + tape.append(start_index, end); + return SUCCESS; +} + +simdjson_inline void tape_builder::start_container(json_iterator &iter) noexcept { + iter.dom_parser.open_containers[iter.depth].tape_index = next_tape_index(iter); + iter.dom_parser.open_containers[iter.depth].count = 0; + tape.skip(); // We don't actually *write* the start element until the end. +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::end_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept { + // Write the ending tape element, pointing at the start location + const uint32_t start_tape_index = iter.dom_parser.open_containers[iter.depth].tape_index; + tape.append(start_tape_index, end); + // Write the start tape element, pointing at the end location (and including count) + // count can overflow if it exceeds 24 bits... so we saturate + // the convention being that a cnt of 0xffffff or more is undetermined in value (>= 0xffffff). + const uint32_t count = iter.dom_parser.open_containers[iter.depth].count; + const uint32_t cntsat = count > 0xFFFFFF ? 0xFFFFFF : count; + tape_writer::write(iter.dom_parser.doc->tape[start_tape_index], next_tape_index(iter) | (uint64_t(cntsat) << 32), start); + return SUCCESS; +} + +simdjson_inline uint8_t *tape_builder::on_start_string(json_iterator &iter) noexcept { + // we advance the point, accounting for the fact that we have a NULL termination + tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::STRING); + return current_string_buf_loc + sizeof(uint32_t); +} + +simdjson_inline void tape_builder::on_end_string(uint8_t *dst) noexcept { + uint32_t str_length = uint32_t(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 + // Currently unneeded because we refuse to parse docs larger or equal to 4GB. + memcpy(current_string_buf_loc, &str_length, sizeof(uint32_t)); + // NULL termination is still handy if you expect all your strings to + // be NULL terminated? It comes at a small cost + *dst = 0; + current_string_buf_loc = dst + 1; +} + +} // namespace stage2 +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H +/* end file generic/stage2/tape_builder.h for arm64 */ +/* end file generic/stage2/amalgamated.h for arm64 */ + +// +// Stage 1 +// +namespace simdjson { +namespace arm64 { + +simdjson_warn_unused error_code implementation::create_dom_parser_implementation( + size_t capacity, + size_t max_depth, + std::unique_ptr& dst +) const noexcept { + dst.reset( new (std::nothrow) dom_parser_implementation() ); + if (!dst) { return MEMALLOC; } + if (auto err = dst->set_capacity(capacity)) + return err; + if (auto err = dst->set_max_depth(max_depth)) + return err; + return SUCCESS; +} + +namespace { + +using namespace simd; + +simdjson_inline json_character_block json_character_block::classify(const simd::simd8x64& in) { + // Functional programming causes trouble with Visual Studio. + // Keeping this version in comments since it is much nicer: + // auto v = in.map([&](simd8 chunk) { + // auto nib_lo = chunk & 0xf; + // auto nib_hi = chunk.shr<4>(); + // auto shuf_lo = nib_lo.lookup_16(16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 12, 1, 2, 9, 0, 0); + // auto shuf_hi = nib_hi.lookup_16(8, 0, 18, 4, 0, 1, 0, 1, 0, 0, 0, 3, 2, 1, 0, 0); + // return shuf_lo & shuf_hi; + // }); + const simd8 table1(16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 12, 1, 2, 9, 0, 0); + const simd8 table2(8, 0, 18, 4, 0, 1, 0, 1, 0, 0, 0, 3, 2, 1, 0, 0); + + simd8x64 v( + (in.chunks[0] & 0xf).lookup_16(table1) & (in.chunks[0].shr<4>()).lookup_16(table2), + (in.chunks[1] & 0xf).lookup_16(table1) & (in.chunks[1].shr<4>()).lookup_16(table2), + (in.chunks[2] & 0xf).lookup_16(table1) & (in.chunks[2].shr<4>()).lookup_16(table2), + (in.chunks[3] & 0xf).lookup_16(table1) & (in.chunks[3].shr<4>()).lookup_16(table2) + ); + + + // We compute whitespace and op separately. If the code later only use one or the + // other, given the fact that all functions are aggressively inlined, we can + // hope that useless computations will be omitted. This is namely case when + // minifying (we only need whitespace). *However* if we only need spaces, + // it is likely that we will still compute 'v' above with two lookup_16: one + // could do it a bit cheaper. This is in contrast with the x64 implementations + // where we can, efficiently, do the white space and structural matching + // separately. One reason for this difference is that on ARM NEON, the table + // lookups either zero or leave unchanged the characters exceeding 0xF whereas + // on x64, the equivalent instruction (pshufb) automatically applies a mask, + // ignoring the 4 most significant bits. Thus the x64 implementation is + // optimized differently. This being said, if you use this code strictly + // just for minification (or just to identify the structural characters), + // there is a small untaken optimization opportunity here. We deliberately + // do not pick it up. + + uint64_t op = simd8x64( + v.chunks[0].any_bits_set(0x7), + v.chunks[1].any_bits_set(0x7), + v.chunks[2].any_bits_set(0x7), + v.chunks[3].any_bits_set(0x7) + ).to_bitmask(); + + uint64_t whitespace = simd8x64( + v.chunks[0].any_bits_set(0x18), + v.chunks[1].any_bits_set(0x18), + v.chunks[2].any_bits_set(0x18), + v.chunks[3].any_bits_set(0x18) + ).to_bitmask(); + + return { whitespace, op }; +} + +simdjson_inline bool is_ascii(const simd8x64& input) { + simd8 bits = input.reduce_or(); + return bits.max_val() < 0x80u; +} + +simdjson_unused simdjson_inline simd8 must_be_continuation(const simd8 prev1, const simd8 prev2, const simd8 prev3) { + simd8 is_second_byte = prev1 >= uint8_t(0xc0u); + simd8 is_third_byte = prev2 >= uint8_t(0xe0u); + simd8 is_fourth_byte = prev3 >= uint8_t(0xf0u); + // Use ^ instead of | for is_*_byte, because ^ is commutative, and the caller is using ^ as well. + // This will work fine because we only have to report errors for cases with 0-1 lead bytes. + // Multiple lead bytes implies 2 overlapping multibyte characters, and if that happens, there is + // guaranteed to be at least *one* lead byte that is part of only 1 other multibyte character. + // The error will be detected there. + return is_second_byte ^ is_third_byte ^ is_fourth_byte; +} + +simdjson_inline simd8 must_be_2_3_continuation(const simd8 prev2, const simd8 prev3) { + simd8 is_third_byte = prev2 >= uint8_t(0xe0u); + simd8 is_fourth_byte = prev3 >= uint8_t(0xf0u); + return is_third_byte ^ is_fourth_byte; +} + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +// +// Stage 2 +// + +// +// Implementation-specific overrides +// +namespace simdjson { +namespace arm64 { + +simdjson_warn_unused error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept { + return arm64::stage1::json_minifier::minify<64>(buf, len, dst, dst_len); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, stage1_mode streaming) noexcept { + this->buf = _buf; + this->len = _len; + return arm64::stage1::json_structural_indexer::index<64>(buf, len, *this, streaming); +} + +simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t len) const noexcept { + return arm64::stage1::generic_validate_utf8(buf,len); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { + return stage2::tape_builder::parse_document(*this, _doc); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { + return stage2::tape_builder::parse_document(*this, _doc); +} + +simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept { + return arm64::stringparsing::parse_string(src, dst, allow_replacement); +} + +simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept { + return arm64::stringparsing::parse_wobbly_string(src, dst); +} + +simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { + auto error = stage1(_buf, _len, stage1_mode::regular); + if (error) { return error; } + return stage2(_doc); +} + +} // namespace arm64 +} // namespace simdjson + +/* including simdjson/arm64/end.h: #include */ +/* begin file simdjson/arm64/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#undef SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT +/* undefining SIMDJSON_IMPLEMENTATION from "arm64" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/arm64/end.h */ + +#endif // SIMDJSON_SRC_ARM64_CPP +/* end file arm64.cpp */ +#endif +#if SIMDJSON_IMPLEMENTATION_FALLBACK +/* including fallback.cpp: #include */ +/* begin file fallback.cpp */ +#ifndef SIMDJSON_SRC_FALLBACK_CPP +#define SIMDJSON_SRC_FALLBACK_CPP + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +/* including simdjson/fallback.h: #include */ +/* begin file simdjson/fallback.h */ +#ifndef SIMDJSON_FALLBACK_H +#define SIMDJSON_FALLBACK_H + +/* including simdjson/fallback/begin.h: #include "simdjson/fallback/begin.h" */ +/* begin file simdjson/fallback/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "fallback" */ +#define SIMDJSON_IMPLEMENTATION fallback +/* including simdjson/fallback/base.h: #include "simdjson/fallback/base.h" */ +/* begin file simdjson/fallback/base.h */ +#ifndef SIMDJSON_FALLBACK_BASE_H +#define SIMDJSON_FALLBACK_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Fallback implementation (runs on any machine). + */ +namespace fallback { + +class implementation; + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_BASE_H +/* end file simdjson/fallback/base.h */ +/* including simdjson/fallback/bitmanipulation.h: #include "simdjson/fallback/bitmanipulation.h" */ +/* begin file simdjson/fallback/bitmanipulation.h */ +#ifndef SIMDJSON_FALLBACK_BITMANIPULATION_H +#define SIMDJSON_FALLBACK_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace { + +#if defined(_MSC_VER) && !defined(_M_ARM64) && !defined(_M_X64) +static inline unsigned char _BitScanForward64(unsigned long* ret, uint64_t x) { + unsigned long x0 = (unsigned long)x, top, bottom; + _BitScanForward(&top, (unsigned long)(x >> 32)); + _BitScanForward(&bottom, x0); + *ret = x0 ? bottom : 32 + top; + return x != 0; +} +static unsigned char _BitScanReverse64(unsigned long* ret, uint64_t x) { + unsigned long x1 = (unsigned long)(x >> 32), top, bottom; + _BitScanReverse(&top, x1); + _BitScanReverse(&bottom, (unsigned long)x); + *ret = x1 ? top + 32 : bottom; + return x != 0; +} +#endif + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#ifdef _MSC_VER + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// _MSC_VER +} + +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_BITMANIPULATION_H +/* end file simdjson/fallback/bitmanipulation.h */ +/* including simdjson/fallback/stringparsing_defs.h: #include "simdjson/fallback/stringparsing_defs.h" */ +/* begin file simdjson/fallback/stringparsing_defs.h */ +#ifndef SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H +#define SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace { + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 1; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return c == '"'; } + simdjson_inline bool has_backslash() { return c == '\\'; } + simdjson_inline int quote_index() { return c == '"' ? 0 : 1; } + simdjson_inline int backslash_index() { return c == '\\' ? 0 : 1; } + + uint8_t c; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // store to dest unconditionally - we can overwrite the bits we don't like later + dst[0] = src[0]; + return { src[0] }; +} + +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H +/* end file simdjson/fallback/stringparsing_defs.h */ +/* including simdjson/fallback/numberparsing_defs.h: #include "simdjson/fallback/numberparsing_defs.h" */ +/* begin file simdjson/fallback/numberparsing_defs.h */ +#ifndef SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H +#define SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +#ifdef JSON_TEST_NUMBERS // for unit testing +void found_invalid_number(const uint8_t *buf); +void found_integer(int64_t result, const uint8_t *buf); +void found_unsigned_integer(uint64_t result, const uint8_t *buf); +void found_float(double result, const uint8_t *buf); +#endif + +namespace simdjson { +namespace fallback { +namespace numberparsing { + +// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const char *chars) { + uint64_t val; + memcpy(&val, chars, sizeof(uint64_t)); + val = (val & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8; + val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16; + return uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32); +} + +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + return parse_eight_digits_unrolled(reinterpret_cast(chars)); +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace fallback +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H +/* end file simdjson/fallback/numberparsing_defs.h */ +/* end file simdjson/fallback/begin.h */ +/* including simdjson/generic/amalgamated.h for fallback: #include "simdjson/generic/amalgamated.h" */ +/* begin file simdjson/generic/amalgamated.h for fallback */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_DEPENDENCIES_H) +#error simdjson/generic/dependencies.h must be included before simdjson/generic/amalgamated.h! +#endif + +/* including simdjson/generic/base.h for fallback: #include "simdjson/generic/base.h" */ +/* begin file simdjson/generic/base.h for fallback */ +#ifndef SIMDJSON_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): // If we haven't got an implementation yet, we're in the editor, editing a generic file! Just */ +/* amalgamation skipped (editor-only): // use the most advanced one we can so the most possible stuff can be tested. */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation_detection.h" */ +/* amalgamation skipped (editor-only): #if SIMDJSON_IMPLEMENTATION_ICELAKE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_HASWELL */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_WESTMERE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_ARM64 */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_PPC64 */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_FALLBACK */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/begin.h" */ +/* amalgamation skipped (editor-only): #else */ +/* amalgamation skipped (editor-only): #error "All possible implementations (including fallback) have been disabled! simdjson will not run." */ +/* amalgamation skipped (editor-only): #endif */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { + +struct open_container; +class dom_parser_implementation; + +/** + * The type of a JSON number + */ +enum class number_type { + floating_point_number=1, /// a binary64 number + signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + unsigned_integer /// a positive integer larger or equal to 1<<63 +}; + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_BASE_H +/* end file simdjson/generic/base.h for fallback */ +/* including simdjson/generic/jsoncharutils.h for fallback: #include "simdjson/generic/jsoncharutils.h" */ +/* begin file simdjson/generic/jsoncharutils.h for fallback */ +#ifndef SIMDJSON_GENERIC_JSONCHARUTILS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_JSONCHARUTILS_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/jsoncharutils_tables.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace { +namespace jsoncharutils { + +// return non-zero if not a structural or whitespace char +// zero otherwise +simdjson_inline uint32_t is_not_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace_negated[c]; +} + +simdjson_inline uint32_t is_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace[c]; +} + +// returns a value with the high 16 bits set if not valid +// otherwise returns the conversion of the 4 hex digits at src into the bottom +// 16 bits of the 32-bit return register +// +// see +// https://lemire.me/blog/2019/04/17/parsing-short-hexadecimal-strings-efficiently/ +static inline uint32_t hex_to_u32_nocheck( + const uint8_t *src) { // strictly speaking, static inline is a C-ism + uint32_t v1 = internal::digit_to_val32[630 + src[0]]; + uint32_t v2 = internal::digit_to_val32[420 + src[1]]; + uint32_t v3 = internal::digit_to_val32[210 + src[2]]; + uint32_t v4 = internal::digit_to_val32[0 + src[3]]; + return v1 | v2 | v3 | v4; +} + +// given a code point cp, writes to c +// the utf-8 code, outputting the length in +// bytes, if the length is zero, the code point +// is invalid +// +// This can possibly be made faster using pdep +// and clz and table lookups, but JSON documents +// have few escaped code points, and the following +// function looks cheap. +// +// Note: we assume that surrogates are treated separately +// +simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) { + if (cp <= 0x7F) { + c[0] = uint8_t(cp); + return 1; // ascii + } + if (cp <= 0x7FF) { + c[0] = uint8_t((cp >> 6) + 192); + c[1] = uint8_t((cp & 63) + 128); + return 2; // universal plane + // Surrogates are treated elsewhere... + //} //else if (0xd800 <= cp && cp <= 0xdfff) { + // return 0; // surrogates // could put assert here + } else if (cp <= 0xFFFF) { + c[0] = uint8_t((cp >> 12) + 224); + c[1] = uint8_t(((cp >> 6) & 63) + 128); + c[2] = uint8_t((cp & 63) + 128); + return 3; + } else if (cp <= 0x10FFFF) { // if you know you have a valid code point, this + // is not needed + c[0] = uint8_t((cp >> 18) + 240); + c[1] = uint8_t(((cp >> 12) & 63) + 128); + c[2] = uint8_t(((cp >> 6) & 63) + 128); + c[3] = uint8_t((cp & 63) + 128); + return 4; + } + // will return 0 when the code point was too large. + return 0; // bad r +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +} // namespace jsoncharutils +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_JSONCHARUTILS_H +/* end file simdjson/generic/jsoncharutils.h for fallback */ +/* including simdjson/generic/atomparsing.h for fallback: #include "simdjson/generic/atomparsing.h" */ +/* begin file simdjson/generic/atomparsing.h for fallback */ +#ifndef SIMDJSON_GENERIC_ATOMPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ATOMPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace fallback { +namespace { +/// @private +namespace atomparsing { + +// The string_to_uint32 is exclusively used to map literal strings to 32-bit values. +// We use memcpy instead of a pointer cast to avoid undefined behaviors since we cannot +// be certain that the character pointer will be properly aligned. +// You might think that using memcpy makes this function expensive, but you'd be wrong. +// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false"); +// to the compile-time constant 1936482662. +simdjson_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; } + + +// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive. +// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about. +simdjson_warn_unused +simdjson_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) { + uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++) + static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes"); + std::memcpy(&srcval, src, sizeof(uint32_t)); + return srcval ^ string_to_uint32(atom); +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src) { + return (str4ncmp(src, "true") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_true_atom(src); } + else if (len == 4) { return !str4ncmp(src, "true"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src) { + return (str4ncmp(src+1, "alse") | jsoncharutils::is_not_structural_or_whitespace(src[5])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src, size_t len) { + if (len > 5) { return is_valid_false_atom(src); } + else if (len == 5) { return !str4ncmp(src+1, "alse"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src) { + return (str4ncmp(src, "null") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_null_atom(src); } + else if (len == 4) { return !str4ncmp(src, "null"); } + else { return false; } +} + +} // namespace atomparsing +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ATOMPARSING_H +/* end file simdjson/generic/atomparsing.h for fallback */ +/* including simdjson/generic/dom_parser_implementation.h for fallback: #include "simdjson/generic/dom_parser_implementation.h" */ +/* begin file simdjson/generic/dom_parser_implementation.h for fallback */ +#ifndef SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { + +// expectation: sizeof(open_container) = 64/8. +struct open_container { + uint32_t tape_index; // where, on the tape, does the scope ([,{) begins + uint32_t count; // how many elements in the scope +}; // struct open_container + +static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits"); + +class dom_parser_implementation final : public internal::dom_parser_implementation { +public: + /** Tape location of each open { or [ */ + std::unique_ptr open_containers{}; + /** Whether each open container is a [ or { */ + std::unique_ptr is_array{}; + /** Buffer passed to stage 1 */ + const uint8_t *buf{}; + /** Length passed to stage 1 */ + size_t len{0}; + /** Document passed to stage 2 */ + dom::document *doc{}; + + inline dom_parser_implementation() noexcept; + inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; + inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; + dom_parser_implementation(const dom_parser_implementation &) = delete; + dom_parser_implementation &operator=(const dom_parser_implementation &) = delete; + + simdjson_warn_unused error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage1(const uint8_t *buf, size_t len, stage1_mode partial) noexcept final; + simdjson_warn_unused error_code stage2(dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage2_next(dom::document &doc) noexcept final; + simdjson_warn_unused uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept final; + simdjson_warn_unused uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept final; + inline simdjson_warn_unused error_code set_capacity(size_t capacity) noexcept final; + inline simdjson_warn_unused error_code set_max_depth(size_t max_depth) noexcept final; +private: + simdjson_inline simdjson_warn_unused error_code set_capacity_stage1(size_t capacity); + +}; + +} // namespace fallback +} // namespace simdjson + +namespace simdjson { +namespace fallback { + +inline dom_parser_implementation::dom_parser_implementation() noexcept = default; +inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; +inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; + +// Leaving these here so they can be inlined if so desired +inline simdjson_warn_unused error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept { + if(capacity > SIMDJSON_MAXSIZE_BYTES) { return CAPACITY; } + // Stage 1 index output + size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7; + structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] ); + if (!structural_indexes) { _capacity = 0; return MEMALLOC; } + structural_indexes[0] = 0; + n_structural_indexes = 0; + + _capacity = capacity; + return SUCCESS; +} + +inline simdjson_warn_unused error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept { + // Stage 2 stacks + open_containers.reset(new (std::nothrow) open_container[max_depth]); + is_array.reset(new (std::nothrow) bool[max_depth]); + if (!is_array || !open_containers) { _max_depth = 0; return MEMALLOC; } + + _max_depth = max_depth; + return SUCCESS; +} + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file simdjson/generic/dom_parser_implementation.h for fallback */ +/* including simdjson/generic/implementation_simdjson_result_base.h for fallback: #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base.h for fallback */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { + +// This is a near copy of include/error.h's implementation_simdjson_result_base, except it doesn't use std::pair +// so we can avoid inlining errors +// TODO reconcile these! +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + * + * This is a base class for implementations that want to add functions to the result type for + * chaining. + * + * Override like: + * + * struct simdjson_result : public internal::implementation_simdjson_result_base { + * simdjson_result() noexcept : internal::implementation_simdjson_result_base() {} + * simdjson_result(error_code error) noexcept : internal::implementation_simdjson_result_base(error) {} + * simdjson_result(T &&value) noexcept : internal::implementation_simdjson_result_base(std::forward(value)) {} + * simdjson_result(T &&value, error_code error) noexcept : internal::implementation_simdjson_result_base(value, error) {} + * // Your extra methods here + * } + * + * Then any method returning simdjson_result will be chainable with your methods. + */ +template +struct implementation_simdjson_result_base { + + /** + * Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline implementation_simdjson_result_base() noexcept = default; + + /** + * Create a new error result. + */ + simdjson_inline implementation_simdjson_result_base(error_code error) noexcept; + + /** + * Create a new successful result. + */ + simdjson_inline implementation_simdjson_result_base(T &&value) noexcept; + + /** + * Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline implementation_simdjson_result_base(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); + + +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T& value_unsafe() & noexcept; + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; +protected: + /** users should never directly access first and second. **/ + T first{}; /** Users should never directly access 'first'. **/ + error_code second{UNINITIALIZED}; /** Users should never directly access 'second'. **/ +}; // struct implementation_simdjson_result_base + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H +/* end file simdjson/generic/implementation_simdjson_result_base.h for fallback */ +/* including simdjson/generic/numberparsing.h for fallback: #include "simdjson/generic/numberparsing.h" */ +/* begin file simdjson/generic/numberparsing.h for fallback */ +#ifndef SIMDJSON_GENERIC_NUMBERPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_NUMBERPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include +#include + +namespace simdjson { +namespace fallback { +namespace numberparsing { + +#ifdef JSON_TEST_NUMBERS +#define INVALID_NUMBER(SRC) (found_invalid_number((SRC)), NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (found_integer((VALUE), (SRC)), (WRITER).append_s64((VALUE))) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (found_unsigned_integer((VALUE), (SRC)), (WRITER).append_u64((VALUE))) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (found_float((VALUE), (SRC)), (WRITER).append_double((VALUE))) +#else +#define INVALID_NUMBER(SRC) (NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (WRITER).append_s64((VALUE)) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (WRITER).append_u64((VALUE)) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (WRITER).append_double((VALUE)) +#endif + +namespace { + +// Convert a mantissa, an exponent and a sign bit into an ieee64 double. +// The real_exponent needs to be in [0, 2046] (technically real_exponent = 2047 would be acceptable). +// The mantissa should be in [0,1<<53). The bit at index (1ULL << 52) while be zeroed. +simdjson_inline double to_double(uint64_t mantissa, uint64_t real_exponent, bool negative) { + double d; + mantissa &= ~(1ULL << 52); + mantissa |= real_exponent << 52; + mantissa |= ((static_cast(negative)) << 63); + std::memcpy(&d, &mantissa, sizeof(d)); + return d; +} + +// Attempts to compute i * 10^(power) exactly; and if "negative" is +// true, negate the result. +// This function will only work in some cases, when it does not work, success is +// set to false. This should work *most of the time* (like 99% of the time). +// We assume that power is in the [smallest_power, +// largest_power] interval: the caller is responsible for this check. +simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative, double &d) { + // we start with a fast path + // It was described in + // Clinger WD. How to read floating point numbers accurately. + // ACM SIGPLAN Notices. 1990 +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + // We cannot be certain that x/y is rounded to nearest. + if (0 <= power && power <= 22 && i <= 9007199254740991) +#else + if (-22 <= power && power <= 22 && i <= 9007199254740991) +#endif + { + // convert the integer into a double. This is lossless since + // 0 <= i <= 2^53 - 1. + d = double(i); + // + // The general idea is as follows. + // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then + // 1) Both s and p can be represented exactly as 64-bit floating-point + // values + // (binary64). + // 2) Because s and p can be represented exactly as floating-point values, + // then s * p + // and s / p will produce correctly rounded values. + // + if (power < 0) { + d = d / simdjson::internal::power_of_ten[-power]; + } else { + d = d * simdjson::internal::power_of_ten[power]; + } + if (negative) { + d = -d; + } + return true; + } + // When 22 < power && power < 22 + 16, we could + // hope for another, secondary fast path. It was + // described by David M. Gay in "Correctly rounded + // binary-decimal and decimal-binary conversions." (1990) + // If you need to compute i * 10^(22 + x) for x < 16, + // first compute i * 10^x, if you know that result is exact + // (e.g., when i * 10^x < 2^53), + // then you can still proceed and do (i * 10^x) * 10^22. + // Is this worth your time? + // You need 22 < power *and* power < 22 + 16 *and* (i * 10^(x-22) < 2^53) + // for this second fast path to work. + // If you you have 22 < power *and* power < 22 + 16, and then you + // optimistically compute "i * 10^(x-22)", there is still a chance that you + // have wasted your time if i * 10^(x-22) >= 2^53. It makes the use cases of + // this optimization maybe less common than we would like. Source: + // http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + // also used in RapidJSON: https://rapidjson.org/strtod_8h_source.html + + // The fast path has now failed, so we are failing back on the slower path. + + // In the slow path, we need to adjust i so that it is > 1<<63 which is always + // possible, except if i == 0, so we handle i == 0 separately. + if(i == 0) { + d = negative ? -0.0 : 0.0; + return true; + } + + + // The exponent is 1024 + 63 + power + // + floor(log(5**power)/log(2)). + // The 1024 comes from the ieee64 standard. + // The 63 comes from the fact that we use a 64-bit word. + // + // Computing floor(log(5**power)/log(2)) could be + // slow. Instead we use a fast function. + // + // For power in (-400,350), we have that + // (((152170 + 65536) * power ) >> 16); + // is equal to + // floor(log(5**power)/log(2)) + power when power >= 0 + // and it is equal to + // ceil(log(5**-power)/log(2)) + power when power < 0 + // + // The 65536 is (1<<16) and corresponds to + // (65536 * power) >> 16 ---> power + // + // ((152170 * power ) >> 16) is equal to + // floor(log(5**power)/log(2)) + // + // Note that this is not magic: 152170/(1<<16) is + // approximatively equal to log(5)/log(2). + // The 1<<16 value is a power of two; we could use a + // larger power of 2 if we wanted to. + // + int64_t exponent = (((152170 + 65536) * power) >> 16) + 1024 + 63; + + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(i); + i <<= lz; + + + // We are going to need to do some 64-bit arithmetic to get a precise product. + // We use a table lookup approach. + // It is safe because + // power >= smallest_power + // and power <= largest_power + // We recover the mantissa of the power, it has a leading 1. It is always + // rounded down. + // + // We want the most significant 64 bits of the product. We know + // this will be non-zero because the most significant bit of i is + // 1. + const uint32_t index = 2 * uint32_t(power - simdjson::internal::smallest_power); + // Optimization: It may be that materializing the index as a variable might confuse some compilers and prevent effective complex-addressing loads. (Done for code clarity.) + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); + // Both i and power_of_five_128[index] have their most significant bit set to 1 which + // implies that the either the most or the second most significant bit of the product + // is 1. We pack values in this manner for efficiency reasons: it maximizes the use + // we make of the product. It also makes it easy to reason about the product: there + // is 0 or 1 leading zero in the product. + + // Unless the least significant 9 bits of the high (64-bit) part of the full + // product are all 1s, then we know that the most significant 55 bits are + // exact and no further work is needed. Having 55 bits is necessary because + // we need 53 bits for the mantissa but we have to have one rounding bit and + // we can waste a bit if the most significant bit of the product is zero. + if((firstproduct.high & 0x1FF) == 0x1FF) { + // We want to compute i * 5^q, but only care about the top 55 bits at most. + // Consider the scenario where q>=0. Then 5^q may not fit in 64-bits. Doing + // the full computation is wasteful. So we do what is called a "truncated + // multiplication". + // We take the most significant 64-bits, and we put them in + // power_of_five_128[index]. Usually, that's good enough to approximate i * 5^q + // to the desired approximation using one multiplication. Sometimes it does not suffice. + // Then we store the next most significant 64 bits in power_of_five_128[index + 1], and + // then we get a better approximation to i * 5^q. + // + // That's for when q>=0. The logic for q<0 is somewhat similar but it is somewhat + // more complicated. + // + // There is an extra layer of complexity in that we need more than 55 bits of + // accuracy in the round-to-even scenario. + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if(secondproduct.high > firstproduct.low) { firstproduct.high++; } + // As it has been proven by Noble Mushtak and Daniel Lemire in "Fast Number Parsing Without + // Fallback" (https://arxiv.org/abs/2212.06644), at this point we are sure that the product + // is sufficiently accurate, and more computation is not needed. + } + uint64_t lower = firstproduct.low; + uint64_t upper = firstproduct.high; + // The final mantissa should be 53 bits with a leading 1. + // We shift it so that it occupies 54 bits with a leading 1. + /////// + uint64_t upperbit = upper >> 63; + uint64_t mantissa = upper >> (upperbit + 9); + lz += int(1 ^ upperbit); + + // Here we have mantissa < (1<<54). + int64_t real_exponent = exponent - lz; + if (simdjson_unlikely(real_exponent <= 0)) { // we have a subnormal? + // Here have that real_exponent <= 0 so -real_exponent >= 0 + if(-real_exponent + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure. + d = negative ? -0.0 : 0.0; + return true; + } + // next line is safe because -real_exponent + 1 < 0 + mantissa >>= -real_exponent + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0. + mantissa += (mantissa & 1); // round up + mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + real_exponent = (mantissa < (uint64_t(1) << 52)) ? 0 : 1; + d = to_double(mantissa, real_exponent, negative); + return true; + } + // We have to round to even. The "to even" part + // is only a problem when we are right in between two floats + // which we guard against. + // If we have lots of trailing zeros, we may fall right between two + // floating-point values. + // + // The round-to-even cases take the form of a number 2m+1 which is in (2^53,2^54] + // times a power of two. That is, it is right between a number with binary significand + // m and another number with binary significand m+1; and it must be the case + // that it cannot be represented by a float itself. + // + // We must have that w * 10 ^q == (2m+1) * 2^p for some power of two 2^p. + // Recall that 10^q = 5^q * 2^q. + // When q >= 0, we must have that (2m+1) is divible by 5^q, so 5^q <= 2^54. We have that + // 5^23 <= 2^54 and it is the last power of five to qualify, so q <= 23. + // When q<0, we have w >= (2m+1) x 5^{-q}. We must have that w<2^{64} so + // (2m+1) x 5^{-q} < 2^{64}. We have that 2m+1>2^{53}. Hence, we must have + // 2^{53} x 5^{-q} < 2^{64}. + // Hence we have 5^{-q} < 2^{11}$ or q>= -4. + // + // We require lower <= 1 and not lower == 0 because we could not prove that + // that lower == 0 is implied; but we could prove that lower <= 1 is a necessary and sufficient test. + if (simdjson_unlikely((lower <= 1) && (power >= -4) && (power <= 23) && ((mantissa & 3) == 1))) { + if((mantissa << (upperbit + 64 - 53 - 2)) == upper) { + mantissa &= ~1; // flip it so that we do not round up + } + } + + mantissa += mantissa & 1; + mantissa >>= 1; + + // Here we have mantissa < (1<<53), unless there was an overflow + if (mantissa >= (1ULL << 53)) { + ////////// + // This will happen when parsing values such as 7.2057594037927933e+16 + //////// + mantissa = (1ULL << 52); + real_exponent++; + } + mantissa &= ~(1ULL << 52); + // we have to check that real_exponent is in range, otherwise we bail out + if (simdjson_unlikely(real_exponent > 2046)) { + // We have an infinite value!!! We could actually throw an error here if we could. + return false; + } + d = to_double(mantissa, real_exponent, negative); + return true; +} + +// We call a fallback floating-point parser that might be slow. Note +// it will accept JSON numbers, but the JSON spec. is more restrictive so +// before you call parse_float_fallback, you need to have validated the input +// string with the JSON grammar. +// It will return an error (false) if the parsed number is infinite. +// The string parsing itself always succeeds. We know that there is at least +// one digit. +static bool parse_float_fallback(const uint8_t *ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +static bool parse_float_fallback(const uint8_t *ptr, const uint8_t *end_ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr), reinterpret_cast(end_ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +// check quickly whether the next 8 chars are made of digits +// at a glance, it looks better than Mula's +// http://0x80.pl/articles/swar-digits-validate.html +simdjson_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) { + uint64_t val; + // this can read up to 7 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(7 <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be bigger than 7"); + std::memcpy(&val, chars, 8); + // a branchy method might be faster: + // return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030) + // && (( (val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0 ) == + // 0x3030303030303030); + return (((val & 0xF0F0F0F0F0F0F0F0) | + (((val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4)) == + 0x3333333333333333); +} + +template +SIMDJSON_NO_SANITIZE_UNDEFINED // We deliberately allow overflow here and check later +simdjson_inline bool parse_digit(const uint8_t c, I &i) { + const uint8_t digit = static_cast(c - '0'); + if (digit > 9) { + return false; + } + // PERF NOTE: multiplication by 10 is cheaper than arbitrary integer multiplication + i = 10 * i + digit; // might overflow, we will handle the overflow later + return true; +} + +simdjson_inline error_code parse_decimal_after_separator(simdjson_unused const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) { + // we continue with the fiction that we have an integer. If the + // floating point number is representable as x * 10^z for some integer + // z that fits in 53 bits, then we will be able to convert back the + // the integer into a float in a lossless manner. + const uint8_t *const first_after_period = p; + +#ifdef SIMDJSON_SWAR_NUMBER_PARSING +#if SIMDJSON_SWAR_NUMBER_PARSING + // this helps if we have lots of decimals! + // this turns out to be frequent enough. + if (is_made_of_eight_digits_fast(p)) { + i = i * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + } +#endif // SIMDJSON_SWAR_NUMBER_PARSING +#endif // #ifdef SIMDJSON_SWAR_NUMBER_PARSING + // Unrolling the first digit makes a small difference on some implementations (e.g. westmere) + if (parse_digit(*p, i)) { ++p; } + while (parse_digit(*p, i)) { p++; } + exponent = first_after_period - p; + // Decimal without digits (123.) is illegal + if (exponent == 0) { + return INVALID_NUMBER(src); + } + return SUCCESS; +} + +simdjson_inline error_code parse_exponent(simdjson_unused const uint8_t *const src, const uint8_t *&p, int64_t &exponent) { + // Exp Sign: -123.456e[-]78 + bool neg_exp = ('-' == *p); + if (neg_exp || '+' == *p) { p++; } // Skip + as well + + // Exponent: -123.456e-[78] + auto start_exp = p; + int64_t exp_number = 0; + while (parse_digit(*p, exp_number)) { ++p; } + // It is possible for parse_digit to overflow. + // In particular, it could overflow to INT64_MIN, and we cannot do - INT64_MIN. + // Thus we *must* check for possible overflow before we negate exp_number. + + // Performance notes: it may seem like combining the two "simdjson_unlikely checks" below into + // a single simdjson_unlikely path would be faster. The reasoning is sound, but the compiler may + // not oblige and may, in fact, generate two distinct paths in any case. It might be + // possible to do uint64_t(p - start_exp - 1) >= 18 but it could end up trading off + // instructions for a simdjson_likely branch, an unconclusive gain. + + // If there were no digits, it's an error. + if (simdjson_unlikely(p == start_exp)) { + return INVALID_NUMBER(src); + } + // We have a valid positive exponent in exp_number at this point, except that + // it may have overflowed. + + // If there were more than 18 digits, we may have overflowed the integer. We have to do + // something!!!! + if (simdjson_unlikely(p > start_exp+18)) { + // Skip leading zeroes: 1e000000000000000000001 is technically valid and doesn't overflow + while (*start_exp == '0') { start_exp++; } + // 19 digits could overflow int64_t and is kind of absurd anyway. We don't + // support exponents smaller than -999,999,999,999,999,999 and bigger + // than 999,999,999,999,999,999. + // We can truncate. + // Note that 999999999999999999 is assuredly too large. The maximal ieee64 value before + // infinity is ~1.8e308. The smallest subnormal is ~5e-324. So, actually, we could + // truncate at 324. + // Note that there is no reason to fail per se at this point in time. + // E.g., 0e999999999999999999999 is a fine number. + if (p > start_exp+18) { exp_number = 999999999999999999; } + } + // At this point, we know that exp_number is a sane, positive, signed integer. + // It is <= 999,999,999,999,999,999. As long as 'exponent' is in + // [-8223372036854775808, 8223372036854775808], we won't overflow. Because 'exponent' + // is bounded in magnitude by the size of the JSON input, we are fine in this universe. + // To sum it up: the next line should never overflow. + exponent += (neg_exp ? -exp_number : exp_number); + return SUCCESS; +} + +simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t digit_count) { + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + const uint8_t *start = start_digits; + while ((*start == '0') || (*start == '.')) { ++start; } + // we over-decrement by one when there is a '.' + return digit_count - size_t(start - start_digits); +} + +} // unnamed namespace + +/** @private */ +static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) { + if (parse_float_fallback(src, answer)) { + return SUCCESS; + } + return INVALID_NUMBER(src); +} + +/** @private */ +template +simdjson_inline error_code write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer) { + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon in practice. + // + // 9999999999999999999 < 2**64 so we can accommodate 19 digits. + // If we have a decimal separator, then digit_count - 1 is the number of digits, but we + // may not have a decimal separator! + if (simdjson_unlikely(digit_count > 19 && significant_digits(start_digits, digit_count) > 19)) { + // Ok, chances are good that we had an overflow! + // this is almost never going to get called!!! + // we start anew, going slowly!!! + // This will happen in the following examples: + // 10000000000000000000000000000000000000000000e+308 + // 3.1415926535897932384626433832795028841971693993751 + // + // NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer + // reference to it, it would force it to be stored in memory, preventing the compiler from + // picking it apart and putting into registers. i.e. if we pass it as reference, + // it gets slow. + double d; + error_code error = slow_float_parsing(src, &d); + writer.append_double(d); + return error; + } + // NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other + // way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331 + // To future reader: we'd love if someone found a better way, or at least could explain this result! + if (simdjson_unlikely(exponent < simdjson::internal::smallest_power) || (exponent > simdjson::internal::largest_power)) { + // + // Important: smallest_power is such that it leads to a zero value. + // Observe that 18446744073709551615e-343 == 0, i.e. (2**64 - 1) e -343 is zero + // so something x 10^-343 goes to zero, but not so with something x 10^-342. + static_assert(simdjson::internal::smallest_power <= -342, "smallest_power is not small enough"); + // + if((exponent < simdjson::internal::smallest_power) || (i == 0)) { + // E.g. Parse "-0.0e-999" into the same value as "-0.0". See https://en.wikipedia.org/wiki/Signed_zero + WRITE_DOUBLE(negative ? -0.0 : 0.0, src, writer); + return SUCCESS; + } else { // (exponent > largest_power) and (i != 0) + // We have, for sure, an infinite value and simdjson refuses to parse infinite values. + return INVALID_NUMBER(src); + } + } + double d; + if (!compute_float_64(exponent, i, negative, d)) { + // we are almost never going to get here. + if (!parse_float_fallback(src, &d)) { return INVALID_NUMBER(src); } + } + WRITE_DOUBLE(d, src, writer); + return SUCCESS; +} + +// for performance analysis, it is sometimes useful to skip parsing +#ifdef SIMDJSON_SKIPNUMBERPARSING + +template +simdjson_inline error_code parse_number(const uint8_t *const, W &writer) { + writer.append_s64(0); // always write zero + return SUCCESS; // always succeeds +} + +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { return number_type::signed_integer; } +#else + +// parse the number at src +// define JSON_TEST_NUMBERS for unit testing +// +// It is assumed that the number is followed by a structural ({,},],[) character +// or a white space character. If that is not the case (e.g., when the JSON +// document is made of a single number), then it is necessary to copy the +// content and append a space before calling this function. +// +// Our objective is accurate parsing (ULP of 0) at high speed. +template +simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) { + + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + if (digit_count == 0 || ('0' == *start_digits && digit_count > 1)) { return INVALID_NUMBER(src); } + + // + // Handle floats if there is a . or e (or both) + // + int64_t exponent = 0; + bool is_float = false; + if ('.' == *p) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) ); + digit_count = int(p - start_digits); // used later to guard against overflows + } + if (('e' == *p) || ('E' == *p)) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_exponent(src, p, exponent) ); + } + if (is_float) { + const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p); + SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) ); + if (dirty_end) { return INVALID_NUMBER(src); } + return SUCCESS; + } + + // The longest negative 64-bit number is 19 digits. + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + size_t longest_digit_count = negative ? 19 : 20; + if (digit_count > longest_digit_count) { return INVALID_NUMBER(src); } + if (digit_count == longest_digit_count) { + if (negative) { + // Anything negative above INT64_MAX+1 is invalid + if (i > uint64_t(INT64_MAX)+1) { return INVALID_NUMBER(src); } + WRITE_INTEGER(~i+1, src, writer); + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + } else if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INVALID_NUMBER(src); } + } + + // Write unsigned if it doesn't fit in a signed integer. + if (i > uint64_t(INT64_MAX)) { + WRITE_UNSIGNED(i, src, writer); + } else { + WRITE_INTEGER(negative ? (~i+1) : i, src, writer); + } + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; +} + +// Inlineable functions +namespace { + +// This table can be used to characterize the final character of an integer +// string. For JSON structural character and allowable white space characters, +// we return SUCCESS. For 'e', '.' and 'E', we return INCORRECT_TYPE. Otherwise +// we return NUMBER_ERROR. +// Optimization note: we could easily reduce the size of the table by half (to 128) +// at the cost of an extra branch. +// Optimization note: we want the values to use at most 8 bits (not, e.g., 32 bits): +static_assert(error_code(uint8_t(NUMBER_ERROR))== NUMBER_ERROR, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(SUCCESS))== SUCCESS, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(INCORRECT_TYPE))== INCORRECT_TYPE, "bad NUMBER_ERROR cast"); + +const uint8_t integer_string_finisher[256] = { + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, INCORRECT_TYPE, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, SUCCESS, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR}; + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + + +// Parse any number from 0 to 18,446,744,073,709,551,615 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src, const uint8_t * const src_end) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if ((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { + const uint8_t *p = src + 1; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (*p != '"') { return NUMBER_ERROR; } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + // Note: we use src[1] and not src[0] because src[0] is the quote character in this + // instance. + if (src[1] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src, const uint8_t * const src_end) noexcept { + // + // Check for minus sign + // + if(src == src_end) { return NUMBER_ERROR; } + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = src; + uint64_t i = 0; + while (parse_digit(*src, i)) { src++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(src - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*src)) { + // return (*src == '.' || *src == 'e' || *src == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(*src != '"') { return NUMBER_ERROR; } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { + return (*src == '-'); +} + +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { return true; } + return false; +} + +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { + // We have an integer. + // If the number is negative and valid, it must be a signed integer. + if(negative) { return number_type::signed_integer; } + // We want values larger or equal to 9223372036854775808 to be unsigned + // integers, and the other values to be signed integers. + int digit_count = int(p - src); + if(digit_count >= 19) { + const uint8_t * smaller_big_integer = reinterpret_cast("9223372036854775808"); + if((digit_count >= 20) || (memcmp(src, smaller_big_integer, 19) >= 0)) { + return number_type::unsigned_integer; + } + } + return number_type::signed_integer; + } + // Hopefully, we have 'e' or 'E' or '.'. + return number_type::floating_point_number; +} + +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src, const uint8_t * const src_end) noexcept { + if(src == src_end) { return NUMBER_ERROR; } + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + if(p == src_end) { return NUMBER_ERROR; } + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while ((p != src_end) && parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely((p != src_end) && (*p == '.'))) { + p++; + const uint8_t *start_decimal_digits = p; + if ((p == src_end) || !parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = start_digits-src > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if ((p != src_end) && (*p == 'e' || *p == 'E')) { + p++; + if(p == src_end) { return NUMBER_ERROR; } + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while ((p != src_end) && parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (*p != '"') { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +} // unnamed namespace +#endif // SIMDJSON_SKIPNUMBERPARSING + +} // namespace numberparsing + +inline std::ostream& operator<<(std::ostream& out, number_type type) noexcept { + switch (type) { + case number_type::signed_integer: out << "integer in [-9223372036854775808,9223372036854775808)"; break; + case number_type::unsigned_integer: out << "unsigned integer in [9223372036854775808,18446744073709551616)"; break; + case number_type::floating_point_number: out << "floating-point number (binary64)"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_NUMBERPARSING_H +/* end file simdjson/generic/numberparsing.h for fallback */ + +/* including simdjson/generic/implementation_simdjson_result_base-inl.h for fallback: #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { + +// +// internal::implementation_simdjson_result_base inline implementation +// + +template +simdjson_inline void implementation_simdjson_result_base::tie(T &value, error_code &error) && noexcept { + error = this->second; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +simdjson_warn_unused simdjson_inline error_code implementation_simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; +} + +template +simdjson_inline error_code implementation_simdjson_result_base::error() const noexcept { + return this->second; +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& implementation_simdjson_result_base::value() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline T&& implementation_simdjson_result_base::take_value() && noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& implementation_simdjson_result_base::value_unsafe() const& noexcept { + return this->first; +} + +template +simdjson_inline T& implementation_simdjson_result_base::value_unsafe() & noexcept { + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value_unsafe() && noexcept { + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value, error_code error) noexcept + : first{std::forward(value)}, second{error} {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(error_code error) noexcept + : implementation_simdjson_result_base(T{}, error) {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value) noexcept + : implementation_simdjson_result_base(std::forward(value), SUCCESS) {} + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H +/* end file simdjson/generic/implementation_simdjson_result_base-inl.h for fallback */ +/* end file simdjson/generic/amalgamated.h for fallback */ +/* including simdjson/fallback/end.h: #include "simdjson/fallback/end.h" */ +/* begin file simdjson/fallback/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +/* undefining SIMDJSON_IMPLEMENTATION from "fallback" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/fallback/end.h */ + +#endif // SIMDJSON_FALLBACK_H +/* end file simdjson/fallback.h */ +/* including simdjson/fallback/implementation.h: #include */ +/* begin file simdjson/fallback/implementation.h */ +#ifndef SIMDJSON_FALLBACK_IMPLEMENTATION_H +#define SIMDJSON_FALLBACK_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation( + "fallback", + "Generic fallback implementation", + 0 + ) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_IMPLEMENTATION_H +/* end file simdjson/fallback/implementation.h */ + +/* including simdjson/fallback/begin.h: #include */ +/* begin file simdjson/fallback/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "fallback" */ +#define SIMDJSON_IMPLEMENTATION fallback +/* including simdjson/fallback/base.h: #include "simdjson/fallback/base.h" */ +/* begin file simdjson/fallback/base.h */ +#ifndef SIMDJSON_FALLBACK_BASE_H +#define SIMDJSON_FALLBACK_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Fallback implementation (runs on any machine). + */ +namespace fallback { + +class implementation; + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_BASE_H +/* end file simdjson/fallback/base.h */ +/* including simdjson/fallback/bitmanipulation.h: #include "simdjson/fallback/bitmanipulation.h" */ +/* begin file simdjson/fallback/bitmanipulation.h */ +#ifndef SIMDJSON_FALLBACK_BITMANIPULATION_H +#define SIMDJSON_FALLBACK_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace { + +#if defined(_MSC_VER) && !defined(_M_ARM64) && !defined(_M_X64) +static inline unsigned char _BitScanForward64(unsigned long* ret, uint64_t x) { + unsigned long x0 = (unsigned long)x, top, bottom; + _BitScanForward(&top, (unsigned long)(x >> 32)); + _BitScanForward(&bottom, x0); + *ret = x0 ? bottom : 32 + top; + return x != 0; +} +static unsigned char _BitScanReverse64(unsigned long* ret, uint64_t x) { + unsigned long x1 = (unsigned long)(x >> 32), top, bottom; + _BitScanReverse(&top, x1); + _BitScanReverse(&bottom, (unsigned long)x); + *ret = x1 ? top + 32 : bottom; + return x != 0; +} +#endif + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#ifdef _MSC_VER + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// _MSC_VER +} + +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_BITMANIPULATION_H +/* end file simdjson/fallback/bitmanipulation.h */ +/* including simdjson/fallback/stringparsing_defs.h: #include "simdjson/fallback/stringparsing_defs.h" */ +/* begin file simdjson/fallback/stringparsing_defs.h */ +#ifndef SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H +#define SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace { + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 1; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return c == '"'; } + simdjson_inline bool has_backslash() { return c == '\\'; } + simdjson_inline int quote_index() { return c == '"' ? 0 : 1; } + simdjson_inline int backslash_index() { return c == '\\' ? 0 : 1; } + + uint8_t c; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // store to dest unconditionally - we can overwrite the bits we don't like later + dst[0] = src[0]; + return { src[0] }; +} + +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H +/* end file simdjson/fallback/stringparsing_defs.h */ +/* including simdjson/fallback/numberparsing_defs.h: #include "simdjson/fallback/numberparsing_defs.h" */ +/* begin file simdjson/fallback/numberparsing_defs.h */ +#ifndef SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H +#define SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +#ifdef JSON_TEST_NUMBERS // for unit testing +void found_invalid_number(const uint8_t *buf); +void found_integer(int64_t result, const uint8_t *buf); +void found_unsigned_integer(uint64_t result, const uint8_t *buf); +void found_float(double result, const uint8_t *buf); +#endif + +namespace simdjson { +namespace fallback { +namespace numberparsing { + +// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const char *chars) { + uint64_t val; + memcpy(&val, chars, sizeof(uint64_t)); + val = (val & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8; + val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16; + return uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32); +} + +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + return parse_eight_digits_unrolled(reinterpret_cast(chars)); +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace fallback +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H +/* end file simdjson/fallback/numberparsing_defs.h */ +/* end file simdjson/fallback/begin.h */ +/* including generic/stage1/find_next_document_index.h for fallback: #include */ +/* begin file generic/stage1/find_next_document_index.h for fallback */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace { +namespace stage1 { + +/** + * This algorithm is used to quickly identify the last structural position that + * makes up a complete document. + * + * It does this by going backwards and finding the last *document boundary* (a + * place where one value follows another without a comma between them). If the + * last document (the characters after the boundary) has an equal number of + * start and end brackets, it is considered complete. + * + * Simply put, we iterate over the structural characters, starting from + * the end. We consider that we found the end of a JSON document when the + * first element of the pair is NOT one of these characters: '{' '[' ':' ',' + * and when the second element is NOT one of these characters: '}' ']' ':' ','. + * + * This simple comparison works most of the time, but it does not cover cases + * where the batch's structural indexes contain a perfect amount of documents. + * In such a case, we do not have access to the structural index which follows + * the last document, therefore, we do not have access to the second element in + * the pair, and that means we cannot identify the last document. To fix this + * issue, we keep a count of the open and closed curly/square braces we found + * while searching for the pair. When we find a pair AND the count of open and + * closed curly/square braces is the same, we know that we just passed a + * complete document, therefore the last json buffer location is the end of the + * batch. + */ +simdjson_inline uint32_t find_next_document_index(dom_parser_implementation &parser) { + // Variant: do not count separately, just figure out depth + if(parser.n_structural_indexes == 0) { return 0; } + auto arr_cnt = 0; + auto obj_cnt = 0; + for (auto i = parser.n_structural_indexes - 1; i > 0; i--) { + auto idxb = parser.structural_indexes[i]; + switch (parser.buf[idxb]) { + case ':': + case ',': + continue; + case '}': + obj_cnt--; + continue; + case ']': + arr_cnt--; + continue; + case '{': + obj_cnt++; + break; + case '[': + arr_cnt++; + break; + } + auto idxa = parser.structural_indexes[i - 1]; + switch (parser.buf[idxa]) { + case '{': + case '[': + case ':': + case ',': + continue; + } + // Last document is complete, so the next document will appear after! + if (!arr_cnt && !obj_cnt) { + return parser.n_structural_indexes; + } + // Last document is incomplete; mark the document at i + 1 as the next one + return i; + } + // If we made it to the end, we want to finish counting to see if we have a full document. + switch (parser.buf[parser.structural_indexes[0]]) { + case '}': + obj_cnt--; + break; + case ']': + arr_cnt--; + break; + case '{': + obj_cnt++; + break; + case '[': + arr_cnt++; + break; + } + if (!arr_cnt && !obj_cnt) { + // We have a complete document. + return parser.n_structural_indexes; + } + return 0; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H +/* end file generic/stage1/find_next_document_index.h for fallback */ +/* including generic/stage2/stringparsing.h for fallback: #include */ +/* begin file generic/stage2/stringparsing.h for fallback */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses +// It is intended to be included multiple times and compiled multiple times + +namespace simdjson { +namespace fallback { +namespace { +/// @private +namespace stringparsing { + +// begin copypasta +// These chars yield themselves: " \ / +// b -> backspace, f -> formfeed, n -> newline, r -> cr, t -> horizontal tab +// u not handled in this table as it's complex +static const uint8_t escape_map[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0x22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2f, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x4. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5c, 0, 0, 0, // 0x5. + 0, 0, 0x08, 0, 0, 0, 0x0c, 0, 0, 0, 0, 0, 0, 0, 0x0a, 0, // 0x6. + 0, 0, 0x0d, 0, 0x09, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x7. + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +// handle a unicode codepoint +// write appropriate values into dest +// src will advance 6 bytes or 12 bytes +// dest will advance a variable amount (return via pointer) +// return true if the unicode codepoint was valid +// We work in little-endian then swap at write time +simdjson_warn_unused +simdjson_inline bool handle_unicode_codepoint(const uint8_t **src_ptr, + uint8_t **dst_ptr, bool allow_replacement) { + // Use the default Unicode Character 'REPLACEMENT CHARACTER' (U+FFFD) + constexpr uint32_t substitution_code_point = 0xfffd; + // jsoncharutils::hex_to_u32_nocheck fills high 16 bits of the return value with 1s if the + // conversion isn't valid; we defer the check for this to inside the + // multilingual plane check + uint32_t code_point = jsoncharutils::hex_to_u32_nocheck(*src_ptr + 2); + *src_ptr += 6; + + // If we found a high surrogate, we must + // check for low surrogate for characters + // outside the Basic + // Multilingual Plane. + if (code_point >= 0xd800 && code_point < 0xdc00) { + const uint8_t *src_data = *src_ptr; + /* Compiler optimizations convert this to a single 16-bit load and compare on most platforms */ + if (((src_data[0] << 8) | src_data[1]) != ((static_cast ('\\') << 8) | static_cast ('u'))) { + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } else { + uint32_t code_point_2 = jsoncharutils::hex_to_u32_nocheck(src_data + 2); + + // We have already checked that the high surrogate is valid and + // (code_point - 0xd800) < 1024. + // + // Check that code_point_2 is in the range 0xdc00..0xdfff + // and that code_point_2 was parsed from valid hex. + uint32_t low_bit = code_point_2 - 0xdc00; + if (low_bit >> 10) { + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } else { + code_point = (((code_point - 0xd800) << 10) | low_bit) + 0x10000; + *src_ptr += 6; + } + + } + } else if (code_point >= 0xdc00 && code_point <= 0xdfff) { + // If we encounter a low surrogate (not preceded by a high surrogate) + // then we have an error. + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } + size_t offset = jsoncharutils::codepoint_to_utf8(code_point, *dst_ptr); + *dst_ptr += offset; + return offset > 0; +} + + +// handle a unicode codepoint using the wobbly convention +// https://simonsapin.github.io/wtf-8/ +// write appropriate values into dest +// src will advance 6 bytes or 12 bytes +// dest will advance a variable amount (return via pointer) +// return true if the unicode codepoint was valid +// We work in little-endian then swap at write time +simdjson_warn_unused +simdjson_inline bool handle_unicode_codepoint_wobbly(const uint8_t **src_ptr, + uint8_t **dst_ptr) { + // It is not ideal that this function is nearly identical to handle_unicode_codepoint. + // + // jsoncharutils::hex_to_u32_nocheck fills high 16 bits of the return value with 1s if the + // conversion isn't valid; we defer the check for this to inside the + // multilingual plane check + uint32_t code_point = jsoncharutils::hex_to_u32_nocheck(*src_ptr + 2); + *src_ptr += 6; + // If we found a high surrogate, we must + // check for low surrogate for characters + // outside the Basic + // Multilingual Plane. + if (code_point >= 0xd800 && code_point < 0xdc00) { + const uint8_t *src_data = *src_ptr; + /* Compiler optimizations convert this to a single 16-bit load and compare on most platforms */ + if (((src_data[0] << 8) | src_data[1]) == ((static_cast ('\\') << 8) | static_cast ('u'))) { + uint32_t code_point_2 = jsoncharutils::hex_to_u32_nocheck(src_data + 2); + uint32_t low_bit = code_point_2 - 0xdc00; + if ((low_bit >> 10) == 0) { + code_point = + (((code_point - 0xd800) << 10) | low_bit) + 0x10000; + *src_ptr += 6; + } + } + } + + size_t offset = jsoncharutils::codepoint_to_utf8(code_point, *dst_ptr); + *dst_ptr += offset; + return offset > 0; +} + + +/** + * Unescape a valid UTF-8 string from src to dst, stopping at a final unescaped quote. There + * must be an unescaped quote terminating the string. It returns the final output + * position as pointer. In case of error (e.g., the string has bad escaped codes), + * then null_nullptrptr is returned. It is assumed that the output buffer is large + * enough. E.g., if src points at 'joe"', then dst needs to have four free bytes + + * SIMDJSON_PADDING bytes. + */ +simdjson_warn_unused simdjson_inline uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) { + while (1) { + // Copy the next n bytes, and find the backslash and quote in them. + auto bs_quote = backslash_and_quote::copy_and_find(src, dst); + // If the next thing is the end quote, copy and return + if (bs_quote.has_quote_first()) { + // we encountered quotes first. Move dst to point to quotes and exit + return dst + bs_quote.quote_index(); + } + if (bs_quote.has_backslash()) { + /* find out where the backspace is */ + auto bs_dist = bs_quote.backslash_index(); + uint8_t escape_char = src[bs_dist + 1]; + /* we encountered backslash first. Handle backslash */ + if (escape_char == 'u') { + /* move src/dst up to the start; they will be further adjusted + within the unicode codepoint handling code. */ + src += bs_dist; + dst += bs_dist; + if (!handle_unicode_codepoint(&src, &dst, allow_replacement)) { + return nullptr; + } + } else { + /* simple 1:1 conversion. Will eat bs_dist+2 characters in input and + * write bs_dist+1 characters to output + * note this may reach beyond the part of the buffer we've actually + * seen. I think this is ok */ + uint8_t escape_result = escape_map[escape_char]; + if (escape_result == 0u) { + return nullptr; /* bogus escape value is an error */ + } + dst[bs_dist] = escape_result; + src += bs_dist + 2; + dst += bs_dist + 1; + } + } else { + /* they are the same. Since they can't co-occur, it means we + * encountered neither. */ + src += backslash_and_quote::BYTES_PROCESSED; + dst += backslash_and_quote::BYTES_PROCESSED; + } + } +} + +simdjson_warn_unused simdjson_inline uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) { + // It is not ideal that this function is nearly identical to parse_string. + while (1) { + // Copy the next n bytes, and find the backslash and quote in them. + auto bs_quote = backslash_and_quote::copy_and_find(src, dst); + // If the next thing is the end quote, copy and return + if (bs_quote.has_quote_first()) { + // we encountered quotes first. Move dst to point to quotes and exit + return dst + bs_quote.quote_index(); + } + if (bs_quote.has_backslash()) { + /* find out where the backspace is */ + auto bs_dist = bs_quote.backslash_index(); + uint8_t escape_char = src[bs_dist + 1]; + /* we encountered backslash first. Handle backslash */ + if (escape_char == 'u') { + /* move src/dst up to the start; they will be further adjusted + within the unicode codepoint handling code. */ + src += bs_dist; + dst += bs_dist; + if (!handle_unicode_codepoint_wobbly(&src, &dst)) { + return nullptr; + } + } else { + /* simple 1:1 conversion. Will eat bs_dist+2 characters in input and + * write bs_dist+1 characters to output + * note this may reach beyond the part of the buffer we've actually + * seen. I think this is ok */ + uint8_t escape_result = escape_map[escape_char]; + if (escape_result == 0u) { + return nullptr; /* bogus escape value is an error */ + } + dst[bs_dist] = escape_result; + src += bs_dist + 2; + dst += bs_dist + 1; + } + } else { + /* they are the same. Since they can't co-occur, it means we + * encountered neither. */ + src += backslash_and_quote::BYTES_PROCESSED; + dst += backslash_and_quote::BYTES_PROCESSED; + } + } +} + +} // namespace stringparsing +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H +/* end file generic/stage2/stringparsing.h for fallback */ +/* including generic/stage2/logger.h for fallback: #include */ +/* begin file generic/stage2/logger.h for fallback */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_LOGGER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_LOGGER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + + +// This is for an internal-only stage 2 specific logger. +// Set LOG_ENABLED = true to log what stage 2 is doing! +namespace simdjson { +namespace fallback { +namespace { +namespace logger { + + static constexpr const char * DASHES = "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"; + +#if SIMDJSON_VERBOSE_LOGGING + static constexpr const bool LOG_ENABLED = true; +#else + static constexpr const bool LOG_ENABLED = false; +#endif + static constexpr const int LOG_EVENT_LEN = 20; + static constexpr const int LOG_BUFFER_LEN = 30; + static constexpr const int LOG_SMALL_BUFFER_LEN = 10; + static constexpr const int LOG_INDEX_LEN = 5; + + static int log_depth; // Not threadsafe. Log only. + + // Helper to turn unprintable or newline characters into spaces + static simdjson_inline char printable_char(char c) { + if (c >= 0x20) { + return c; + } else { + return ' '; + } + } + + // Print the header and set up log_start + static simdjson_inline void log_start() { + if (LOG_ENABLED) { + log_depth = 0; + printf("\n"); + printf("| %-*s | %-*s | %-*s | %-*s | Detail |\n", LOG_EVENT_LEN, "Event", LOG_BUFFER_LEN, "Buffer", LOG_SMALL_BUFFER_LEN, "Next", 5, "Next#"); + printf("|%.*s|%.*s|%.*s|%.*s|--------|\n", LOG_EVENT_LEN+2, DASHES, LOG_BUFFER_LEN+2, DASHES, LOG_SMALL_BUFFER_LEN+2, DASHES, 5+2, DASHES); + } + } + + simdjson_unused static simdjson_inline void log_string(const char *message) { + if (LOG_ENABLED) { + printf("%s\n", message); + } + } + + // Logs a single line from the stage 2 DOM parser + template + static simdjson_inline void log_line(S &structurals, const char *title_prefix, const char *title, const char *detail) { + if (LOG_ENABLED) { + printf("| %*s%s%-*s ", log_depth*2, "", title_prefix, LOG_EVENT_LEN - log_depth*2 - int(strlen(title_prefix)), title); + auto current_index = structurals.at_beginning() ? nullptr : structurals.next_structural-1; + auto next_index = structurals.next_structural; + auto current = current_index ? &structurals.buf[*current_index] : reinterpret_cast(" "); + auto next = &structurals.buf[*next_index]; + { + // Print the next N characters in the buffer. + printf("| "); + // Otherwise, print the characters starting from the buffer position. + // Print spaces for unprintable or newline characters. + for (int i=0;i */ +/* begin file generic/stage2/json_iterator.h for fallback */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace { +namespace stage2 { + +class json_iterator { +public: + const uint8_t* const buf; + uint32_t *next_structural; + dom_parser_implementation &dom_parser; + uint32_t depth{0}; + + /** + * Walk the JSON document. + * + * The visitor receives callbacks when values are encountered. All callbacks pass the iterator as + * the first parameter; some callbacks have other parameters as well: + * + * - visit_document_start() - at the beginning. + * - visit_document_end() - at the end (if things were successful). + * + * - visit_array_start() - at the start `[` of a non-empty array. + * - visit_array_end() - at the end `]` of a non-empty array. + * - visit_empty_array() - when an empty array is encountered. + * + * - visit_object_end() - at the start `]` of a non-empty object. + * - visit_object_start() - at the end `]` of a non-empty object. + * - visit_empty_object() - when an empty object is encountered. + * - visit_key(const uint8_t *key) - when a key in an object field is encountered. key is + * guaranteed to point at the first quote of the string (`"key"`). + * - visit_primitive(const uint8_t *value) - when a value is a string, number, boolean or null. + * - visit_root_primitive(iter, uint8_t *value) - when the top-level value is a string, number, boolean or null. + * + * - increment_count(iter) - each time a value is found in an array or object. + */ + template + simdjson_warn_unused simdjson_inline error_code walk_document(V &visitor) noexcept; + + /** + * Create an iterator capable of walking a JSON document. + * + * The document must have already passed through stage 1. + */ + simdjson_inline json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index); + + /** + * Look at the next token. + * + * Tokens can be strings, numbers, booleans, null, or operators (`[{]},:`)). + * + * They may include invalid JSON as well (such as `1.2.3` or `ture`). + */ + simdjson_inline const uint8_t *peek() const noexcept; + /** + * Advance to the next token. + * + * Tokens can be strings, numbers, booleans, null, or operators (`[{]},:`)). + * + * They may include invalid JSON as well (such as `1.2.3` or `ture`). + */ + simdjson_inline const uint8_t *advance() noexcept; + /** + * Get the remaining length of the document, from the start of the current token. + */ + simdjson_inline size_t remaining_len() const noexcept; + /** + * Check if we are at the end of the document. + * + * If this is true, there are no more tokens. + */ + simdjson_inline bool at_eof() const noexcept; + /** + * Check if we are at the beginning of the document. + */ + simdjson_inline bool at_beginning() const noexcept; + simdjson_inline uint8_t last_structural() const noexcept; + + /** + * Log that a value has been found. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_value(const char *type) const noexcept; + /** + * Log the start of a multipart value. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_start_value(const char *type) const noexcept; + /** + * Log the end of a multipart value. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_end_value(const char *type) const noexcept; + /** + * Log an error. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_error(const char *error) const noexcept; + + template + simdjson_warn_unused simdjson_inline error_code visit_root_primitive(V &visitor, const uint8_t *value) noexcept; + template + simdjson_warn_unused simdjson_inline error_code visit_primitive(V &visitor, const uint8_t *value) noexcept; +}; + +template +simdjson_warn_unused simdjson_inline error_code json_iterator::walk_document(V &visitor) noexcept { + logger::log_start(); + + // + // Start the document + // + if (at_eof()) { return EMPTY; } + log_start_value("document"); + SIMDJSON_TRY( visitor.visit_document_start(*this) ); + + // + // Read first value + // + { + auto value = advance(); + + // Make sure the outer object or array is closed before continuing; otherwise, there are ways we + // could get into memory corruption. See https://github.com/simdjson/simdjson/issues/906 + if (!STREAMING) { + switch (*value) { + case '{': if (last_structural() != '}') { log_value("starting brace unmatched"); return TAPE_ERROR; }; break; + case '[': if (last_structural() != ']') { log_value("starting bracket unmatched"); return TAPE_ERROR; }; break; + } + } + + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_root_primitive(*this, value) ); break; + } + } + goto document_end; + +// +// Object parser states +// +object_begin: + log_start_value("object"); + depth++; + if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; } + dom_parser.is_array[depth] = false; + SIMDJSON_TRY( visitor.visit_object_start(*this) ); + + { + auto key = advance(); + if (*key != '"') { log_error("Object does not start with a key"); return TAPE_ERROR; } + SIMDJSON_TRY( visitor.increment_count(*this) ); + SIMDJSON_TRY( visitor.visit_key(*this, key) ); + } + +object_field: + if (simdjson_unlikely( *advance() != ':' )) { log_error("Missing colon after key in object"); return TAPE_ERROR; } + { + auto value = advance(); + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break; + } + } + +object_continue: + switch (*advance()) { + case ',': + SIMDJSON_TRY( visitor.increment_count(*this) ); + { + auto key = advance(); + if (simdjson_unlikely( *key != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; } + SIMDJSON_TRY( visitor.visit_key(*this, key) ); + } + goto object_field; + case '}': log_end_value("object"); SIMDJSON_TRY( visitor.visit_object_end(*this) ); goto scope_end; + default: log_error("No comma between object fields"); return TAPE_ERROR; + } + +scope_end: + depth--; + if (depth == 0) { goto document_end; } + if (dom_parser.is_array[depth]) { goto array_continue; } + goto object_continue; + +// +// Array parser states +// +array_begin: + log_start_value("array"); + depth++; + if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; } + dom_parser.is_array[depth] = true; + SIMDJSON_TRY( visitor.visit_array_start(*this) ); + SIMDJSON_TRY( visitor.increment_count(*this) ); + +array_value: + { + auto value = advance(); + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break; + } + } + +array_continue: + switch (*advance()) { + case ',': SIMDJSON_TRY( visitor.increment_count(*this) ); goto array_value; + case ']': log_end_value("array"); SIMDJSON_TRY( visitor.visit_array_end(*this) ); goto scope_end; + default: log_error("Missing comma between array values"); return TAPE_ERROR; + } + +document_end: + log_end_value("document"); + SIMDJSON_TRY( visitor.visit_document_end(*this) ); + + dom_parser.next_structural_index = uint32_t(next_structural - &dom_parser.structural_indexes[0]); + + // If we didn't make it to the end, it's an error + if ( !STREAMING && dom_parser.next_structural_index != dom_parser.n_structural_indexes ) { + log_error("More than one JSON value at the root of the document, or extra characters at the end of the JSON!"); + return TAPE_ERROR; + } + + return SUCCESS; + +} // walk_document() + +simdjson_inline json_iterator::json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index) + : buf{_dom_parser.buf}, + next_structural{&_dom_parser.structural_indexes[start_structural_index]}, + dom_parser{_dom_parser} { +} + +simdjson_inline const uint8_t *json_iterator::peek() const noexcept { + return &buf[*(next_structural)]; +} +simdjson_inline const uint8_t *json_iterator::advance() noexcept { + return &buf[*(next_structural++)]; +} +simdjson_inline size_t json_iterator::remaining_len() const noexcept { + return dom_parser.len - *(next_structural-1); +} + +simdjson_inline bool json_iterator::at_eof() const noexcept { + return next_structural == &dom_parser.structural_indexes[dom_parser.n_structural_indexes]; +} +simdjson_inline bool json_iterator::at_beginning() const noexcept { + return next_structural == dom_parser.structural_indexes.get(); +} +simdjson_inline uint8_t json_iterator::last_structural() const noexcept { + return buf[dom_parser.structural_indexes[dom_parser.n_structural_indexes - 1]]; +} + +simdjson_inline void json_iterator::log_value(const char *type) const noexcept { + logger::log_line(*this, "", type, ""); +} + +simdjson_inline void json_iterator::log_start_value(const char *type) const noexcept { + logger::log_line(*this, "+", type, ""); + if (logger::LOG_ENABLED) { logger::log_depth++; } +} + +simdjson_inline void json_iterator::log_end_value(const char *type) const noexcept { + if (logger::LOG_ENABLED) { logger::log_depth--; } + logger::log_line(*this, "-", type, ""); +} + +simdjson_inline void json_iterator::log_error(const char *error) const noexcept { + logger::log_line(*this, "", "ERROR", error); +} + +template +simdjson_warn_unused simdjson_inline error_code json_iterator::visit_root_primitive(V &visitor, const uint8_t *value) noexcept { + switch (*value) { + case '"': return visitor.visit_root_string(*this, value); + case 't': return visitor.visit_root_true_atom(*this, value); + case 'f': return visitor.visit_root_false_atom(*this, value); + case 'n': return visitor.visit_root_null_atom(*this, value); + case '-': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return visitor.visit_root_number(*this, value); + default: + log_error("Document starts with a non-value character"); + return TAPE_ERROR; + } +} +template +simdjson_warn_unused simdjson_inline error_code json_iterator::visit_primitive(V &visitor, const uint8_t *value) noexcept { + // Use the fact that most scalars are going to be either strings or numbers. + if(*value == '"') { + return visitor.visit_string(*this, value); + } else if (((*value - '0') < 10) || (*value == '-')) { + return visitor.visit_number(*this, value); + } + // true, false, null are uncommon. + switch (*value) { + case 't': return visitor.visit_true_atom(*this, value); + case 'f': return visitor.visit_false_atom(*this, value); + case 'n': return visitor.visit_null_atom(*this, value); + default: + log_error("Non-value found when value was expected!"); + return TAPE_ERROR; + } +} + +} // namespace stage2 +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H +/* end file generic/stage2/json_iterator.h for fallback */ +/* including generic/stage2/tape_writer.h for fallback: #include */ +/* begin file generic/stage2/tape_writer.h for fallback */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace fallback { +namespace { +namespace stage2 { + +struct tape_writer { + /** The next place to write to tape */ + uint64_t *next_tape_loc; + + /** Write a signed 64-bit value to tape. */ + simdjson_inline void append_s64(int64_t value) noexcept; + + /** Write an unsigned 64-bit value to tape. */ + simdjson_inline void append_u64(uint64_t value) noexcept; + + /** Write a double value to tape. */ + simdjson_inline void append_double(double value) noexcept; + + /** + * Append a tape entry (an 8-bit type,and 56 bits worth of value). + */ + simdjson_inline void append(uint64_t val, internal::tape_type t) noexcept; + + /** + * Skip the current tape entry without writing. + * + * Used to skip the start of the container, since we'll come back later to fill it in when the + * container ends. + */ + simdjson_inline void skip() noexcept; + + /** + * Skip the number of tape entries necessary to write a large u64 or i64. + */ + simdjson_inline void skip_large_integer() noexcept; + + /** + * Skip the number of tape entries necessary to write a double. + */ + simdjson_inline void skip_double() noexcept; + + /** + * Write a value to a known location on tape. + * + * Used to go back and write out the start of a container after the container ends. + */ + simdjson_inline static void write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept; + +private: + /** + * Append both the tape entry, and a supplementary value following it. Used for types that need + * all 64 bits, such as double and uint64_t. + */ + template + simdjson_inline void append2(uint64_t val, T val2, internal::tape_type t) noexcept; +}; // struct tape_writer + +simdjson_inline void tape_writer::append_s64(int64_t value) noexcept { + append2(0, value, internal::tape_type::INT64); +} + +simdjson_inline void tape_writer::append_u64(uint64_t value) noexcept { + append(0, internal::tape_type::UINT64); + *next_tape_loc = value; + next_tape_loc++; +} + +/** Write a double value to tape. */ +simdjson_inline void tape_writer::append_double(double value) noexcept { + append2(0, value, internal::tape_type::DOUBLE); +} + +simdjson_inline void tape_writer::skip() noexcept { + next_tape_loc++; +} + +simdjson_inline void tape_writer::skip_large_integer() noexcept { + next_tape_loc += 2; +} + +simdjson_inline void tape_writer::skip_double() noexcept { + next_tape_loc += 2; +} + +simdjson_inline void tape_writer::append(uint64_t val, internal::tape_type t) noexcept { + *next_tape_loc = val | ((uint64_t(char(t))) << 56); + next_tape_loc++; +} + +template +simdjson_inline void tape_writer::append2(uint64_t val, T val2, internal::tape_type t) noexcept { + append(val, t); + static_assert(sizeof(val2) == sizeof(*next_tape_loc), "Type is not 64 bits!"); + memcpy(next_tape_loc, &val2, sizeof(val2)); + next_tape_loc++; +} + +simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept { + tape_loc = val | ((uint64_t(char(t))) << 56); +} + +} // namespace stage2 +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H +/* end file generic/stage2/tape_writer.h for fallback */ +/* including generic/stage2/tape_builder.h for fallback: #include */ +/* begin file generic/stage2/tape_builder.h for fallback */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + + +namespace simdjson { +namespace fallback { +namespace { +namespace stage2 { + +struct tape_builder { + template + simdjson_warn_unused static simdjson_inline error_code parse_document( + dom_parser_implementation &dom_parser, + dom::document &doc) noexcept; + + /** Called when a non-empty document starts. */ + simdjson_warn_unused simdjson_inline error_code visit_document_start(json_iterator &iter) noexcept; + /** Called when a non-empty document ends without error. */ + simdjson_warn_unused simdjson_inline error_code visit_document_end(json_iterator &iter) noexcept; + + /** Called when a non-empty array starts. */ + simdjson_warn_unused simdjson_inline error_code visit_array_start(json_iterator &iter) noexcept; + /** Called when a non-empty array ends. */ + simdjson_warn_unused simdjson_inline error_code visit_array_end(json_iterator &iter) noexcept; + /** Called when an empty array is found. */ + simdjson_warn_unused simdjson_inline error_code visit_empty_array(json_iterator &iter) noexcept; + + /** Called when a non-empty object starts. */ + simdjson_warn_unused simdjson_inline error_code visit_object_start(json_iterator &iter) noexcept; + /** + * Called when a key in a field is encountered. + * + * primitive, visit_object_start, visit_empty_object, visit_array_start, or visit_empty_array + * will be called after this with the field value. + */ + simdjson_warn_unused simdjson_inline error_code visit_key(json_iterator &iter, const uint8_t *key) noexcept; + /** Called when a non-empty object ends. */ + simdjson_warn_unused simdjson_inline error_code visit_object_end(json_iterator &iter) noexcept; + /** Called when an empty object is found. */ + simdjson_warn_unused simdjson_inline error_code visit_empty_object(json_iterator &iter) noexcept; + + /** + * Called when a string, number, boolean or null is found. + */ + simdjson_warn_unused simdjson_inline error_code visit_primitive(json_iterator &iter, const uint8_t *value) noexcept; + /** + * Called when a string, number, boolean or null is found at the top level of a document (i.e. + * when there is no array or object and the entire document is a single string, number, boolean or + * null. + * + * This is separate from primitive() because simdjson's normal primitive parsing routines assume + * there is at least one more token after the value, which is only true in an array or object. + */ + simdjson_warn_unused simdjson_inline error_code visit_root_primitive(json_iterator &iter, const uint8_t *value) noexcept; + + simdjson_warn_unused simdjson_inline error_code visit_string(json_iterator &iter, const uint8_t *value, bool key = false) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_number(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_true_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_false_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_null_atom(json_iterator &iter, const uint8_t *value) noexcept; + + simdjson_warn_unused simdjson_inline error_code visit_root_string(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_number(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_true_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_false_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_null_atom(json_iterator &iter, const uint8_t *value) noexcept; + + /** Called each time a new field or element in an array or object is found. */ + simdjson_warn_unused simdjson_inline error_code increment_count(json_iterator &iter) noexcept; + + /** Next location to write to tape */ + tape_writer tape; +private: + /** Next write location in the string buf for stage 2 parsing */ + uint8_t *current_string_buf_loc; + + simdjson_inline tape_builder(dom::document &doc) noexcept; + + simdjson_inline uint32_t next_tape_index(json_iterator &iter) const noexcept; + simdjson_inline void start_container(json_iterator &iter) noexcept; + simdjson_warn_unused simdjson_inline error_code end_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept; + simdjson_warn_unused simdjson_inline error_code empty_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept; + simdjson_inline uint8_t *on_start_string(json_iterator &iter) noexcept; + simdjson_inline void on_end_string(uint8_t *dst) noexcept; +}; // struct tape_builder + +template +simdjson_warn_unused simdjson_inline error_code tape_builder::parse_document( + dom_parser_implementation &dom_parser, + dom::document &doc) noexcept { + dom_parser.doc = &doc; + json_iterator iter(dom_parser, STREAMING ? dom_parser.next_structural_index : 0); + tape_builder builder(doc); + return iter.walk_document(builder); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_primitive(json_iterator &iter, const uint8_t *value) noexcept { + return iter.visit_root_primitive(*this, value); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_primitive(json_iterator &iter, const uint8_t *value) noexcept { + return iter.visit_primitive(*this, value); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_empty_object(json_iterator &iter) noexcept { + return empty_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_empty_array(json_iterator &iter) noexcept { + return empty_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_document_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_object_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_array_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_object_end(json_iterator &iter) noexcept { + return end_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_array_end(json_iterator &iter) noexcept { + return end_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_document_end(json_iterator &iter) noexcept { + constexpr uint32_t start_tape_index = 0; + tape.append(start_tape_index, internal::tape_type::ROOT); + tape_writer::write(iter.dom_parser.doc->tape[start_tape_index], next_tape_index(iter), internal::tape_type::ROOT); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_key(json_iterator &iter, const uint8_t *key) noexcept { + return visit_string(iter, key, true); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::increment_count(json_iterator &iter) noexcept { + iter.dom_parser.open_containers[iter.depth].count++; // we have a key value pair in the object at parser.dom_parser.depth - 1 + return SUCCESS; +} + +simdjson_inline tape_builder::tape_builder(dom::document &doc) noexcept : tape{doc.tape.get()}, current_string_buf_loc{doc.string_buf.get()} {} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_string(json_iterator &iter, const uint8_t *value, bool key) noexcept { + iter.log_value(key ? "key" : "string"); + uint8_t *dst = on_start_string(iter); + dst = stringparsing::parse_string(value+1, dst, false); // We do not allow replacement when the escape characters are invalid. + if (dst == nullptr) { + iter.log_error("Invalid escape in string"); + return STRING_ERROR; + } + on_end_string(dst); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(json_iterator &iter, const uint8_t *value) noexcept { + return visit_string(iter, value); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("number"); + return numberparsing::parse_number(value, tape); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept { + // + // We need to make a copy to make sure that the string is space terminated. + // This is not about padding the input, which should already padded up + // to len + SIMDJSON_PADDING. However, we have no control at this stage + // on how the padding was done. What if the input string was padded with nulls? + // It is quite common for an input string to have an extra null character (C string). + // We do not want to allow 9\0 (where \0 is the null character) inside a JSON + // document, but the string "9\0" by itself is fine. So we make a copy and + // pad the input with spaces when we know that there is just one input element. + // This copy is relatively expensive, but it will almost never be called in + // practice unless you are in the strange scenario where you have many JSON + // documents made of single atoms. + // + std::unique_ptrcopy(new (std::nothrow) uint8_t[iter.remaining_len() + SIMDJSON_PADDING]); + if (copy.get() == nullptr) { return MEMALLOC; } + std::memcpy(copy.get(), value, iter.remaining_len()); + std::memset(copy.get() + iter.remaining_len(), ' ', SIMDJSON_PADDING); + error_code error = visit_number(iter, copy.get()); + return error; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_true_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("true"); + if (!atomparsing::is_valid_true_atom(value)) { return T_ATOM_ERROR; } + tape.append(0, internal::tape_type::TRUE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_true_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("true"); + if (!atomparsing::is_valid_true_atom(value, iter.remaining_len())) { return T_ATOM_ERROR; } + tape.append(0, internal::tape_type::TRUE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_false_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("false"); + if (!atomparsing::is_valid_false_atom(value)) { return F_ATOM_ERROR; } + tape.append(0, internal::tape_type::FALSE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_false_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("false"); + if (!atomparsing::is_valid_false_atom(value, iter.remaining_len())) { return F_ATOM_ERROR; } + tape.append(0, internal::tape_type::FALSE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_null_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("null"); + if (!atomparsing::is_valid_null_atom(value)) { return N_ATOM_ERROR; } + tape.append(0, internal::tape_type::NULL_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_null_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("null"); + if (!atomparsing::is_valid_null_atom(value, iter.remaining_len())) { return N_ATOM_ERROR; } + tape.append(0, internal::tape_type::NULL_VALUE); + return SUCCESS; +} + +// private: + +simdjson_inline uint32_t tape_builder::next_tape_index(json_iterator &iter) const noexcept { + return uint32_t(tape.next_tape_loc - iter.dom_parser.doc->tape.get()); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::empty_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept { + auto start_index = next_tape_index(iter); + tape.append(start_index+2, start); + tape.append(start_index, end); + return SUCCESS; +} + +simdjson_inline void tape_builder::start_container(json_iterator &iter) noexcept { + iter.dom_parser.open_containers[iter.depth].tape_index = next_tape_index(iter); + iter.dom_parser.open_containers[iter.depth].count = 0; + tape.skip(); // We don't actually *write* the start element until the end. +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::end_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept { + // Write the ending tape element, pointing at the start location + const uint32_t start_tape_index = iter.dom_parser.open_containers[iter.depth].tape_index; + tape.append(start_tape_index, end); + // Write the start tape element, pointing at the end location (and including count) + // count can overflow if it exceeds 24 bits... so we saturate + // the convention being that a cnt of 0xffffff or more is undetermined in value (>= 0xffffff). + const uint32_t count = iter.dom_parser.open_containers[iter.depth].count; + const uint32_t cntsat = count > 0xFFFFFF ? 0xFFFFFF : count; + tape_writer::write(iter.dom_parser.doc->tape[start_tape_index], next_tape_index(iter) | (uint64_t(cntsat) << 32), start); + return SUCCESS; +} + +simdjson_inline uint8_t *tape_builder::on_start_string(json_iterator &iter) noexcept { + // we advance the point, accounting for the fact that we have a NULL termination + tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::STRING); + return current_string_buf_loc + sizeof(uint32_t); +} + +simdjson_inline void tape_builder::on_end_string(uint8_t *dst) noexcept { + uint32_t str_length = uint32_t(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 + // Currently unneeded because we refuse to parse docs larger or equal to 4GB. + memcpy(current_string_buf_loc, &str_length, sizeof(uint32_t)); + // NULL termination is still handy if you expect all your strings to + // be NULL terminated? It comes at a small cost + *dst = 0; + current_string_buf_loc = dst + 1; +} + +} // namespace stage2 +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H +/* end file generic/stage2/tape_builder.h for fallback */ + +// +// Stage 1 +// + +namespace simdjson { +namespace fallback { + +simdjson_warn_unused error_code implementation::create_dom_parser_implementation( + size_t capacity, + size_t max_depth, + std::unique_ptr& dst +) const noexcept { + dst.reset( new (std::nothrow) fallback::dom_parser_implementation() ); + if (!dst) { return MEMALLOC; } + if (auto err = dst->set_capacity(capacity)) + return err; + if (auto err = dst->set_max_depth(max_depth)) + return err; + return SUCCESS; +} + +namespace { +namespace stage1 { + +class structural_scanner { +public: + +simdjson_inline structural_scanner(dom_parser_implementation &_parser, stage1_mode _partial) + : buf{_parser.buf}, + next_structural_index{_parser.structural_indexes.get()}, + parser{_parser}, + len{static_cast(_parser.len)}, + partial{_partial} { +} + +simdjson_inline void add_structural() { + *next_structural_index = idx; + next_structural_index++; +} + +simdjson_inline bool is_continuation(uint8_t c) { + return (c & 0xc0) == 0x80; +} + +simdjson_inline void validate_utf8_character() { + // Continuation + if (simdjson_unlikely((buf[idx] & 0x40) == 0)) { + // extra continuation + error = UTF8_ERROR; + idx++; + return; + } + + // 2-byte + if ((buf[idx] & 0x20) == 0) { + // missing continuation + if (simdjson_unlikely(idx+1 > len || !is_continuation(buf[idx+1]))) { + if (idx+1 > len && is_streaming(partial)) { idx = len; return; } + error = UTF8_ERROR; + idx++; + return; + } + // overlong: 1100000_ 10______ + if (buf[idx] <= 0xc1) { error = UTF8_ERROR; } + idx += 2; + return; + } + + // 3-byte + if ((buf[idx] & 0x10) == 0) { + // missing continuation + if (simdjson_unlikely(idx+2 > len || !is_continuation(buf[idx+1]) || !is_continuation(buf[idx+2]))) { + if (idx+2 > len && is_streaming(partial)) { idx = len; return; } + error = UTF8_ERROR; + idx++; + return; + } + // overlong: 11100000 100_____ ________ + if (buf[idx] == 0xe0 && buf[idx+1] <= 0x9f) { error = UTF8_ERROR; } + // surrogates: U+D800-U+DFFF 11101101 101_____ + if (buf[idx] == 0xed && buf[idx+1] >= 0xa0) { error = UTF8_ERROR; } + idx += 3; + return; + } + + // 4-byte + // missing continuation + if (simdjson_unlikely(idx+3 > len || !is_continuation(buf[idx+1]) || !is_continuation(buf[idx+2]) || !is_continuation(buf[idx+3]))) { + if (idx+2 > len && is_streaming(partial)) { idx = len; return; } + error = UTF8_ERROR; + idx++; + return; + } + // overlong: 11110000 1000____ ________ ________ + if (buf[idx] == 0xf0 && buf[idx+1] <= 0x8f) { error = UTF8_ERROR; } + // too large: > U+10FFFF: + // 11110100 (1001|101_)____ + // 1111(1___|011_|0101) 10______ + // also includes 5, 6, 7 and 8 byte characters: + // 11111___ + if (buf[idx] == 0xf4 && buf[idx+1] >= 0x90) { error = UTF8_ERROR; } + if (buf[idx] >= 0xf5) { error = UTF8_ERROR; } + idx += 4; +} + +// Returns true if the string is unclosed. +simdjson_inline bool validate_string() { + idx++; // skip first quote + while (idx < len && buf[idx] != '"') { + if (buf[idx] == '\\') { + idx += 2; + } else if (simdjson_unlikely(buf[idx] & 0x80)) { + validate_utf8_character(); + } else { + if (buf[idx] < 0x20) { error = UNESCAPED_CHARS; } + idx++; + } + } + if (idx >= len) { return true; } + return false; +} + +simdjson_inline bool is_whitespace_or_operator(uint8_t c) { + switch (c) { + case '{': case '}': case '[': case ']': case ',': case ':': + case ' ': case '\r': case '\n': case '\t': + return true; + default: + return false; + } +} + +// +// Parse the entire input in STEP_SIZE-byte chunks. +// +simdjson_inline error_code scan() { + bool unclosed_string = false; + for (;idx 0) { + if(parser.structural_indexes[0] == 0) { + // If the buffer is partial and we started at index 0 but the document is + // incomplete, it's too big to parse. + return CAPACITY; + } else { + // It is possible that the document could be parsed, we just had a lot + // of white space. + parser.n_structural_indexes = 0; + return EMPTY; + } + } + parser.n_structural_indexes = new_structural_indexes; + } else if(partial == stage1_mode::streaming_final) { + if(unclosed_string) { parser.n_structural_indexes--; } + // We truncate the input to the end of the last complete document (or zero). + // Because partial == stage1_mode::streaming_final, it means that we may + // silently ignore trailing garbage. Though it sounds bad, we do it + // deliberately because many people who have streams of JSON documents + // will truncate them for processing. E.g., imagine that you are uncompressing + // the data from a size file or receiving it in chunks from the network. You + // may not know where exactly the last document will be. Meanwhile the + // document_stream instances allow people to know the JSON documents they are + // parsing (see the iterator.source() method). + parser.n_structural_indexes = find_next_document_index(parser); + // We store the initial n_structural_indexes so that the client can see + // whether we used truncation. If initial_n_structural_indexes == parser.n_structural_indexes, + // then this will query parser.structural_indexes[parser.n_structural_indexes] which is len, + // otherwise, it will copy some prior index. + parser.structural_indexes[parser.n_structural_indexes + 1] = parser.structural_indexes[parser.n_structural_indexes]; + // This next line is critical, do not change it unless you understand what you are + // doing. + parser.structural_indexes[parser.n_structural_indexes] = uint32_t(len); + if (parser.n_structural_indexes == 0) { return EMPTY; } + } else if(unclosed_string) { error = UNCLOSED_STRING; } + return error; +} + +private: + const uint8_t *buf; + uint32_t *next_structural_index; + dom_parser_implementation &parser; + uint32_t len; + uint32_t idx{0}; + error_code error{SUCCESS}; + stage1_mode partial; +}; // structural_scanner + +} // namespace stage1 +} // unnamed namespace + +simdjson_warn_unused error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, stage1_mode partial) noexcept { + this->buf = _buf; + this->len = _len; + stage1::structural_scanner scanner(*this, partial); + return scanner.scan(); +} + +// big table for the minifier +static uint8_t jump_table[256 * 3] = { + 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, + 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, + 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, + 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, + 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, + 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, + 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, + 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, + 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, + 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, + 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, + 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, + 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, + 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, + 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, + 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, + 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, + 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, + 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, + 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, + 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, +}; + +simdjson_warn_unused error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept { + size_t i = 0, pos = 0; + uint8_t quote = 0; + uint8_t nonescape = 1; + + while (i < len) { + unsigned char c = buf[i]; + uint8_t *meta = jump_table + 3 * c; + + quote = quote ^ (meta[0] & nonescape); + dst[pos] = c; + pos += meta[2] | quote; + + i += 1; + nonescape = uint8_t(~nonescape) | (meta[1]); + } + dst_len = pos; // we intentionally do not work with a reference + // for fear of aliasing + return quote ? UNCLOSED_STRING : SUCCESS; +} + +// credit: based on code from Google Fuchsia (Apache Licensed) +simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t len) const noexcept { + const uint8_t *data = reinterpret_cast(buf); + uint64_t pos = 0; + uint32_t code_point = 0; + while (pos < len) { + // check of the next 8 bytes are ascii. + uint64_t next_pos = pos + 16; + if (next_pos <= len) { // if it is safe to read 8 more bytes, check that they are ascii + uint64_t v1; + memcpy(&v1, data + pos, sizeof(uint64_t)); + uint64_t v2; + memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t)); + uint64_t v{v1 | v2}; + if ((v & 0x8080808080808080) == 0) { + pos = next_pos; + continue; + } + } + unsigned char byte = data[pos]; + if (byte < 0x80) { + pos++; + continue; + } else if ((byte & 0xe0) == 0xc0) { + next_pos = pos + 2; + if (next_pos > len) { return false; } + if ((data[pos + 1] & 0xc0) != 0x80) { return false; } + // range check + code_point = (byte & 0x1f) << 6 | (data[pos + 1] & 0x3f); + if (code_point < 0x80 || 0x7ff < code_point) { return false; } + } else if ((byte & 0xf0) == 0xe0) { + next_pos = pos + 3; + if (next_pos > len) { return false; } + if ((data[pos + 1] & 0xc0) != 0x80) { return false; } + if ((data[pos + 2] & 0xc0) != 0x80) { return false; } + // range check + code_point = (byte & 0x0f) << 12 | + (data[pos + 1] & 0x3f) << 6 | + (data[pos + 2] & 0x3f); + if (code_point < 0x800 || 0xffff < code_point || + (0xd7ff < code_point && code_point < 0xe000)) { + return false; + } + } else if ((byte & 0xf8) == 0xf0) { // 0b11110000 + next_pos = pos + 4; + if (next_pos > len) { return false; } + if ((data[pos + 1] & 0xc0) != 0x80) { return false; } + if ((data[pos + 2] & 0xc0) != 0x80) { return false; } + if ((data[pos + 3] & 0xc0) != 0x80) { return false; } + // range check + code_point = + (byte & 0x07) << 18 | (data[pos + 1] & 0x3f) << 12 | + (data[pos + 2] & 0x3f) << 6 | (data[pos + 3] & 0x3f); + if (code_point <= 0xffff || 0x10ffff < code_point) { return false; } + } else { + // we may have a continuation + return false; + } + pos = next_pos; + } + return true; +} + +} // namespace fallback +} // namespace simdjson + +// +// Stage 2 +// + +namespace simdjson { +namespace fallback { + +simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { + return stage2::tape_builder::parse_document(*this, _doc); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { + return stage2::tape_builder::parse_document(*this, _doc); +} + +simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { + return fallback::stringparsing::parse_string(src, dst, replacement_char); +} + +simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept { + return fallback::stringparsing::parse_wobbly_string(src, dst); +} + +simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { + auto error = stage1(_buf, _len, stage1_mode::regular); + if (error) { return error; } + return stage2(_doc); +} + +} // namespace fallback +} // namespace simdjson + +/* including simdjson/fallback/end.h: #include */ +/* begin file simdjson/fallback/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +/* undefining SIMDJSON_IMPLEMENTATION from "fallback" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/fallback/end.h */ + +#endif // SIMDJSON_SRC_FALLBACK_CPP +/* end file fallback.cpp */ +#endif +#if SIMDJSON_IMPLEMENTATION_HASWELL +/* including haswell.cpp: #include */ +/* begin file haswell.cpp */ +#ifndef SIMDJSON_SRC_HASWELL_CPP +#define SIMDJSON_SRC_HASWELL_CPP + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +/* including simdjson/haswell.h: #include */ +/* begin file simdjson/haswell.h */ +#ifndef SIMDJSON_HASWELL_H +#define SIMDJSON_HASWELL_H + +/* including simdjson/haswell/begin.h: #include "simdjson/haswell/begin.h" */ +/* begin file simdjson/haswell/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "haswell" */ +#define SIMDJSON_IMPLEMENTATION haswell + +/* including simdjson/haswell/base.h: #include "simdjson/haswell/base.h" */ +/* begin file simdjson/haswell/base.h */ +#ifndef SIMDJSON_HASWELL_BASE_H +#define SIMDJSON_HASWELL_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_HASWELL +namespace simdjson { +/** + * Implementation for Haswell (Intel AVX2). + */ +namespace haswell { + +class implementation; + +namespace { +namespace simd { +template struct simd8; +template struct simd8x64; +} // namespace simd +} // unnamed namespace + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_BASE_H +/* end file simdjson/haswell/base.h */ +/* including simdjson/haswell/intrinsics.h: #include "simdjson/haswell/intrinsics.h" */ +/* begin file simdjson/haswell/intrinsics.h */ +#ifndef SIMDJSON_HASWELL_INTRINSICS_H +#define SIMDJSON_HASWELL_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + * e.g., if __AVX2__ is set... in turn, we normally set these + * macros by compiling against the corresponding architecture + * (e.g., arch:AVX2, -mavx2, etc.) which compiles the whole + * software with these advanced instructions. In simdjson, we + * want to compile the whole program for a generic target, + * and only target our specific kernels. As a workaround, + * we directly include the needed headers. These headers would + * normally guard against such usage, but we carefully included + * (or ) before, so the headers + * are fooled. + */ +#include // for _blsr_u64 +#include // for __lzcnt64 +#include // for most things (AVX2, AVX512, _popcnt64) +#include +#include +#include +#include +#include // for _mm_clmulepi64_si128 +// unfortunately, we may not get _blsr_u64, but, thankfully, clang +// has it as a macro. +#ifndef _blsr_u64 +// we roll our own +#define _blsr_u64(n) ((n - 1) & n) +#endif // _blsr_u64 +#endif // SIMDJSON_CLANG_VISUAL_STUDIO + +static_assert(sizeof(__m256i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for haswell kernel."); + +#endif // SIMDJSON_HASWELL_INTRINSICS_H +/* end file simdjson/haswell/intrinsics.h */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_HASWELL +SIMDJSON_TARGET_REGION("avx2,bmi,pclmul,lzcnt,popcnt") +#endif + +/* including simdjson/haswell/bitmanipulation.h: #include "simdjson/haswell/bitmanipulation.h" */ +/* begin file simdjson/haswell/bitmanipulation.h */ +#ifndef SIMDJSON_HASWELL_BITMANIPULATION_H +#define SIMDJSON_HASWELL_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/bitmask.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return (int)_tzcnt_u64(input_num); +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + //////// + // You might expect the next line to be equivalent to + // return (int)_tzcnt_u64(input_num); + // but the generated code differs and might be less efficient? + //////// + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return _blsr_u64(input_num); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { + return int(_lzcnt_u64(input_num)); +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_BITMANIPULATION_H +/* end file simdjson/haswell/bitmanipulation.h */ +/* including simdjson/haswell/bitmask.h: #include "simdjson/haswell/bitmask.h" */ +/* begin file simdjson/haswell/bitmask.h */ +#ifndef SIMDJSON_HASWELL_BITMASK_H +#define SIMDJSON_HASWELL_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(const uint64_t bitmask) { + // There should be no such thing with a processor supporting avx2 + // but not clmul. + __m128i all_ones = _mm_set1_epi8('\xFF'); + __m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0ULL, bitmask), all_ones, 0); + return _mm_cvtsi128_si64(result); +} + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_BITMASK_H +/* end file simdjson/haswell/bitmask.h */ +/* including simdjson/haswell/numberparsing_defs.h: #include "simdjson/haswell/numberparsing_defs.h" */ +/* begin file simdjson/haswell/numberparsing_defs.h */ +#ifndef SIMDJSON_HASWELL_NUMBERPARSING_DEFS_H +#define SIMDJSON_HASWELL_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace numberparsing { + +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + // this actually computes *16* values so we are being wasteful. + const __m128i ascii0 = _mm_set1_epi8('0'); + const __m128i mul_1_10 = + _mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1); + const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1); + const __m128i mul_1_10000 = + _mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1); + const __m128i input = _mm_sub_epi8( + _mm_loadu_si128(reinterpret_cast(chars)), ascii0); + const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10); + const __m128i t2 = _mm_madd_epi16(t1, mul_1_100); + const __m128i t3 = _mm_packus_epi32(t2, t2); + const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000); + return _mm_cvtsi128_si32( + t4); // only captures the sum of the first 8 digits, drop the rest +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace haswell +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_HASWELL_NUMBERPARSING_DEFS_H +/* end file simdjson/haswell/numberparsing_defs.h */ +/* including simdjson/haswell/simd.h: #include "simdjson/haswell/simd.h" */ +/* begin file simdjson/haswell/simd.h */ +#ifndef SIMDJSON_HASWELL_SIMD_H +#define SIMDJSON_HASWELL_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace simd { + + // Forward-declared so they can be used by splat and friends. + template + struct base { + __m256i value; + + // Zero constructor + simdjson_inline base() : value{__m256i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m256i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m256i&() const { return this->value; } + simdjson_inline operator __m256i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm256_or_si256(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm256_and_si256(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm256_xor_si256(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm256_andnot_si256(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + // Forward-declared so they can be used by splat and friends. + template + struct simd8; + + template> + struct base8: base> { + typedef uint32_t bitmask_t; + typedef uint64_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m256i _value) : base>(_value) {} + + friend simdjson_really_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return _mm256_cmpeq_epi8(lhs, rhs); } + + static const int SIZE = sizeof(base::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return _mm256_alignr_epi8(*this, _mm256_permute2x128_si256(prev_chunk, *this, 0x21), 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm256_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m256i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { return _mm256_movemask_epi8(*this); } + simdjson_inline bool any() const { return !_mm256_testz_si256(*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm256_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm256_setzero_si256(); } + static simdjson_inline simd8 load(const T values[32]) { + return _mm256_loadu_si256(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m256i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[32]) const { return _mm256_storeu_si256(reinterpret_cast<__m256i *>(dst), *this); } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm256_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm256_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm256_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 32 - count_ones(mask) bytes of the result are significant but 32 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint32_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in four steps, first 8 bytes and then second 8 bytes... + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // second least significant 8 bits + uint8_t mask3 = uint8_t(mask >> 16); // ... + uint8_t mask4 = uint8_t(mask >> 24); // ... + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + __m256i shufmask = _mm256_set_epi64x(thintable_epi8[mask4], thintable_epi8[mask3], + thintable_epi8[mask2], thintable_epi8[mask1]); + // we increment by 0x08 the second half of the mask and so forth + shufmask = + _mm256_add_epi8(shufmask, _mm256_set_epi32(0x18181818, 0x18181818, + 0x10101010, 0x10101010, 0x08080808, 0x08080808, 0, 0)); + // this is the version "nearly pruned" + __m256i pruned = _mm256_shuffle_epi8(*this, shufmask); + // we still need to put the pieces back together. + // we compute the popcount of the first words: + int pop1 = BitsSetTable256mul2[mask1]; + int pop3 = BitsSetTable256mul2[mask3]; + + // then load the corresponding mask + // could be done with _mm256_loadu2_m128i but many standard libraries omit this intrinsic. + __m256i v256 = _mm256_castsi128_si256( + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop1 * 8))); + __m256i compactmask = _mm256_insertf128_si256(v256, + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop3 * 8)), 1); + __m256i almostthere = _mm256_shuffle_epi8(pruned, compactmask); + // We just need to write out the result. + // This is the tricky bit that is hard to do + // if we want to return a SIMD register, since there + // is no single-instruction approach to recombine + // the two 128-bit lanes with an offset. + __m128i v128; + v128 = _mm256_castsi256_si128(almostthere); + _mm_storeu_si128( reinterpret_cast<__m128i *>(output), v128); + v128 = _mm256_extractf128_si256(almostthere, 1); + _mm_storeu_si128( reinterpret_cast<__m128i *>(output + 16 - count_ones(mask & 0xFFFF)), v128); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m256i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t values[32]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15, + int8_t v16, int8_t v17, int8_t v18, int8_t v19, int8_t v20, int8_t v21, int8_t v22, int8_t v23, + int8_t v24, int8_t v25, int8_t v26, int8_t v27, int8_t v28, int8_t v29, int8_t v30, int8_t v31 + ) : simd8(_mm256_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v16,v17,v18,v19,v20,v21,v22,v23, + v24,v25,v26,v27,v28,v29,v30,v31 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm256_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm256_min_epi8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return _mm256_cmpgt_epi8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm256_cmpgt_epi8(other, *this); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m256i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t values[32]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15, + uint8_t v16, uint8_t v17, uint8_t v18, uint8_t v19, uint8_t v20, uint8_t v21, uint8_t v22, uint8_t v23, + uint8_t v24, uint8_t v25, uint8_t v26, uint8_t v27, uint8_t v28, uint8_t v29, uint8_t v30, uint8_t v31 + ) : simd8(_mm256_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v16,v17,v18,v19,v20,v21,v22,v23, + v24,v25,v26,v27,v28,v29,v30,v31 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm256_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm256_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm256_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm256_min_epu8(other, *this); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline simd8 operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline simd8 operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->lt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return *this == uint8_t(0); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + simdjson_inline bool is_ascii() const { return _mm256_movemask_epi8(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { return _mm256_testz_si256(*this, *this); } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return _mm256_testz_si256(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm256_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm256_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline int get_bit() const { return _mm256_movemask_epi8(_mm256_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 2, "Haswell kernel should use two registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1) : chunks{chunk0, chunk1} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+32)} {} + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + uint32_t mask1 = uint32_t(mask); + uint32_t mask2 = uint32_t(mask >> 32); + this->chunks[0].compress(mask1, output); + this->chunks[1].compress(mask2, output + 32 - count_ones(mask1)); + return 64 - count_ones(mask); + } + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r_lo = uint32_t(this->chunks[0].to_bitmask()); + uint64_t r_hi = this->chunks[1].to_bitmask(); + return r_lo | (r_hi << 32); + } + + simdjson_inline simd8 reduce_or() const { + return this->chunks[0] | this->chunks[1]; + } + + simdjson_inline simd8x64 bit_or(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] | mask, + this->chunks[1] | mask + ); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64( + this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1] + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_SIMD_H +/* end file simdjson/haswell/simd.h */ +/* including simdjson/haswell/stringparsing_defs.h: #include "simdjson/haswell/stringparsing_defs.h" */ +/* begin file simdjson/haswell/stringparsing_defs.h */ +#ifndef SIMDJSON_HASWELL_STRINGPARSING_DEFS_H +#define SIMDJSON_HASWELL_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/simd.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return ((quote_bits - 1) & bs_bits) != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 15 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v(src); + // store to dest unconditionally - we can overwrite the bits we don't like later + v.store(dst); + return { + static_cast((v == '\\').to_bitmask()), // bs_bits + static_cast((v == '"').to_bitmask()), // quote_bits + }; +} + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_STRINGPARSING_DEFS_H +/* end file simdjson/haswell/stringparsing_defs.h */ +/* end file simdjson/haswell/begin.h */ +/* including simdjson/generic/amalgamated.h for haswell: #include "simdjson/generic/amalgamated.h" */ +/* begin file simdjson/generic/amalgamated.h for haswell */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_DEPENDENCIES_H) +#error simdjson/generic/dependencies.h must be included before simdjson/generic/amalgamated.h! +#endif + +/* including simdjson/generic/base.h for haswell: #include "simdjson/generic/base.h" */ +/* begin file simdjson/generic/base.h for haswell */ +#ifndef SIMDJSON_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): // If we haven't got an implementation yet, we're in the editor, editing a generic file! Just */ +/* amalgamation skipped (editor-only): // use the most advanced one we can so the most possible stuff can be tested. */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation_detection.h" */ +/* amalgamation skipped (editor-only): #if SIMDJSON_IMPLEMENTATION_ICELAKE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_HASWELL */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_WESTMERE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_ARM64 */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_PPC64 */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_FALLBACK */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/begin.h" */ +/* amalgamation skipped (editor-only): #else */ +/* amalgamation skipped (editor-only): #error "All possible implementations (including fallback) have been disabled! simdjson will not run." */ +/* amalgamation skipped (editor-only): #endif */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { + +struct open_container; +class dom_parser_implementation; + +/** + * The type of a JSON number + */ +enum class number_type { + floating_point_number=1, /// a binary64 number + signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + unsigned_integer /// a positive integer larger or equal to 1<<63 +}; + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_BASE_H +/* end file simdjson/generic/base.h for haswell */ +/* including simdjson/generic/jsoncharutils.h for haswell: #include "simdjson/generic/jsoncharutils.h" */ +/* begin file simdjson/generic/jsoncharutils.h for haswell */ +#ifndef SIMDJSON_GENERIC_JSONCHARUTILS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_JSONCHARUTILS_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/jsoncharutils_tables.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace jsoncharutils { + +// return non-zero if not a structural or whitespace char +// zero otherwise +simdjson_inline uint32_t is_not_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace_negated[c]; +} + +simdjson_inline uint32_t is_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace[c]; +} + +// returns a value with the high 16 bits set if not valid +// otherwise returns the conversion of the 4 hex digits at src into the bottom +// 16 bits of the 32-bit return register +// +// see +// https://lemire.me/blog/2019/04/17/parsing-short-hexadecimal-strings-efficiently/ +static inline uint32_t hex_to_u32_nocheck( + const uint8_t *src) { // strictly speaking, static inline is a C-ism + uint32_t v1 = internal::digit_to_val32[630 + src[0]]; + uint32_t v2 = internal::digit_to_val32[420 + src[1]]; + uint32_t v3 = internal::digit_to_val32[210 + src[2]]; + uint32_t v4 = internal::digit_to_val32[0 + src[3]]; + return v1 | v2 | v3 | v4; +} + +// given a code point cp, writes to c +// the utf-8 code, outputting the length in +// bytes, if the length is zero, the code point +// is invalid +// +// This can possibly be made faster using pdep +// and clz and table lookups, but JSON documents +// have few escaped code points, and the following +// function looks cheap. +// +// Note: we assume that surrogates are treated separately +// +simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) { + if (cp <= 0x7F) { + c[0] = uint8_t(cp); + return 1; // ascii + } + if (cp <= 0x7FF) { + c[0] = uint8_t((cp >> 6) + 192); + c[1] = uint8_t((cp & 63) + 128); + return 2; // universal plane + // Surrogates are treated elsewhere... + //} //else if (0xd800 <= cp && cp <= 0xdfff) { + // return 0; // surrogates // could put assert here + } else if (cp <= 0xFFFF) { + c[0] = uint8_t((cp >> 12) + 224); + c[1] = uint8_t(((cp >> 6) & 63) + 128); + c[2] = uint8_t((cp & 63) + 128); + return 3; + } else if (cp <= 0x10FFFF) { // if you know you have a valid code point, this + // is not needed + c[0] = uint8_t((cp >> 18) + 240); + c[1] = uint8_t(((cp >> 12) & 63) + 128); + c[2] = uint8_t(((cp >> 6) & 63) + 128); + c[3] = uint8_t((cp & 63) + 128); + return 4; + } + // will return 0 when the code point was too large. + return 0; // bad r +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +} // namespace jsoncharutils +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_JSONCHARUTILS_H +/* end file simdjson/generic/jsoncharutils.h for haswell */ +/* including simdjson/generic/atomparsing.h for haswell: #include "simdjson/generic/atomparsing.h" */ +/* begin file simdjson/generic/atomparsing.h for haswell */ +#ifndef SIMDJSON_GENERIC_ATOMPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ATOMPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace haswell { +namespace { +/// @private +namespace atomparsing { + +// The string_to_uint32 is exclusively used to map literal strings to 32-bit values. +// We use memcpy instead of a pointer cast to avoid undefined behaviors since we cannot +// be certain that the character pointer will be properly aligned. +// You might think that using memcpy makes this function expensive, but you'd be wrong. +// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false"); +// to the compile-time constant 1936482662. +simdjson_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; } + + +// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive. +// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about. +simdjson_warn_unused +simdjson_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) { + uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++) + static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes"); + std::memcpy(&srcval, src, sizeof(uint32_t)); + return srcval ^ string_to_uint32(atom); +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src) { + return (str4ncmp(src, "true") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_true_atom(src); } + else if (len == 4) { return !str4ncmp(src, "true"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src) { + return (str4ncmp(src+1, "alse") | jsoncharutils::is_not_structural_or_whitespace(src[5])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src, size_t len) { + if (len > 5) { return is_valid_false_atom(src); } + else if (len == 5) { return !str4ncmp(src+1, "alse"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src) { + return (str4ncmp(src, "null") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_null_atom(src); } + else if (len == 4) { return !str4ncmp(src, "null"); } + else { return false; } +} + +} // namespace atomparsing +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ATOMPARSING_H +/* end file simdjson/generic/atomparsing.h for haswell */ +/* including simdjson/generic/dom_parser_implementation.h for haswell: #include "simdjson/generic/dom_parser_implementation.h" */ +/* begin file simdjson/generic/dom_parser_implementation.h for haswell */ +#ifndef SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { + +// expectation: sizeof(open_container) = 64/8. +struct open_container { + uint32_t tape_index; // where, on the tape, does the scope ([,{) begins + uint32_t count; // how many elements in the scope +}; // struct open_container + +static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits"); + +class dom_parser_implementation final : public internal::dom_parser_implementation { +public: + /** Tape location of each open { or [ */ + std::unique_ptr open_containers{}; + /** Whether each open container is a [ or { */ + std::unique_ptr is_array{}; + /** Buffer passed to stage 1 */ + const uint8_t *buf{}; + /** Length passed to stage 1 */ + size_t len{0}; + /** Document passed to stage 2 */ + dom::document *doc{}; + + inline dom_parser_implementation() noexcept; + inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; + inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; + dom_parser_implementation(const dom_parser_implementation &) = delete; + dom_parser_implementation &operator=(const dom_parser_implementation &) = delete; + + simdjson_warn_unused error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage1(const uint8_t *buf, size_t len, stage1_mode partial) noexcept final; + simdjson_warn_unused error_code stage2(dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage2_next(dom::document &doc) noexcept final; + simdjson_warn_unused uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept final; + simdjson_warn_unused uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept final; + inline simdjson_warn_unused error_code set_capacity(size_t capacity) noexcept final; + inline simdjson_warn_unused error_code set_max_depth(size_t max_depth) noexcept final; +private: + simdjson_inline simdjson_warn_unused error_code set_capacity_stage1(size_t capacity); + +}; + +} // namespace haswell +} // namespace simdjson + +namespace simdjson { +namespace haswell { + +inline dom_parser_implementation::dom_parser_implementation() noexcept = default; +inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; +inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; + +// Leaving these here so they can be inlined if so desired +inline simdjson_warn_unused error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept { + if(capacity > SIMDJSON_MAXSIZE_BYTES) { return CAPACITY; } + // Stage 1 index output + size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7; + structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] ); + if (!structural_indexes) { _capacity = 0; return MEMALLOC; } + structural_indexes[0] = 0; + n_structural_indexes = 0; + + _capacity = capacity; + return SUCCESS; +} + +inline simdjson_warn_unused error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept { + // Stage 2 stacks + open_containers.reset(new (std::nothrow) open_container[max_depth]); + is_array.reset(new (std::nothrow) bool[max_depth]); + if (!is_array || !open_containers) { _max_depth = 0; return MEMALLOC; } + + _max_depth = max_depth; + return SUCCESS; +} + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file simdjson/generic/dom_parser_implementation.h for haswell */ +/* including simdjson/generic/implementation_simdjson_result_base.h for haswell: #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base.h for haswell */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { + +// This is a near copy of include/error.h's implementation_simdjson_result_base, except it doesn't use std::pair +// so we can avoid inlining errors +// TODO reconcile these! +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + * + * This is a base class for implementations that want to add functions to the result type for + * chaining. + * + * Override like: + * + * struct simdjson_result : public internal::implementation_simdjson_result_base { + * simdjson_result() noexcept : internal::implementation_simdjson_result_base() {} + * simdjson_result(error_code error) noexcept : internal::implementation_simdjson_result_base(error) {} + * simdjson_result(T &&value) noexcept : internal::implementation_simdjson_result_base(std::forward(value)) {} + * simdjson_result(T &&value, error_code error) noexcept : internal::implementation_simdjson_result_base(value, error) {} + * // Your extra methods here + * } + * + * Then any method returning simdjson_result will be chainable with your methods. + */ +template +struct implementation_simdjson_result_base { + + /** + * Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline implementation_simdjson_result_base() noexcept = default; + + /** + * Create a new error result. + */ + simdjson_inline implementation_simdjson_result_base(error_code error) noexcept; + + /** + * Create a new successful result. + */ + simdjson_inline implementation_simdjson_result_base(T &&value) noexcept; + + /** + * Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline implementation_simdjson_result_base(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); + + +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T& value_unsafe() & noexcept; + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; +protected: + /** users should never directly access first and second. **/ + T first{}; /** Users should never directly access 'first'. **/ + error_code second{UNINITIALIZED}; /** Users should never directly access 'second'. **/ +}; // struct implementation_simdjson_result_base + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H +/* end file simdjson/generic/implementation_simdjson_result_base.h for haswell */ +/* including simdjson/generic/numberparsing.h for haswell: #include "simdjson/generic/numberparsing.h" */ +/* begin file simdjson/generic/numberparsing.h for haswell */ +#ifndef SIMDJSON_GENERIC_NUMBERPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_NUMBERPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include +#include + +namespace simdjson { +namespace haswell { +namespace numberparsing { + +#ifdef JSON_TEST_NUMBERS +#define INVALID_NUMBER(SRC) (found_invalid_number((SRC)), NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (found_integer((VALUE), (SRC)), (WRITER).append_s64((VALUE))) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (found_unsigned_integer((VALUE), (SRC)), (WRITER).append_u64((VALUE))) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (found_float((VALUE), (SRC)), (WRITER).append_double((VALUE))) +#else +#define INVALID_NUMBER(SRC) (NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (WRITER).append_s64((VALUE)) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (WRITER).append_u64((VALUE)) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (WRITER).append_double((VALUE)) +#endif + +namespace { + +// Convert a mantissa, an exponent and a sign bit into an ieee64 double. +// The real_exponent needs to be in [0, 2046] (technically real_exponent = 2047 would be acceptable). +// The mantissa should be in [0,1<<53). The bit at index (1ULL << 52) while be zeroed. +simdjson_inline double to_double(uint64_t mantissa, uint64_t real_exponent, bool negative) { + double d; + mantissa &= ~(1ULL << 52); + mantissa |= real_exponent << 52; + mantissa |= ((static_cast(negative)) << 63); + std::memcpy(&d, &mantissa, sizeof(d)); + return d; +} + +// Attempts to compute i * 10^(power) exactly; and if "negative" is +// true, negate the result. +// This function will only work in some cases, when it does not work, success is +// set to false. This should work *most of the time* (like 99% of the time). +// We assume that power is in the [smallest_power, +// largest_power] interval: the caller is responsible for this check. +simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative, double &d) { + // we start with a fast path + // It was described in + // Clinger WD. How to read floating point numbers accurately. + // ACM SIGPLAN Notices. 1990 +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + // We cannot be certain that x/y is rounded to nearest. + if (0 <= power && power <= 22 && i <= 9007199254740991) +#else + if (-22 <= power && power <= 22 && i <= 9007199254740991) +#endif + { + // convert the integer into a double. This is lossless since + // 0 <= i <= 2^53 - 1. + d = double(i); + // + // The general idea is as follows. + // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then + // 1) Both s and p can be represented exactly as 64-bit floating-point + // values + // (binary64). + // 2) Because s and p can be represented exactly as floating-point values, + // then s * p + // and s / p will produce correctly rounded values. + // + if (power < 0) { + d = d / simdjson::internal::power_of_ten[-power]; + } else { + d = d * simdjson::internal::power_of_ten[power]; + } + if (negative) { + d = -d; + } + return true; + } + // When 22 < power && power < 22 + 16, we could + // hope for another, secondary fast path. It was + // described by David M. Gay in "Correctly rounded + // binary-decimal and decimal-binary conversions." (1990) + // If you need to compute i * 10^(22 + x) for x < 16, + // first compute i * 10^x, if you know that result is exact + // (e.g., when i * 10^x < 2^53), + // then you can still proceed and do (i * 10^x) * 10^22. + // Is this worth your time? + // You need 22 < power *and* power < 22 + 16 *and* (i * 10^(x-22) < 2^53) + // for this second fast path to work. + // If you you have 22 < power *and* power < 22 + 16, and then you + // optimistically compute "i * 10^(x-22)", there is still a chance that you + // have wasted your time if i * 10^(x-22) >= 2^53. It makes the use cases of + // this optimization maybe less common than we would like. Source: + // http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + // also used in RapidJSON: https://rapidjson.org/strtod_8h_source.html + + // The fast path has now failed, so we are failing back on the slower path. + + // In the slow path, we need to adjust i so that it is > 1<<63 which is always + // possible, except if i == 0, so we handle i == 0 separately. + if(i == 0) { + d = negative ? -0.0 : 0.0; + return true; + } + + + // The exponent is 1024 + 63 + power + // + floor(log(5**power)/log(2)). + // The 1024 comes from the ieee64 standard. + // The 63 comes from the fact that we use a 64-bit word. + // + // Computing floor(log(5**power)/log(2)) could be + // slow. Instead we use a fast function. + // + // For power in (-400,350), we have that + // (((152170 + 65536) * power ) >> 16); + // is equal to + // floor(log(5**power)/log(2)) + power when power >= 0 + // and it is equal to + // ceil(log(5**-power)/log(2)) + power when power < 0 + // + // The 65536 is (1<<16) and corresponds to + // (65536 * power) >> 16 ---> power + // + // ((152170 * power ) >> 16) is equal to + // floor(log(5**power)/log(2)) + // + // Note that this is not magic: 152170/(1<<16) is + // approximatively equal to log(5)/log(2). + // The 1<<16 value is a power of two; we could use a + // larger power of 2 if we wanted to. + // + int64_t exponent = (((152170 + 65536) * power) >> 16) + 1024 + 63; + + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(i); + i <<= lz; + + + // We are going to need to do some 64-bit arithmetic to get a precise product. + // We use a table lookup approach. + // It is safe because + // power >= smallest_power + // and power <= largest_power + // We recover the mantissa of the power, it has a leading 1. It is always + // rounded down. + // + // We want the most significant 64 bits of the product. We know + // this will be non-zero because the most significant bit of i is + // 1. + const uint32_t index = 2 * uint32_t(power - simdjson::internal::smallest_power); + // Optimization: It may be that materializing the index as a variable might confuse some compilers and prevent effective complex-addressing loads. (Done for code clarity.) + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); + // Both i and power_of_five_128[index] have their most significant bit set to 1 which + // implies that the either the most or the second most significant bit of the product + // is 1. We pack values in this manner for efficiency reasons: it maximizes the use + // we make of the product. It also makes it easy to reason about the product: there + // is 0 or 1 leading zero in the product. + + // Unless the least significant 9 bits of the high (64-bit) part of the full + // product are all 1s, then we know that the most significant 55 bits are + // exact and no further work is needed. Having 55 bits is necessary because + // we need 53 bits for the mantissa but we have to have one rounding bit and + // we can waste a bit if the most significant bit of the product is zero. + if((firstproduct.high & 0x1FF) == 0x1FF) { + // We want to compute i * 5^q, but only care about the top 55 bits at most. + // Consider the scenario where q>=0. Then 5^q may not fit in 64-bits. Doing + // the full computation is wasteful. So we do what is called a "truncated + // multiplication". + // We take the most significant 64-bits, and we put them in + // power_of_five_128[index]. Usually, that's good enough to approximate i * 5^q + // to the desired approximation using one multiplication. Sometimes it does not suffice. + // Then we store the next most significant 64 bits in power_of_five_128[index + 1], and + // then we get a better approximation to i * 5^q. + // + // That's for when q>=0. The logic for q<0 is somewhat similar but it is somewhat + // more complicated. + // + // There is an extra layer of complexity in that we need more than 55 bits of + // accuracy in the round-to-even scenario. + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if(secondproduct.high > firstproduct.low) { firstproduct.high++; } + // As it has been proven by Noble Mushtak and Daniel Lemire in "Fast Number Parsing Without + // Fallback" (https://arxiv.org/abs/2212.06644), at this point we are sure that the product + // is sufficiently accurate, and more computation is not needed. + } + uint64_t lower = firstproduct.low; + uint64_t upper = firstproduct.high; + // The final mantissa should be 53 bits with a leading 1. + // We shift it so that it occupies 54 bits with a leading 1. + /////// + uint64_t upperbit = upper >> 63; + uint64_t mantissa = upper >> (upperbit + 9); + lz += int(1 ^ upperbit); + + // Here we have mantissa < (1<<54). + int64_t real_exponent = exponent - lz; + if (simdjson_unlikely(real_exponent <= 0)) { // we have a subnormal? + // Here have that real_exponent <= 0 so -real_exponent >= 0 + if(-real_exponent + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure. + d = negative ? -0.0 : 0.0; + return true; + } + // next line is safe because -real_exponent + 1 < 0 + mantissa >>= -real_exponent + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0. + mantissa += (mantissa & 1); // round up + mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + real_exponent = (mantissa < (uint64_t(1) << 52)) ? 0 : 1; + d = to_double(mantissa, real_exponent, negative); + return true; + } + // We have to round to even. The "to even" part + // is only a problem when we are right in between two floats + // which we guard against. + // If we have lots of trailing zeros, we may fall right between two + // floating-point values. + // + // The round-to-even cases take the form of a number 2m+1 which is in (2^53,2^54] + // times a power of two. That is, it is right between a number with binary significand + // m and another number with binary significand m+1; and it must be the case + // that it cannot be represented by a float itself. + // + // We must have that w * 10 ^q == (2m+1) * 2^p for some power of two 2^p. + // Recall that 10^q = 5^q * 2^q. + // When q >= 0, we must have that (2m+1) is divible by 5^q, so 5^q <= 2^54. We have that + // 5^23 <= 2^54 and it is the last power of five to qualify, so q <= 23. + // When q<0, we have w >= (2m+1) x 5^{-q}. We must have that w<2^{64} so + // (2m+1) x 5^{-q} < 2^{64}. We have that 2m+1>2^{53}. Hence, we must have + // 2^{53} x 5^{-q} < 2^{64}. + // Hence we have 5^{-q} < 2^{11}$ or q>= -4. + // + // We require lower <= 1 and not lower == 0 because we could not prove that + // that lower == 0 is implied; but we could prove that lower <= 1 is a necessary and sufficient test. + if (simdjson_unlikely((lower <= 1) && (power >= -4) && (power <= 23) && ((mantissa & 3) == 1))) { + if((mantissa << (upperbit + 64 - 53 - 2)) == upper) { + mantissa &= ~1; // flip it so that we do not round up + } + } + + mantissa += mantissa & 1; + mantissa >>= 1; + + // Here we have mantissa < (1<<53), unless there was an overflow + if (mantissa >= (1ULL << 53)) { + ////////// + // This will happen when parsing values such as 7.2057594037927933e+16 + //////// + mantissa = (1ULL << 52); + real_exponent++; + } + mantissa &= ~(1ULL << 52); + // we have to check that real_exponent is in range, otherwise we bail out + if (simdjson_unlikely(real_exponent > 2046)) { + // We have an infinite value!!! We could actually throw an error here if we could. + return false; + } + d = to_double(mantissa, real_exponent, negative); + return true; +} + +// We call a fallback floating-point parser that might be slow. Note +// it will accept JSON numbers, but the JSON spec. is more restrictive so +// before you call parse_float_fallback, you need to have validated the input +// string with the JSON grammar. +// It will return an error (false) if the parsed number is infinite. +// The string parsing itself always succeeds. We know that there is at least +// one digit. +static bool parse_float_fallback(const uint8_t *ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +static bool parse_float_fallback(const uint8_t *ptr, const uint8_t *end_ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr), reinterpret_cast(end_ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +// check quickly whether the next 8 chars are made of digits +// at a glance, it looks better than Mula's +// http://0x80.pl/articles/swar-digits-validate.html +simdjson_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) { + uint64_t val; + // this can read up to 7 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(7 <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be bigger than 7"); + std::memcpy(&val, chars, 8); + // a branchy method might be faster: + // return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030) + // && (( (val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0 ) == + // 0x3030303030303030); + return (((val & 0xF0F0F0F0F0F0F0F0) | + (((val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4)) == + 0x3333333333333333); +} + +template +SIMDJSON_NO_SANITIZE_UNDEFINED // We deliberately allow overflow here and check later +simdjson_inline bool parse_digit(const uint8_t c, I &i) { + const uint8_t digit = static_cast(c - '0'); + if (digit > 9) { + return false; + } + // PERF NOTE: multiplication by 10 is cheaper than arbitrary integer multiplication + i = 10 * i + digit; // might overflow, we will handle the overflow later + return true; +} + +simdjson_inline error_code parse_decimal_after_separator(simdjson_unused const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) { + // we continue with the fiction that we have an integer. If the + // floating point number is representable as x * 10^z for some integer + // z that fits in 53 bits, then we will be able to convert back the + // the integer into a float in a lossless manner. + const uint8_t *const first_after_period = p; + +#ifdef SIMDJSON_SWAR_NUMBER_PARSING +#if SIMDJSON_SWAR_NUMBER_PARSING + // this helps if we have lots of decimals! + // this turns out to be frequent enough. + if (is_made_of_eight_digits_fast(p)) { + i = i * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + } +#endif // SIMDJSON_SWAR_NUMBER_PARSING +#endif // #ifdef SIMDJSON_SWAR_NUMBER_PARSING + // Unrolling the first digit makes a small difference on some implementations (e.g. westmere) + if (parse_digit(*p, i)) { ++p; } + while (parse_digit(*p, i)) { p++; } + exponent = first_after_period - p; + // Decimal without digits (123.) is illegal + if (exponent == 0) { + return INVALID_NUMBER(src); + } + return SUCCESS; +} + +simdjson_inline error_code parse_exponent(simdjson_unused const uint8_t *const src, const uint8_t *&p, int64_t &exponent) { + // Exp Sign: -123.456e[-]78 + bool neg_exp = ('-' == *p); + if (neg_exp || '+' == *p) { p++; } // Skip + as well + + // Exponent: -123.456e-[78] + auto start_exp = p; + int64_t exp_number = 0; + while (parse_digit(*p, exp_number)) { ++p; } + // It is possible for parse_digit to overflow. + // In particular, it could overflow to INT64_MIN, and we cannot do - INT64_MIN. + // Thus we *must* check for possible overflow before we negate exp_number. + + // Performance notes: it may seem like combining the two "simdjson_unlikely checks" below into + // a single simdjson_unlikely path would be faster. The reasoning is sound, but the compiler may + // not oblige and may, in fact, generate two distinct paths in any case. It might be + // possible to do uint64_t(p - start_exp - 1) >= 18 but it could end up trading off + // instructions for a simdjson_likely branch, an unconclusive gain. + + // If there were no digits, it's an error. + if (simdjson_unlikely(p == start_exp)) { + return INVALID_NUMBER(src); + } + // We have a valid positive exponent in exp_number at this point, except that + // it may have overflowed. + + // If there were more than 18 digits, we may have overflowed the integer. We have to do + // something!!!! + if (simdjson_unlikely(p > start_exp+18)) { + // Skip leading zeroes: 1e000000000000000000001 is technically valid and doesn't overflow + while (*start_exp == '0') { start_exp++; } + // 19 digits could overflow int64_t and is kind of absurd anyway. We don't + // support exponents smaller than -999,999,999,999,999,999 and bigger + // than 999,999,999,999,999,999. + // We can truncate. + // Note that 999999999999999999 is assuredly too large. The maximal ieee64 value before + // infinity is ~1.8e308. The smallest subnormal is ~5e-324. So, actually, we could + // truncate at 324. + // Note that there is no reason to fail per se at this point in time. + // E.g., 0e999999999999999999999 is a fine number. + if (p > start_exp+18) { exp_number = 999999999999999999; } + } + // At this point, we know that exp_number is a sane, positive, signed integer. + // It is <= 999,999,999,999,999,999. As long as 'exponent' is in + // [-8223372036854775808, 8223372036854775808], we won't overflow. Because 'exponent' + // is bounded in magnitude by the size of the JSON input, we are fine in this universe. + // To sum it up: the next line should never overflow. + exponent += (neg_exp ? -exp_number : exp_number); + return SUCCESS; +} + +simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t digit_count) { + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + const uint8_t *start = start_digits; + while ((*start == '0') || (*start == '.')) { ++start; } + // we over-decrement by one when there is a '.' + return digit_count - size_t(start - start_digits); +} + +} // unnamed namespace + +/** @private */ +static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) { + if (parse_float_fallback(src, answer)) { + return SUCCESS; + } + return INVALID_NUMBER(src); +} + +/** @private */ +template +simdjson_inline error_code write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer) { + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon in practice. + // + // 9999999999999999999 < 2**64 so we can accommodate 19 digits. + // If we have a decimal separator, then digit_count - 1 is the number of digits, but we + // may not have a decimal separator! + if (simdjson_unlikely(digit_count > 19 && significant_digits(start_digits, digit_count) > 19)) { + // Ok, chances are good that we had an overflow! + // this is almost never going to get called!!! + // we start anew, going slowly!!! + // This will happen in the following examples: + // 10000000000000000000000000000000000000000000e+308 + // 3.1415926535897932384626433832795028841971693993751 + // + // NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer + // reference to it, it would force it to be stored in memory, preventing the compiler from + // picking it apart and putting into registers. i.e. if we pass it as reference, + // it gets slow. + double d; + error_code error = slow_float_parsing(src, &d); + writer.append_double(d); + return error; + } + // NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other + // way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331 + // To future reader: we'd love if someone found a better way, or at least could explain this result! + if (simdjson_unlikely(exponent < simdjson::internal::smallest_power) || (exponent > simdjson::internal::largest_power)) { + // + // Important: smallest_power is such that it leads to a zero value. + // Observe that 18446744073709551615e-343 == 0, i.e. (2**64 - 1) e -343 is zero + // so something x 10^-343 goes to zero, but not so with something x 10^-342. + static_assert(simdjson::internal::smallest_power <= -342, "smallest_power is not small enough"); + // + if((exponent < simdjson::internal::smallest_power) || (i == 0)) { + // E.g. Parse "-0.0e-999" into the same value as "-0.0". See https://en.wikipedia.org/wiki/Signed_zero + WRITE_DOUBLE(negative ? -0.0 : 0.0, src, writer); + return SUCCESS; + } else { // (exponent > largest_power) and (i != 0) + // We have, for sure, an infinite value and simdjson refuses to parse infinite values. + return INVALID_NUMBER(src); + } + } + double d; + if (!compute_float_64(exponent, i, negative, d)) { + // we are almost never going to get here. + if (!parse_float_fallback(src, &d)) { return INVALID_NUMBER(src); } + } + WRITE_DOUBLE(d, src, writer); + return SUCCESS; +} + +// for performance analysis, it is sometimes useful to skip parsing +#ifdef SIMDJSON_SKIPNUMBERPARSING + +template +simdjson_inline error_code parse_number(const uint8_t *const, W &writer) { + writer.append_s64(0); // always write zero + return SUCCESS; // always succeeds +} + +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { return number_type::signed_integer; } +#else + +// parse the number at src +// define JSON_TEST_NUMBERS for unit testing +// +// It is assumed that the number is followed by a structural ({,},],[) character +// or a white space character. If that is not the case (e.g., when the JSON +// document is made of a single number), then it is necessary to copy the +// content and append a space before calling this function. +// +// Our objective is accurate parsing (ULP of 0) at high speed. +template +simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) { + + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + if (digit_count == 0 || ('0' == *start_digits && digit_count > 1)) { return INVALID_NUMBER(src); } + + // + // Handle floats if there is a . or e (or both) + // + int64_t exponent = 0; + bool is_float = false; + if ('.' == *p) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) ); + digit_count = int(p - start_digits); // used later to guard against overflows + } + if (('e' == *p) || ('E' == *p)) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_exponent(src, p, exponent) ); + } + if (is_float) { + const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p); + SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) ); + if (dirty_end) { return INVALID_NUMBER(src); } + return SUCCESS; + } + + // The longest negative 64-bit number is 19 digits. + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + size_t longest_digit_count = negative ? 19 : 20; + if (digit_count > longest_digit_count) { return INVALID_NUMBER(src); } + if (digit_count == longest_digit_count) { + if (negative) { + // Anything negative above INT64_MAX+1 is invalid + if (i > uint64_t(INT64_MAX)+1) { return INVALID_NUMBER(src); } + WRITE_INTEGER(~i+1, src, writer); + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + } else if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INVALID_NUMBER(src); } + } + + // Write unsigned if it doesn't fit in a signed integer. + if (i > uint64_t(INT64_MAX)) { + WRITE_UNSIGNED(i, src, writer); + } else { + WRITE_INTEGER(negative ? (~i+1) : i, src, writer); + } + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; +} + +// Inlineable functions +namespace { + +// This table can be used to characterize the final character of an integer +// string. For JSON structural character and allowable white space characters, +// we return SUCCESS. For 'e', '.' and 'E', we return INCORRECT_TYPE. Otherwise +// we return NUMBER_ERROR. +// Optimization note: we could easily reduce the size of the table by half (to 128) +// at the cost of an extra branch. +// Optimization note: we want the values to use at most 8 bits (not, e.g., 32 bits): +static_assert(error_code(uint8_t(NUMBER_ERROR))== NUMBER_ERROR, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(SUCCESS))== SUCCESS, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(INCORRECT_TYPE))== INCORRECT_TYPE, "bad NUMBER_ERROR cast"); + +const uint8_t integer_string_finisher[256] = { + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, INCORRECT_TYPE, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, SUCCESS, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR}; + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + + +// Parse any number from 0 to 18,446,744,073,709,551,615 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src, const uint8_t * const src_end) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if ((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { + const uint8_t *p = src + 1; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (*p != '"') { return NUMBER_ERROR; } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + // Note: we use src[1] and not src[0] because src[0] is the quote character in this + // instance. + if (src[1] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src, const uint8_t * const src_end) noexcept { + // + // Check for minus sign + // + if(src == src_end) { return NUMBER_ERROR; } + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = src; + uint64_t i = 0; + while (parse_digit(*src, i)) { src++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(src - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*src)) { + // return (*src == '.' || *src == 'e' || *src == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(*src != '"') { return NUMBER_ERROR; } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { + return (*src == '-'); +} + +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { return true; } + return false; +} + +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { + // We have an integer. + // If the number is negative and valid, it must be a signed integer. + if(negative) { return number_type::signed_integer; } + // We want values larger or equal to 9223372036854775808 to be unsigned + // integers, and the other values to be signed integers. + int digit_count = int(p - src); + if(digit_count >= 19) { + const uint8_t * smaller_big_integer = reinterpret_cast("9223372036854775808"); + if((digit_count >= 20) || (memcmp(src, smaller_big_integer, 19) >= 0)) { + return number_type::unsigned_integer; + } + } + return number_type::signed_integer; + } + // Hopefully, we have 'e' or 'E' or '.'. + return number_type::floating_point_number; +} + +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src, const uint8_t * const src_end) noexcept { + if(src == src_end) { return NUMBER_ERROR; } + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + if(p == src_end) { return NUMBER_ERROR; } + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while ((p != src_end) && parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely((p != src_end) && (*p == '.'))) { + p++; + const uint8_t *start_decimal_digits = p; + if ((p == src_end) || !parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = start_digits-src > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if ((p != src_end) && (*p == 'e' || *p == 'E')) { + p++; + if(p == src_end) { return NUMBER_ERROR; } + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while ((p != src_end) && parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (*p != '"') { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +} // unnamed namespace +#endif // SIMDJSON_SKIPNUMBERPARSING + +} // namespace numberparsing + +inline std::ostream& operator<<(std::ostream& out, number_type type) noexcept { + switch (type) { + case number_type::signed_integer: out << "integer in [-9223372036854775808,9223372036854775808)"; break; + case number_type::unsigned_integer: out << "unsigned integer in [9223372036854775808,18446744073709551616)"; break; + case number_type::floating_point_number: out << "floating-point number (binary64)"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_NUMBERPARSING_H +/* end file simdjson/generic/numberparsing.h for haswell */ + +/* including simdjson/generic/implementation_simdjson_result_base-inl.h for haswell: #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { + +// +// internal::implementation_simdjson_result_base inline implementation +// + +template +simdjson_inline void implementation_simdjson_result_base::tie(T &value, error_code &error) && noexcept { + error = this->second; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +simdjson_warn_unused simdjson_inline error_code implementation_simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; +} + +template +simdjson_inline error_code implementation_simdjson_result_base::error() const noexcept { + return this->second; +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& implementation_simdjson_result_base::value() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline T&& implementation_simdjson_result_base::take_value() && noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& implementation_simdjson_result_base::value_unsafe() const& noexcept { + return this->first; +} + +template +simdjson_inline T& implementation_simdjson_result_base::value_unsafe() & noexcept { + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value_unsafe() && noexcept { + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value, error_code error) noexcept + : first{std::forward(value)}, second{error} {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(error_code error) noexcept + : implementation_simdjson_result_base(T{}, error) {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value) noexcept + : implementation_simdjson_result_base(std::forward(value), SUCCESS) {} + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H +/* end file simdjson/generic/implementation_simdjson_result_base-inl.h for haswell */ +/* end file simdjson/generic/amalgamated.h for haswell */ +/* including simdjson/haswell/end.h: #include "simdjson/haswell/end.h" */ +/* begin file simdjson/haswell/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_HASWELL +SIMDJSON_UNTARGET_REGION +#endif + +/* undefining SIMDJSON_IMPLEMENTATION from "haswell" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/haswell/end.h */ + +#endif // SIMDJSON_HASWELL_H +/* end file simdjson/haswell.h */ +/* including simdjson/haswell/implementation.h: #include */ +/* begin file simdjson/haswell/implementation.h */ +#ifndef SIMDJSON_HASWELL_IMPLEMENTATION_H +#define SIMDJSON_HASWELL_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_HASWELL +namespace simdjson { +namespace haswell { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation( + "haswell", + "Intel/AMD AVX2", + internal::instruction_set::AVX2 | internal::instruction_set::PCLMULQDQ | internal::instruction_set::BMI1 | internal::instruction_set::BMI2 + ) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_IMPLEMENTATION_H +/* end file simdjson/haswell/implementation.h */ + +/* including simdjson/haswell/begin.h: #include */ +/* begin file simdjson/haswell/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "haswell" */ +#define SIMDJSON_IMPLEMENTATION haswell + +/* including simdjson/haswell/base.h: #include "simdjson/haswell/base.h" */ +/* begin file simdjson/haswell/base.h */ +#ifndef SIMDJSON_HASWELL_BASE_H +#define SIMDJSON_HASWELL_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_HASWELL +namespace simdjson { +/** + * Implementation for Haswell (Intel AVX2). + */ +namespace haswell { + +class implementation; + +namespace { +namespace simd { +template struct simd8; +template struct simd8x64; +} // namespace simd +} // unnamed namespace + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_BASE_H +/* end file simdjson/haswell/base.h */ +/* including simdjson/haswell/intrinsics.h: #include "simdjson/haswell/intrinsics.h" */ +/* begin file simdjson/haswell/intrinsics.h */ +#ifndef SIMDJSON_HASWELL_INTRINSICS_H +#define SIMDJSON_HASWELL_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + * e.g., if __AVX2__ is set... in turn, we normally set these + * macros by compiling against the corresponding architecture + * (e.g., arch:AVX2, -mavx2, etc.) which compiles the whole + * software with these advanced instructions. In simdjson, we + * want to compile the whole program for a generic target, + * and only target our specific kernels. As a workaround, + * we directly include the needed headers. These headers would + * normally guard against such usage, but we carefully included + * (or ) before, so the headers + * are fooled. + */ +#include // for _blsr_u64 +#include // for __lzcnt64 +#include // for most things (AVX2, AVX512, _popcnt64) +#include +#include +#include +#include +#include // for _mm_clmulepi64_si128 +// unfortunately, we may not get _blsr_u64, but, thankfully, clang +// has it as a macro. +#ifndef _blsr_u64 +// we roll our own +#define _blsr_u64(n) ((n - 1) & n) +#endif // _blsr_u64 +#endif // SIMDJSON_CLANG_VISUAL_STUDIO + +static_assert(sizeof(__m256i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for haswell kernel."); + +#endif // SIMDJSON_HASWELL_INTRINSICS_H +/* end file simdjson/haswell/intrinsics.h */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_HASWELL +SIMDJSON_TARGET_REGION("avx2,bmi,pclmul,lzcnt,popcnt") +#endif + +/* including simdjson/haswell/bitmanipulation.h: #include "simdjson/haswell/bitmanipulation.h" */ +/* begin file simdjson/haswell/bitmanipulation.h */ +#ifndef SIMDJSON_HASWELL_BITMANIPULATION_H +#define SIMDJSON_HASWELL_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/bitmask.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return (int)_tzcnt_u64(input_num); +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + //////// + // You might expect the next line to be equivalent to + // return (int)_tzcnt_u64(input_num); + // but the generated code differs and might be less efficient? + //////// + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return _blsr_u64(input_num); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { + return int(_lzcnt_u64(input_num)); +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_BITMANIPULATION_H +/* end file simdjson/haswell/bitmanipulation.h */ +/* including simdjson/haswell/bitmask.h: #include "simdjson/haswell/bitmask.h" */ +/* begin file simdjson/haswell/bitmask.h */ +#ifndef SIMDJSON_HASWELL_BITMASK_H +#define SIMDJSON_HASWELL_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(const uint64_t bitmask) { + // There should be no such thing with a processor supporting avx2 + // but not clmul. + __m128i all_ones = _mm_set1_epi8('\xFF'); + __m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0ULL, bitmask), all_ones, 0); + return _mm_cvtsi128_si64(result); +} + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_BITMASK_H +/* end file simdjson/haswell/bitmask.h */ +/* including simdjson/haswell/numberparsing_defs.h: #include "simdjson/haswell/numberparsing_defs.h" */ +/* begin file simdjson/haswell/numberparsing_defs.h */ +#ifndef SIMDJSON_HASWELL_NUMBERPARSING_DEFS_H +#define SIMDJSON_HASWELL_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace numberparsing { + +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + // this actually computes *16* values so we are being wasteful. + const __m128i ascii0 = _mm_set1_epi8('0'); + const __m128i mul_1_10 = + _mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1); + const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1); + const __m128i mul_1_10000 = + _mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1); + const __m128i input = _mm_sub_epi8( + _mm_loadu_si128(reinterpret_cast(chars)), ascii0); + const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10); + const __m128i t2 = _mm_madd_epi16(t1, mul_1_100); + const __m128i t3 = _mm_packus_epi32(t2, t2); + const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000); + return _mm_cvtsi128_si32( + t4); // only captures the sum of the first 8 digits, drop the rest +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace haswell +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_HASWELL_NUMBERPARSING_DEFS_H +/* end file simdjson/haswell/numberparsing_defs.h */ +/* including simdjson/haswell/simd.h: #include "simdjson/haswell/simd.h" */ +/* begin file simdjson/haswell/simd.h */ +#ifndef SIMDJSON_HASWELL_SIMD_H +#define SIMDJSON_HASWELL_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace simd { + + // Forward-declared so they can be used by splat and friends. + template + struct base { + __m256i value; + + // Zero constructor + simdjson_inline base() : value{__m256i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m256i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m256i&() const { return this->value; } + simdjson_inline operator __m256i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm256_or_si256(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm256_and_si256(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm256_xor_si256(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm256_andnot_si256(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + // Forward-declared so they can be used by splat and friends. + template + struct simd8; + + template> + struct base8: base> { + typedef uint32_t bitmask_t; + typedef uint64_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m256i _value) : base>(_value) {} + + friend simdjson_really_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return _mm256_cmpeq_epi8(lhs, rhs); } + + static const int SIZE = sizeof(base::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return _mm256_alignr_epi8(*this, _mm256_permute2x128_si256(prev_chunk, *this, 0x21), 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm256_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m256i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { return _mm256_movemask_epi8(*this); } + simdjson_inline bool any() const { return !_mm256_testz_si256(*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm256_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm256_setzero_si256(); } + static simdjson_inline simd8 load(const T values[32]) { + return _mm256_loadu_si256(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m256i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[32]) const { return _mm256_storeu_si256(reinterpret_cast<__m256i *>(dst), *this); } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm256_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm256_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm256_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 32 - count_ones(mask) bytes of the result are significant but 32 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint32_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in four steps, first 8 bytes and then second 8 bytes... + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // second least significant 8 bits + uint8_t mask3 = uint8_t(mask >> 16); // ... + uint8_t mask4 = uint8_t(mask >> 24); // ... + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + __m256i shufmask = _mm256_set_epi64x(thintable_epi8[mask4], thintable_epi8[mask3], + thintable_epi8[mask2], thintable_epi8[mask1]); + // we increment by 0x08 the second half of the mask and so forth + shufmask = + _mm256_add_epi8(shufmask, _mm256_set_epi32(0x18181818, 0x18181818, + 0x10101010, 0x10101010, 0x08080808, 0x08080808, 0, 0)); + // this is the version "nearly pruned" + __m256i pruned = _mm256_shuffle_epi8(*this, shufmask); + // we still need to put the pieces back together. + // we compute the popcount of the first words: + int pop1 = BitsSetTable256mul2[mask1]; + int pop3 = BitsSetTable256mul2[mask3]; + + // then load the corresponding mask + // could be done with _mm256_loadu2_m128i but many standard libraries omit this intrinsic. + __m256i v256 = _mm256_castsi128_si256( + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop1 * 8))); + __m256i compactmask = _mm256_insertf128_si256(v256, + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop3 * 8)), 1); + __m256i almostthere = _mm256_shuffle_epi8(pruned, compactmask); + // We just need to write out the result. + // This is the tricky bit that is hard to do + // if we want to return a SIMD register, since there + // is no single-instruction approach to recombine + // the two 128-bit lanes with an offset. + __m128i v128; + v128 = _mm256_castsi256_si128(almostthere); + _mm_storeu_si128( reinterpret_cast<__m128i *>(output), v128); + v128 = _mm256_extractf128_si256(almostthere, 1); + _mm_storeu_si128( reinterpret_cast<__m128i *>(output + 16 - count_ones(mask & 0xFFFF)), v128); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m256i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t values[32]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15, + int8_t v16, int8_t v17, int8_t v18, int8_t v19, int8_t v20, int8_t v21, int8_t v22, int8_t v23, + int8_t v24, int8_t v25, int8_t v26, int8_t v27, int8_t v28, int8_t v29, int8_t v30, int8_t v31 + ) : simd8(_mm256_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v16,v17,v18,v19,v20,v21,v22,v23, + v24,v25,v26,v27,v28,v29,v30,v31 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm256_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm256_min_epi8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return _mm256_cmpgt_epi8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm256_cmpgt_epi8(other, *this); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m256i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t values[32]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15, + uint8_t v16, uint8_t v17, uint8_t v18, uint8_t v19, uint8_t v20, uint8_t v21, uint8_t v22, uint8_t v23, + uint8_t v24, uint8_t v25, uint8_t v26, uint8_t v27, uint8_t v28, uint8_t v29, uint8_t v30, uint8_t v31 + ) : simd8(_mm256_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v16,v17,v18,v19,v20,v21,v22,v23, + v24,v25,v26,v27,v28,v29,v30,v31 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm256_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm256_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm256_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm256_min_epu8(other, *this); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline simd8 operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline simd8 operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->lt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return *this == uint8_t(0); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + simdjson_inline bool is_ascii() const { return _mm256_movemask_epi8(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { return _mm256_testz_si256(*this, *this); } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return _mm256_testz_si256(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm256_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm256_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline int get_bit() const { return _mm256_movemask_epi8(_mm256_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 2, "Haswell kernel should use two registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1) : chunks{chunk0, chunk1} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+32)} {} + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + uint32_t mask1 = uint32_t(mask); + uint32_t mask2 = uint32_t(mask >> 32); + this->chunks[0].compress(mask1, output); + this->chunks[1].compress(mask2, output + 32 - count_ones(mask1)); + return 64 - count_ones(mask); + } + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r_lo = uint32_t(this->chunks[0].to_bitmask()); + uint64_t r_hi = this->chunks[1].to_bitmask(); + return r_lo | (r_hi << 32); + } + + simdjson_inline simd8 reduce_or() const { + return this->chunks[0] | this->chunks[1]; + } + + simdjson_inline simd8x64 bit_or(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] | mask, + this->chunks[1] | mask + ); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64( + this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1] + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_SIMD_H +/* end file simdjson/haswell/simd.h */ +/* including simdjson/haswell/stringparsing_defs.h: #include "simdjson/haswell/stringparsing_defs.h" */ +/* begin file simdjson/haswell/stringparsing_defs.h */ +#ifndef SIMDJSON_HASWELL_STRINGPARSING_DEFS_H +#define SIMDJSON_HASWELL_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/simd.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return ((quote_bits - 1) & bs_bits) != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 15 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v(src); + // store to dest unconditionally - we can overwrite the bits we don't like later + v.store(dst); + return { + static_cast((v == '\\').to_bitmask()), // bs_bits + static_cast((v == '"').to_bitmask()), // quote_bits + }; +} + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_STRINGPARSING_DEFS_H +/* end file simdjson/haswell/stringparsing_defs.h */ +/* end file simdjson/haswell/begin.h */ +/* including generic/amalgamated.h for haswell: #include */ +/* begin file generic/amalgamated.h for haswell */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_SRC_GENERIC_DEPENDENCIES_H) +#error generic/dependencies.h must be included before generic/amalgamated.h! +#endif + +/* including generic/base.h for haswell: #include */ +/* begin file generic/base.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { + +struct json_character_block; + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_BASE_H +/* end file generic/base.h for haswell */ +/* including generic/dom_parser_implementation.h for haswell: #include */ +/* begin file generic/dom_parser_implementation.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// Interface a dom parser implementation must fulfill +namespace simdjson { +namespace haswell { +namespace { + +simdjson_inline simd8 must_be_2_3_continuation(const simd8 prev2, const simd8 prev3); +simdjson_inline bool is_ascii(const simd8x64& input); + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file generic/dom_parser_implementation.h for haswell */ +/* including generic/json_character_block.h for haswell: #include */ +/* begin file generic/json_character_block.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { + +struct json_character_block { + static simdjson_inline json_character_block classify(const simd::simd8x64& in); + + simdjson_inline uint64_t whitespace() const noexcept { return _whitespace; } + simdjson_inline uint64_t op() const noexcept { return _op; } + simdjson_inline uint64_t scalar() const noexcept { return ~(op() | whitespace()); } + + uint64_t _whitespace; + uint64_t _op; +}; + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H +/* end file generic/json_character_block.h for haswell */ +/* end file generic/amalgamated.h for haswell */ +/* including generic/stage1/amalgamated.h for haswell: #include */ +/* begin file generic/stage1/amalgamated.h for haswell */ +// Stuff other things depend on +/* including generic/stage1/base.h for haswell: #include */ +/* begin file generic/stage1/base.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace stage1 { + +class bit_indexer; +template +struct buf_block_reader; +struct json_block; +class json_minifier; +class json_scanner; +struct json_string_block; +class json_string_scanner; +class json_structural_indexer; + +} // namespace stage1 + +namespace utf8_validation { +struct utf8_checker; +} // namespace utf8_validation + +using utf8_validation::utf8_checker; + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_BASE_H +/* end file generic/stage1/base.h for haswell */ +/* including generic/stage1/buf_block_reader.h for haswell: #include */ +/* begin file generic/stage1/buf_block_reader.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace haswell { +namespace { +namespace stage1 { + +// Walks through a buffer in block-sized increments, loading the last part with spaces +template +struct buf_block_reader { +public: + simdjson_inline buf_block_reader(const uint8_t *_buf, size_t _len); + simdjson_inline size_t block_index(); + simdjson_inline bool has_full_block() const; + simdjson_inline const uint8_t *full_block() const; + /** + * Get the last block, padded with spaces. + * + * There will always be a last block, with at least 1 byte, unless len == 0 (in which case this + * function fills the buffer with spaces and returns 0. In particular, if len == STEP_SIZE there + * will be 0 full_blocks and 1 remainder block with STEP_SIZE bytes and no spaces for padding. + * + * @return the number of effective characters in the last block. + */ + simdjson_inline size_t get_remainder(uint8_t *dst) const; + simdjson_inline void advance(); +private: + const uint8_t *buf; + const size_t len; + const size_t lenminusstep; + size_t idx; +}; + +// Routines to print masks and text for debugging bitmask operations +simdjson_unused static char * format_input_text_64(const uint8_t *text) { + static char buf[sizeof(simd8x64) + 1]; + for (size_t i=0; i); i++) { + buf[i] = int8_t(text[i]) < ' ' ? '_' : int8_t(text[i]); + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +// Routines to print masks and text for debugging bitmask operations +simdjson_unused static char * format_input_text(const simd8x64& in) { + static char buf[sizeof(simd8x64) + 1]; + in.store(reinterpret_cast(buf)); + for (size_t i=0; i); i++) { + if (buf[i] < ' ') { buf[i] = '_'; } + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +simdjson_unused static char * format_input_text(const simd8x64& in, uint64_t mask) { + static char buf[sizeof(simd8x64) + 1]; + in.store(reinterpret_cast(buf)); + for (size_t i=0; i); i++) { + if (buf[i] <= ' ') { buf[i] = '_'; } + if (!(mask & (size_t(1) << i))) { buf[i] = ' '; } + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +simdjson_unused static char * format_mask(uint64_t mask) { + static char buf[sizeof(simd8x64) + 1]; + for (size_t i=0; i<64; i++) { + buf[i] = (mask & (size_t(1) << i)) ? 'X' : ' '; + } + buf[64] = '\0'; + return buf; +} + +template +simdjson_inline buf_block_reader::buf_block_reader(const uint8_t *_buf, size_t _len) : buf{_buf}, len{_len}, lenminusstep{len < STEP_SIZE ? 0 : len - STEP_SIZE}, idx{0} {} + +template +simdjson_inline size_t buf_block_reader::block_index() { return idx; } + +template +simdjson_inline bool buf_block_reader::has_full_block() const { + return idx < lenminusstep; +} + +template +simdjson_inline const uint8_t *buf_block_reader::full_block() const { + return &buf[idx]; +} + +template +simdjson_inline size_t buf_block_reader::get_remainder(uint8_t *dst) const { + if(len == idx) { return 0; } // memcpy(dst, null, 0) will trigger an error with some sanitizers + std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it's more efficient to write out 8 or 16 bytes at once. + std::memcpy(dst, buf + idx, len - idx); + return len - idx; +} + +template +simdjson_inline void buf_block_reader::advance() { + idx += STEP_SIZE; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H +/* end file generic/stage1/buf_block_reader.h for haswell */ +/* including generic/stage1/json_escape_scanner.h for haswell: #include */ +/* begin file generic/stage1/json_escape_scanner.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_ESCAPE_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_ESCAPE_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace stage1 { + +/** + * Scans for escape characters in JSON, taking care with multiple backslashes (\\n vs. \n). + */ +struct json_escape_scanner { + /** The actual escape characters (the backslashes themselves). */ + uint64_t next_is_escaped = 0ULL; + + struct escaped_and_escape { + /** + * Mask of escaped characters. + * + * ``` + * \n \\n \\\n \\\\n \ + * 0100100010100101000 + * n \ \ n \ \ + * ``` + */ + uint64_t escaped; + /** + * Mask of escape characters. + * + * ``` + * \n \\n \\\n \\\\n \ + * 1001000101001010001 + * \ \ \ \ \ \ \ + * ``` + */ + uint64_t escape; + }; + + /** + * Get a mask of both escape and escaped characters (the characters following a backslash). + * + * @param potential_escape A mask of the character that can escape others (but could be + * escaped itself). e.g. block.eq('\\') + */ + simdjson_really_inline escaped_and_escape next(uint64_t backslash) noexcept { + +#if !SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT + if (!backslash) { return {next_escaped_without_backslashes(), 0}; } +#endif + + // | | Mask (shows characters instead of 1's) | Depth | Instructions | + // |--------------------------------|----------------------------------------|-------|---------------------| + // | string | `\\n_\\\n___\\\n___\\\\___\\\\__\\\` | | | + // | | ` even odd even odd odd` | | | + // | potential_escape | ` \ \\\ \\\ \\\\ \\\\ \\\` | 1 | 1 (backslash & ~first_is_escaped) + // | escape_and_terminal_code | ` \n \ \n \ \n \ \ \ \ \ \` | 5 | 5 (next_escape_and_terminal_code()) + // | escaped | `\ \ n \ n \ \ \ \ \ ` X | 6 | 7 (escape_and_terminal_code ^ (potential_escape | first_is_escaped)) + // | escape | ` \ \ \ \ \ \ \ \ \ \` | 6 | 8 (escape_and_terminal_code & backslash) + // | first_is_escaped | `\ ` | 7 (*) | 9 (escape >> 63) () + // (*) this is not needed until the next iteration + uint64_t escape_and_terminal_code = next_escape_and_terminal_code(backslash & ~this->next_is_escaped); + uint64_t escaped = escape_and_terminal_code ^ (backslash | this->next_is_escaped); + uint64_t escape = escape_and_terminal_code & backslash; + this->next_is_escaped = escape >> 63; + return {escaped, escape}; + } + +private: + static constexpr const uint64_t ODD_BITS = 0xAAAAAAAAAAAAAAAAULL; + + simdjson_really_inline uint64_t next_escaped_without_backslashes() noexcept { + uint64_t escaped = this->next_is_escaped; + this->next_is_escaped = 0; + return escaped; + } + + /** + * Returns a mask of the next escape characters (masking out escaped backslashes), along with + * any non-backslash escape codes. + * + * \n \\n \\\n \\\\n returns: + * \n \ \ \n \ \ + * 11 100 1011 10100 + * + * You are expected to mask out the first bit yourself if the previous block had a trailing + * escape. + * + * & the result with potential_escape to get just the escape characters. + * ^ the result with (potential_escape | first_is_escaped) to get escaped characters. + */ + static simdjson_really_inline uint64_t next_escape_and_terminal_code(uint64_t potential_escape) noexcept { + // If we were to just shift and mask out any odd bits, we'd actually get a *half* right answer: + // any even-aligned backslash runs would be correct! Odd-aligned backslash runs would be + // inverted (\\\ would be 010 instead of 101). + // + // ``` + // string: | ____\\\\_\\\\_____ | + // maybe_escaped | ODD | \ \ \ \ | + // even-aligned ^^^ ^^^^ odd-aligned + // ``` + // + // Taking that into account, our basic strategy is: + // + // 1. Use subtraction to produce a mask with 1's for even-aligned runs and 0's for + // odd-aligned runs. + // 2. XOR all odd bits, which masks out the odd bits in even-aligned runs, and brings IN the + // odd bits in odd-aligned runs. + // 3. & with backslash to clean up any stray bits. + // runs are set to 0, and then XORing with "odd": + // + // | | Mask (shows characters instead of 1's) | Instructions | + // |--------------------------------|----------------------------------------|---------------------| + // | string | `\\n_\\\n___\\\n___\\\\___\\\\__\\\` | + // | | ` even odd even odd odd` | + // | maybe_escaped | ` n \\n \\n \\\_ \\\_ \\` X | 1 (potential_escape << 1) + // | maybe_escaped_and_odd | ` \n_ \\n _ \\\n_ _ \\\__ _\\\_ \\\` | 1 (maybe_escaped | odd) + // | even_series_codes_and_odd | ` n_\\\ _ n_ _\\\\ _ _ ` | 1 (maybe_escaped_and_odd - potential_escape) + // | escape_and_terminal_code | ` \n \ \n \ \n \ \ \ \ \ \` | 1 (^ odd) + // + + // Escaped characters are characters following an escape. + uint64_t maybe_escaped = potential_escape << 1; + + // To distinguish odd from even escape sequences, therefore, we turn on any *starting* + // escapes that are on an odd byte. (We actually bring in all odd bits, for speed.) + // - Odd runs of backslashes are 0000, and the code at the end ("n" in \n or \\n) is 1. + // - Odd runs of backslashes are 1111, and the code at the end ("n" in \n or \\n) is 0. + // - All other odd bytes are 1, and even bytes are 0. + uint64_t maybe_escaped_and_odd_bits = maybe_escaped | ODD_BITS; + uint64_t even_series_codes_and_odd_bits = maybe_escaped_and_odd_bits - potential_escape; + + // Now we flip all odd bytes back with xor. This: + // - Makes odd runs of backslashes go from 0000 to 1010 + // - Makes even runs of backslashes go from 1111 to 1010 + // - Sets actually-escaped codes to 1 (the n in \n and \\n: \n = 11, \\n = 100) + // - Resets all other bytes to 0 + return even_series_codes_and_odd_bits ^ ODD_BITS; + } +}; + +} // namespace stage1 +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H +/* end file generic/stage1/json_escape_scanner.h for haswell */ +/* including generic/stage1/json_string_scanner.h for haswell: #include */ +/* begin file generic/stage1/json_string_scanner.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace stage1 { + +struct json_string_block { + // We spell out the constructors in the hope of resolving inlining issues with Visual Studio 2017 + simdjson_really_inline json_string_block(uint64_t escaped, uint64_t quote, uint64_t in_string) : + _escaped(escaped), _quote(quote), _in_string(in_string) {} + + // Escaped characters (characters following an escape() character) + simdjson_really_inline uint64_t escaped() const { return _escaped; } + // Real (non-backslashed) quotes + simdjson_really_inline uint64_t quote() const { return _quote; } + // Only characters inside the string (not including the quotes) + simdjson_really_inline uint64_t string_content() const { return _in_string & ~_quote; } + // Return a mask of whether the given characters are inside a string (only works on non-quotes) + simdjson_really_inline uint64_t non_quote_inside_string(uint64_t mask) const { return mask & _in_string; } + // Return a mask of whether the given characters are inside a string (only works on non-quotes) + simdjson_really_inline uint64_t non_quote_outside_string(uint64_t mask) const { return mask & ~_in_string; } + // Tail of string (everything except the start quote) + simdjson_really_inline uint64_t string_tail() const { return _in_string ^ _quote; } + + // escaped characters (backslashed--does not include the hex characters after \u) + uint64_t _escaped; + // real quotes (non-escaped ones) + uint64_t _quote; + // string characters (includes start quote but not end quote) + uint64_t _in_string; +}; + +// Scans blocks for string characters, storing the state necessary to do so +class json_string_scanner { +public: + simdjson_really_inline json_string_block next(const simd::simd8x64& in); + // Returns either UNCLOSED_STRING or SUCCESS + simdjson_really_inline error_code finish(); + +private: + // Scans for escape characters + json_escape_scanner escape_scanner{}; + // Whether the last iteration was still inside a string (all 1's = true, all 0's = false). + uint64_t prev_in_string = 0ULL; +}; + +// +// Return a mask of all string characters plus end quotes. +// +// prev_escaped is overflow saying whether the next character is escaped. +// prev_in_string is overflow saying whether we're still in a string. +// +// Backslash sequences outside of quotes will be detected in stage 2. +// +simdjson_really_inline json_string_block json_string_scanner::next(const simd::simd8x64& in) { + const uint64_t backslash = in.eq('\\'); + const uint64_t escaped = escape_scanner.next(backslash).escaped; + const uint64_t quote = in.eq('"') & ~escaped; + + // + // prefix_xor flips on bits inside the string (and flips off the end quote). + // + // Then we xor with prev_in_string: if we were in a string already, its effect is flipped + // (characters inside strings are outside, and characters outside strings are inside). + // + const uint64_t in_string = prefix_xor(quote) ^ prev_in_string; + + // + // Check if we're still in a string at the end of the box so the next block will know + // + prev_in_string = uint64_t(static_cast(in_string) >> 63); + + // Use ^ to turn the beginning quote off, and the end quote on. + + // We are returning a function-local object so either we get a move constructor + // or we get copy elision. + return json_string_block(escaped, quote, in_string); +} + +simdjson_really_inline error_code json_string_scanner::finish() { + if (prev_in_string) { + return UNCLOSED_STRING; + } + return SUCCESS; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H +/* end file generic/stage1/json_string_scanner.h for haswell */ +/* including generic/stage1/utf8_lookup4_algorithm.h for haswell: #include */ +/* begin file generic/stage1/utf8_lookup4_algorithm.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace utf8_validation { + +using namespace simd; + + simdjson_inline simd8 check_special_cases(const simd8 input, const simd8 prev1) { +// Bit 0 = Too Short (lead byte/ASCII followed by lead byte/ASCII) +// Bit 1 = Too Long (ASCII followed by continuation) +// Bit 2 = Overlong 3-byte +// Bit 4 = Surrogate +// Bit 5 = Overlong 2-byte +// Bit 7 = Two Continuations + constexpr const uint8_t TOO_SHORT = 1<<0; // 11______ 0_______ + // 11______ 11______ + constexpr const uint8_t TOO_LONG = 1<<1; // 0_______ 10______ + constexpr const uint8_t OVERLONG_3 = 1<<2; // 11100000 100_____ + constexpr const uint8_t SURROGATE = 1<<4; // 11101101 101_____ + constexpr const uint8_t OVERLONG_2 = 1<<5; // 1100000_ 10______ + constexpr const uint8_t TWO_CONTS = 1<<7; // 10______ 10______ + constexpr const uint8_t TOO_LARGE = 1<<3; // 11110100 1001____ + // 11110100 101_____ + // 11110101 1001____ + // 11110101 101_____ + // 1111011_ 1001____ + // 1111011_ 101_____ + // 11111___ 1001____ + // 11111___ 101_____ + constexpr const uint8_t TOO_LARGE_1000 = 1<<6; + // 11110101 1000____ + // 1111011_ 1000____ + // 11111___ 1000____ + constexpr const uint8_t OVERLONG_4 = 1<<6; // 11110000 1000____ + + const simd8 byte_1_high = prev1.shr<4>().lookup_16( + // 0_______ ________ + TOO_LONG, TOO_LONG, TOO_LONG, TOO_LONG, + TOO_LONG, TOO_LONG, TOO_LONG, TOO_LONG, + // 10______ ________ + TWO_CONTS, TWO_CONTS, TWO_CONTS, TWO_CONTS, + // 1100____ ________ + TOO_SHORT | OVERLONG_2, + // 1101____ ________ + TOO_SHORT, + // 1110____ ________ + TOO_SHORT | OVERLONG_3 | SURROGATE, + // 1111____ ________ + TOO_SHORT | TOO_LARGE | TOO_LARGE_1000 | OVERLONG_4 + ); + constexpr const uint8_t CARRY = TOO_SHORT | TOO_LONG | TWO_CONTS; // These all have ____ in byte 1 . + const simd8 byte_1_low = (prev1 & 0x0F).lookup_16( + // ____0000 ________ + CARRY | OVERLONG_3 | OVERLONG_2 | OVERLONG_4, + // ____0001 ________ + CARRY | OVERLONG_2, + // ____001_ ________ + CARRY, + CARRY, + + // ____0100 ________ + CARRY | TOO_LARGE, + // ____0101 ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + // ____011_ ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + + // ____1___ ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + // ____1101 ________ + CARRY | TOO_LARGE | TOO_LARGE_1000 | SURROGATE, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000 + ); + const simd8 byte_2_high = input.shr<4>().lookup_16( + // ________ 0_______ + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT, + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT, + + // ________ 1000____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | OVERLONG_3 | TOO_LARGE_1000 | OVERLONG_4, + // ________ 1001____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | OVERLONG_3 | TOO_LARGE, + // ________ 101_____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | SURROGATE | TOO_LARGE, + TOO_LONG | OVERLONG_2 | TWO_CONTS | SURROGATE | TOO_LARGE, + + // ________ 11______ + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT + ); + return (byte_1_high & byte_1_low & byte_2_high); + } + simdjson_inline simd8 check_multibyte_lengths(const simd8 input, + const simd8 prev_input, const simd8 sc) { + simd8 prev2 = input.prev<2>(prev_input); + simd8 prev3 = input.prev<3>(prev_input); + simd8 must23 = simd8(must_be_2_3_continuation(prev2, prev3)); + simd8 must23_80 = must23 & uint8_t(0x80); + return must23_80 ^ sc; + } + + // + // Return nonzero if there are incomplete multibyte characters at the end of the block: + // e.g. if there is a 4-byte character, but it's 3 bytes from the end. + // + simdjson_inline simd8 is_incomplete(const simd8 input) { + // If the previous input's last 3 bytes match this, they're too short (they ended at EOF): + // ... 1111____ 111_____ 11______ +#if SIMDJSON_IMPLEMENTATION_ICELAKE + static const uint8_t max_array[64] = { + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 0xf0u-1, 0xe0u-1, 0xc0u-1 + }; +#else + static const uint8_t max_array[32] = { + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 0xf0u-1, 0xe0u-1, 0xc0u-1 + }; +#endif + const simd8 max_value(&max_array[sizeof(max_array)-sizeof(simd8)]); + return input.gt_bits(max_value); + } + + struct utf8_checker { + // If this is nonzero, there has been a UTF-8 error. + simd8 error; + // The last input we received + simd8 prev_input_block; + // Whether the last input we received was incomplete (used for ASCII fast path) + simd8 prev_incomplete; + + // + // Check whether the current bytes are valid UTF-8. + // + simdjson_inline void check_utf8_bytes(const simd8 input, const simd8 prev_input) { + // Flip prev1...prev3 so we can easily determine if they are 2+, 3+ or 4+ lead bytes + // (2, 3, 4-byte leads become large positive numbers instead of small negative numbers) + simd8 prev1 = input.prev<1>(prev_input); + simd8 sc = check_special_cases(input, prev1); + this->error |= check_multibyte_lengths(input, prev_input, sc); + } + + // The only problem that can happen at EOF is that a multibyte character is too short + // or a byte value too large in the last bytes: check_special_cases only checks for bytes + // too large in the first of two bytes. + simdjson_inline void check_eof() { + // If the previous block had incomplete UTF-8 characters at the end, an ASCII block can't + // possibly finish them. + this->error |= this->prev_incomplete; + } + + simdjson_inline void check_next_input(const simd8x64& input) { + if(simdjson_likely(is_ascii(input))) { + this->error |= this->prev_incomplete; + } else { + // you might think that a for-loop would work, but under Visual Studio, it is not good enough. + static_assert((simd8x64::NUM_CHUNKS == 1) + ||(simd8x64::NUM_CHUNKS == 2) + || (simd8x64::NUM_CHUNKS == 4), + "We support one, two or four chunks per 64-byte block."); + SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 1) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + } else SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 2) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + this->check_utf8_bytes(input.chunks[1], input.chunks[0]); + } else SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 4) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + this->check_utf8_bytes(input.chunks[1], input.chunks[0]); + this->check_utf8_bytes(input.chunks[2], input.chunks[1]); + this->check_utf8_bytes(input.chunks[3], input.chunks[2]); + } + this->prev_incomplete = is_incomplete(input.chunks[simd8x64::NUM_CHUNKS-1]); + this->prev_input_block = input.chunks[simd8x64::NUM_CHUNKS-1]; + } + } + // do not forget to call check_eof! + simdjson_inline error_code errors() { + return this->error.any_bits_set_anywhere() ? error_code::UTF8_ERROR : error_code::SUCCESS; + } + + }; // struct utf8_checker +} // namespace utf8_validation + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H +/* end file generic/stage1/utf8_lookup4_algorithm.h for haswell */ +/* including generic/stage1/json_scanner.h for haswell: #include */ +/* begin file generic/stage1/json_scanner.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace stage1 { + +/** + * A block of scanned json, with information on operators and scalars. + * + * We seek to identify pseudo-structural characters. Anything that is inside + * a string must be omitted (hence & ~_string.string_tail()). + * Otherwise, pseudo-structural characters come in two forms. + * 1. We have the structural characters ([,],{,},:, comma). The + * term 'structural character' is from the JSON RFC. + * 2. We have the 'scalar pseudo-structural characters'. + * Scalars are quotes, and any character except structural characters and white space. + * + * To identify the scalar pseudo-structural characters, we must look at what comes + * before them: it must be a space, a quote or a structural characters. + * Starting with simdjson v0.3, we identify them by + * negation: we identify everything that is followed by a non-quote scalar, + * and we negate that. Whatever remains must be a 'scalar pseudo-structural character'. + */ +struct json_block { +public: + // We spell out the constructors in the hope of resolving inlining issues with Visual Studio 2017 + simdjson_inline json_block(json_string_block&& string, json_character_block characters, uint64_t follows_potential_nonquote_scalar) : + _string(std::move(string)), _characters(characters), _follows_potential_nonquote_scalar(follows_potential_nonquote_scalar) {} + simdjson_inline json_block(json_string_block string, json_character_block characters, uint64_t follows_potential_nonquote_scalar) : + _string(string), _characters(characters), _follows_potential_nonquote_scalar(follows_potential_nonquote_scalar) {} + + /** + * The start of structurals. + * In simdjson prior to v0.3, these were called the pseudo-structural characters. + **/ + simdjson_inline uint64_t structural_start() const noexcept { return potential_structural_start() & ~_string.string_tail(); } + /** All JSON whitespace (i.e. not in a string) */ + simdjson_inline uint64_t whitespace() const noexcept { return non_quote_outside_string(_characters.whitespace()); } + + // Helpers + + /** Whether the given characters are inside a string (only works on non-quotes) */ + simdjson_inline uint64_t non_quote_inside_string(uint64_t mask) const noexcept { return _string.non_quote_inside_string(mask); } + /** Whether the given characters are outside a string (only works on non-quotes) */ + simdjson_inline uint64_t non_quote_outside_string(uint64_t mask) const noexcept { return _string.non_quote_outside_string(mask); } + + // string and escape characters + json_string_block _string; + // whitespace, structural characters ('operators'), scalars + json_character_block _characters; + // whether the previous character was a scalar + uint64_t _follows_potential_nonquote_scalar; +private: + // Potential structurals (i.e. disregarding strings) + + /** + * structural elements ([,],{,},:, comma) plus scalar starts like 123, true and "abc". + * They may reside inside a string. + **/ + simdjson_inline uint64_t potential_structural_start() const noexcept { return _characters.op() | potential_scalar_start(); } + /** + * The start of non-operator runs, like 123, true and "abc". + * It main reside inside a string. + **/ + simdjson_inline uint64_t potential_scalar_start() const noexcept { + // The term "scalar" refers to anything except structural characters and white space + // (so letters, numbers, quotes). + // Whenever it is preceded by something that is not a structural element ({,},[,],:, ") nor a white-space + // then we know that it is irrelevant structurally. + return _characters.scalar() & ~follows_potential_scalar(); + } + /** + * Whether the given character is immediately after a non-operator like 123, true. + * The characters following a quote are not included. + */ + simdjson_inline uint64_t follows_potential_scalar() const noexcept { + // _follows_potential_nonquote_scalar: is defined as marking any character that follows a character + // that is not a structural element ({,},[,],:, comma) nor a quote (") and that is not a + // white space. + // It is understood that within quoted region, anything at all could be marked (irrelevant). + return _follows_potential_nonquote_scalar; + } +}; + +/** + * Scans JSON for important bits: structural characters or 'operators', strings, and scalars. + * + * The scanner starts by calculating two distinct things: + * - string characters (taking \" into account) + * - structural characters or 'operators' ([]{},:, comma) + * and scalars (runs of non-operators like 123, true and "abc") + * + * To minimize data dependency (a key component of the scanner's speed), it finds these in parallel: + * in particular, the operator/scalar bit will find plenty of things that are actually part of + * strings. When we're done, json_block will fuse the two together by masking out tokens that are + * part of a string. + */ +class json_scanner { +public: + json_scanner() = default; + simdjson_inline json_block next(const simd::simd8x64& in); + // Returns either UNCLOSED_STRING or SUCCESS + simdjson_inline error_code finish(); + +private: + // Whether the last character of the previous iteration is part of a scalar token + // (anything except whitespace or a structural character/'operator'). + uint64_t prev_scalar = 0ULL; + json_string_scanner string_scanner{}; +}; + + +// +// Check if the current character immediately follows a matching character. +// +// For example, this checks for quotes with backslashes in front of them: +// +// const uint64_t backslashed_quote = in.eq('"') & immediately_follows(in.eq('\'), prev_backslash); +// +simdjson_inline uint64_t follows(const uint64_t match, uint64_t &overflow) { + const uint64_t result = match << 1 | overflow; + overflow = match >> 63; + return result; +} + +simdjson_inline json_block json_scanner::next(const simd::simd8x64& in) { + json_string_block strings = string_scanner.next(in); + // identifies the white-space and the structural characters + json_character_block characters = json_character_block::classify(in); + // The term "scalar" refers to anything except structural characters and white space + // (so letters, numbers, quotes). + // We want follows_scalar to mark anything that follows a non-quote scalar (so letters and numbers). + // + // A terminal quote should either be followed by a structural character (comma, brace, bracket, colon) + // or nothing. However, we still want ' "a string"true ' to mark the 't' of 'true' as a potential + // pseudo-structural character just like we would if we had ' "a string" true '; otherwise we + // may need to add an extra check when parsing strings. + // + // Performance: there are many ways to skin this cat. + const uint64_t nonquote_scalar = characters.scalar() & ~strings.quote(); + uint64_t follows_nonquote_scalar = follows(nonquote_scalar, prev_scalar); + // We are returning a function-local object so either we get a move constructor + // or we get copy elision. + return json_block( + strings,// strings is a function-local object so either it moves or the copy is elided. + characters, + follows_nonquote_scalar + ); +} + +simdjson_inline error_code json_scanner::finish() { + return string_scanner.finish(); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H +/* end file generic/stage1/json_scanner.h for haswell */ + +// All other declarations +/* including generic/stage1/find_next_document_index.h for haswell: #include */ +/* begin file generic/stage1/find_next_document_index.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace stage1 { + +/** + * This algorithm is used to quickly identify the last structural position that + * makes up a complete document. + * + * It does this by going backwards and finding the last *document boundary* (a + * place where one value follows another without a comma between them). If the + * last document (the characters after the boundary) has an equal number of + * start and end brackets, it is considered complete. + * + * Simply put, we iterate over the structural characters, starting from + * the end. We consider that we found the end of a JSON document when the + * first element of the pair is NOT one of these characters: '{' '[' ':' ',' + * and when the second element is NOT one of these characters: '}' ']' ':' ','. + * + * This simple comparison works most of the time, but it does not cover cases + * where the batch's structural indexes contain a perfect amount of documents. + * In such a case, we do not have access to the structural index which follows + * the last document, therefore, we do not have access to the second element in + * the pair, and that means we cannot identify the last document. To fix this + * issue, we keep a count of the open and closed curly/square braces we found + * while searching for the pair. When we find a pair AND the count of open and + * closed curly/square braces is the same, we know that we just passed a + * complete document, therefore the last json buffer location is the end of the + * batch. + */ +simdjson_inline uint32_t find_next_document_index(dom_parser_implementation &parser) { + // Variant: do not count separately, just figure out depth + if(parser.n_structural_indexes == 0) { return 0; } + auto arr_cnt = 0; + auto obj_cnt = 0; + for (auto i = parser.n_structural_indexes - 1; i > 0; i--) { + auto idxb = parser.structural_indexes[i]; + switch (parser.buf[idxb]) { + case ':': + case ',': + continue; + case '}': + obj_cnt--; + continue; + case ']': + arr_cnt--; + continue; + case '{': + obj_cnt++; + break; + case '[': + arr_cnt++; + break; + } + auto idxa = parser.structural_indexes[i - 1]; + switch (parser.buf[idxa]) { + case '{': + case '[': + case ':': + case ',': + continue; + } + // Last document is complete, so the next document will appear after! + if (!arr_cnt && !obj_cnt) { + return parser.n_structural_indexes; + } + // Last document is incomplete; mark the document at i + 1 as the next one + return i; + } + // If we made it to the end, we want to finish counting to see if we have a full document. + switch (parser.buf[parser.structural_indexes[0]]) { + case '}': + obj_cnt--; + break; + case ']': + arr_cnt--; + break; + case '{': + obj_cnt++; + break; + case '[': + arr_cnt++; + break; + } + if (!arr_cnt && !obj_cnt) { + // We have a complete document. + return parser.n_structural_indexes; + } + return 0; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H +/* end file generic/stage1/find_next_document_index.h for haswell */ +/* including generic/stage1/json_minifier.h for haswell: #include */ +/* begin file generic/stage1/json_minifier.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses in stage1 +// It is intended to be included multiple times and compiled multiple times +// We assume the file in which it is included already includes +// "simdjson/stage1.h" (this simplifies amalgation) + +namespace simdjson { +namespace haswell { +namespace { +namespace stage1 { + +class json_minifier { +public: + template + static error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept; + +private: + simdjson_inline json_minifier(uint8_t *_dst) + : dst{_dst} + {} + template + simdjson_inline void step(const uint8_t *block_buf, buf_block_reader &reader) noexcept; + simdjson_inline void next(const simd::simd8x64& in, const json_block& block); + simdjson_inline error_code finish(uint8_t *dst_start, size_t &dst_len); + json_scanner scanner{}; + uint8_t *dst; +}; + +simdjson_inline void json_minifier::next(const simd::simd8x64& in, const json_block& block) { + uint64_t mask = block.whitespace(); + dst += in.compress(mask, dst); +} + +simdjson_inline error_code json_minifier::finish(uint8_t *dst_start, size_t &dst_len) { + error_code error = scanner.finish(); + if (error) { dst_len = 0; return error; } + dst_len = dst - dst_start; + return SUCCESS; +} + +template<> +simdjson_inline void json_minifier::step<128>(const uint8_t *block_buf, buf_block_reader<128> &reader) noexcept { + simd::simd8x64 in_1(block_buf); + simd::simd8x64 in_2(block_buf+64); + json_block block_1 = scanner.next(in_1); + json_block block_2 = scanner.next(in_2); + this->next(in_1, block_1); + this->next(in_2, block_2); + reader.advance(); +} + +template<> +simdjson_inline void json_minifier::step<64>(const uint8_t *block_buf, buf_block_reader<64> &reader) noexcept { + simd::simd8x64 in_1(block_buf); + json_block block_1 = scanner.next(in_1); + this->next(block_buf, block_1); + reader.advance(); +} + +template +error_code json_minifier::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept { + buf_block_reader reader(buf, len); + json_minifier minifier(dst); + + // Index the first n-1 blocks + while (reader.has_full_block()) { + minifier.step(reader.full_block(), reader); + } + + // Index the last (remainder) block, padded with spaces + uint8_t block[STEP_SIZE]; + size_t remaining_bytes = reader.get_remainder(block); + if (remaining_bytes > 0) { + // We do not want to write directly to the output stream. Rather, we write + // to a local buffer (for safety). + uint8_t out_block[STEP_SIZE]; + uint8_t * const guarded_dst{minifier.dst}; + minifier.dst = out_block; + minifier.step(block, reader); + size_t to_write = minifier.dst - out_block; + // In some cases, we could be enticed to consider the padded spaces + // as part of the string. This is fine as long as we do not write more + // than we consumed. + if(to_write > remaining_bytes) { to_write = remaining_bytes; } + memcpy(guarded_dst, out_block, to_write); + minifier.dst = guarded_dst + to_write; + } + return minifier.finish(dst, dst_len); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H +/* end file generic/stage1/json_minifier.h for haswell */ +/* including generic/stage1/json_structural_indexer.h for haswell: #include */ +/* begin file generic/stage1/json_structural_indexer.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses in stage1 +// It is intended to be included multiple times and compiled multiple times +// We assume the file in which it is included already includes +// "simdjson/stage1.h" (this simplifies amalgation) + +namespace simdjson { +namespace haswell { +namespace { +namespace stage1 { + +class bit_indexer { +public: + uint32_t *tail; + + simdjson_inline bit_indexer(uint32_t *index_buf) : tail(index_buf) {} + +#if SIMDJSON_PREFER_REVERSE_BITS + /** + * ARM lacks a fast trailing zero instruction, but it has a fast + * bit reversal instruction and a fast leading zero instruction. + * Thus it may be profitable to reverse the bits (once) and then + * to rely on a sequence of instructions that call the leading + * zero instruction. + * + * Performance notes: + * The chosen routine is not optimal in terms of data dependency + * since zero_leading_bit might require two instructions. However, + * it tends to minimize the total number of instructions which is + * beneficial. + */ + simdjson_inline void write_index(uint32_t idx, uint64_t& rev_bits, int i) { + int lz = leading_zeroes(rev_bits); + this->tail[i] = static_cast(idx) + lz; + rev_bits = zero_leading_bit(rev_bits, lz); + } +#else + /** + * Under recent x64 systems, we often have both a fast trailing zero + * instruction and a fast 'clear-lower-bit' instruction so the following + * algorithm can be competitive. + */ + + simdjson_inline void write_index(uint32_t idx, uint64_t& bits, int i) { + this->tail[i] = idx + trailing_zeroes(bits); + bits = clear_lowest_bit(bits); + } +#endif // SIMDJSON_PREFER_REVERSE_BITS + + template + simdjson_inline int write_indexes(uint32_t idx, uint64_t& bits) { + write_index(idx, bits, START); + SIMDJSON_IF_CONSTEXPR (N > 1) { + write_indexes<(N-1>0?START+1:START), (N-1>=0?N-1:1)>(idx, bits); + } + return START+N; + } + + template + simdjson_inline int write_indexes_stepped(uint32_t idx, uint64_t& bits, int cnt) { + write_indexes(idx, bits); + SIMDJSON_IF_CONSTEXPR ((START+STEP) < END) { + if (simdjson_unlikely((START+STEP) < cnt)) { + write_indexes_stepped<(START+STEP(idx, bits, cnt); + } + } + return ((END-START) % STEP) == 0 ? END : (END-START) - ((END-START) % STEP) + STEP; + } + + // flatten out values in 'bits' assuming that they are are to have values of idx + // plus their position in the bitvector, and store these indexes at + // base_ptr[base] incrementing base as we go + // will potentially store extra values beyond end of valid bits, so base_ptr + // needs to be large enough to handle this + // + // If the kernel sets SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER, then it + // will provide its own version of the code. +#ifdef SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + simdjson_inline void write(uint32_t idx, uint64_t bits); +#else + simdjson_inline void write(uint32_t idx, uint64_t bits) { + // In some instances, the next branch is expensive because it is mispredicted. + // Unfortunately, in other cases, + // it helps tremendously. + if (bits == 0) + return; + + int cnt = static_cast(count_ones(bits)); + +#if SIMDJSON_PREFER_REVERSE_BITS + bits = reverse_bits(bits); +#endif +#ifdef SIMDJSON_STRUCTURAL_INDEXER_STEP + static constexpr const int STEP = SIMDJSON_STRUCTURAL_INDEXER_STEP; +#else + static constexpr const int STEP = 4; +#endif + static constexpr const int STEP_UNTIL = 24; + + write_indexes_stepped<0, STEP_UNTIL, STEP>(idx, bits, cnt); + SIMDJSON_IF_CONSTEXPR (STEP_UNTIL < 64) { + if (simdjson_unlikely(STEP_UNTIL < cnt)) { + for (int i=STEP_UNTIL; itail += cnt; + } +#endif // SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + +}; + +class json_structural_indexer { +public: + /** + * Find the important bits of JSON in a 128-byte chunk, and add them to structural_indexes. + * + * @param partial Setting the partial parameter to true allows the find_structural_bits to + * tolerate unclosed strings. 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 + static error_code index(const uint8_t *buf, size_t len, dom_parser_implementation &parser, stage1_mode partial) noexcept; + +private: + simdjson_inline json_structural_indexer(uint32_t *structural_indexes); + template + simdjson_inline void step(const uint8_t *block, buf_block_reader &reader) noexcept; + simdjson_inline void next(const simd::simd8x64& in, const json_block& block, size_t idx); + simdjson_inline error_code finish(dom_parser_implementation &parser, size_t idx, size_t len, stage1_mode partial); + + json_scanner scanner{}; + utf8_checker checker{}; + bit_indexer indexer; + uint64_t prev_structurals = 0; + uint64_t unescaped_chars_error = 0; +}; + +simdjson_inline json_structural_indexer::json_structural_indexer(uint32_t *structural_indexes) : indexer{structural_indexes} {} + +// Skip the last character if it is partial +simdjson_inline size_t trim_partial_utf8(const uint8_t *buf, size_t len) { + if (simdjson_unlikely(len < 3)) { + switch (len) { + case 2: + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + if (buf[len-2] >= 0xe0) { return len-2; } // 3- and 4-byte characters with only 2 bytes left + return len; + case 1: + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + return len; + case 0: + return len; + } + } + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + if (buf[len-2] >= 0xe0) { return len-2; } // 3- and 4-byte characters with only 1 byte left + if (buf[len-3] >= 0xf0) { return len-3; } // 4-byte characters with only 3 bytes left + return len; +} + +// +// PERF NOTES: +// We pipe 2 inputs through these stages: +// 1. Load JSON into registers. This takes a long time and is highly parallelizable, so we load +// 2 inputs' worth at once so that by the time step 2 is looking for them input, it's available. +// 2. Scan the JSON for critical data: strings, scalars and operators. This is the critical path. +// The output of step 1 depends entirely on this information. These functions don't quite use +// up enough CPU: the second half of the functions is highly serial, only using 1 execution core +// at a time. The second input's scans has some dependency on the first ones finishing it, but +// they can make a lot of progress before they need that information. +// 3. Step 1 doesn't use enough capacity, so we run some extra stuff while we're waiting for that +// to finish: utf-8 checks and generating the output from the last iteration. +// +// The reason we run 2 inputs at a time, is steps 2 and 3 are *still* not enough to soak up all +// available capacity with just one input. Running 2 at a time seems to give the CPU a good enough +// workout. +// +template +error_code json_structural_indexer::index(const uint8_t *buf, size_t len, dom_parser_implementation &parser, stage1_mode partial) noexcept { + if (simdjson_unlikely(len > parser.capacity())) { return CAPACITY; } + // We guard the rest of the code so that we can assume that len > 0 throughout. + if (len == 0) { return EMPTY; } + if (is_streaming(partial)) { + len = trim_partial_utf8(buf, len); + // If you end up with an empty window after trimming + // the partial UTF-8 bytes, then chances are good that you + // have an UTF-8 formatting error. + if(len == 0) { return UTF8_ERROR; } + } + buf_block_reader reader(buf, len); + json_structural_indexer indexer(parser.structural_indexes.get()); + + // Read all but the last block + while (reader.has_full_block()) { + indexer.step(reader.full_block(), reader); + } + // Take care of the last block (will always be there unless file is empty which is + // not supposed to happen.) + uint8_t block[STEP_SIZE]; + if (simdjson_unlikely(reader.get_remainder(block) == 0)) { return UNEXPECTED_ERROR; } + indexer.step(block, reader); + return indexer.finish(parser, reader.block_index(), len, partial); +} + +template<> +simdjson_inline void json_structural_indexer::step<128>(const uint8_t *block, buf_block_reader<128> &reader) noexcept { + simd::simd8x64 in_1(block); + simd::simd8x64 in_2(block+64); + json_block block_1 = scanner.next(in_1); + json_block block_2 = scanner.next(in_2); + this->next(in_1, block_1, reader.block_index()); + this->next(in_2, block_2, reader.block_index()+64); + reader.advance(); +} + +template<> +simdjson_inline void json_structural_indexer::step<64>(const uint8_t *block, buf_block_reader<64> &reader) noexcept { + simd::simd8x64 in_1(block); + json_block block_1 = scanner.next(in_1); + this->next(in_1, block_1, reader.block_index()); + reader.advance(); +} + +simdjson_inline void json_structural_indexer::next(const simd::simd8x64& in, const json_block& block, size_t idx) { + uint64_t unescaped = in.lteq(0x1F); +#if SIMDJSON_UTF8VALIDATION + checker.check_next_input(in); +#endif + indexer.write(uint32_t(idx-64), prev_structurals); // Output *last* iteration's structurals to the parser + prev_structurals = block.structural_start(); + unescaped_chars_error |= block.non_quote_inside_string(unescaped); +} + +simdjson_inline error_code json_structural_indexer::finish(dom_parser_implementation &parser, size_t idx, size_t len, stage1_mode partial) { + // Write out the final iteration's structurals + indexer.write(uint32_t(idx-64), prev_structurals); + error_code error = scanner.finish(); + // We deliberately break down the next expression so that it is + // human readable. + const bool should_we_exit = is_streaming(partial) ? + ((error != SUCCESS) && (error != UNCLOSED_STRING)) // when partial we tolerate UNCLOSED_STRING + : (error != SUCCESS); // if partial is false, we must have SUCCESS + const bool have_unclosed_string = (error == UNCLOSED_STRING); + if (simdjson_unlikely(should_we_exit)) { return error; } + + if (unescaped_chars_error) { + return UNESCAPED_CHARS; + } + parser.n_structural_indexes = uint32_t(indexer.tail - parser.structural_indexes.get()); + /*** + * The On Demand API requires special padding. + * + * This is related to https://github.com/simdjson/simdjson/issues/906 + * Basically, we want to make sure that if the parsing continues beyond the last (valid) + * structural character, it quickly stops. + * Only three structural characters can be repeated without triggering an error in JSON: [,] and }. + * We repeat the padding character (at 'len'). We don't know what it is, but if the parsing + * continues, then it must be [,] or }. + * Suppose it is ] or }. We backtrack to the first character, what could it be that would + * not trigger an error? It could be ] or } but no, because you can't start a document that way. + * It can't be a comma, a colon or any simple value. So the only way we could continue is + * if the repeated character is [. But if so, the document must start with [. But if the document + * starts with [, it should end with ]. If we enforce that rule, then we would get + * ][[ which is invalid. + * + * This is illustrated with the test array_iterate_unclosed_error() on the following input: + * R"({ "a": [,,)" + **/ + parser.structural_indexes[parser.n_structural_indexes] = uint32_t(len); // used later in partial == stage1_mode::streaming_final + parser.structural_indexes[parser.n_structural_indexes + 1] = uint32_t(len); + parser.structural_indexes[parser.n_structural_indexes + 2] = 0; + parser.next_structural_index = 0; + // a valid JSON file cannot have zero structural indexes - we should have found something + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { + return EMPTY; + } + if (simdjson_unlikely(parser.structural_indexes[parser.n_structural_indexes - 1] > len)) { + return UNEXPECTED_ERROR; + } + if (partial == stage1_mode::streaming_partial) { + // If we have an unclosed string, then the last structural + // will be the quote and we want to make sure to omit it. + if(have_unclosed_string) { + parser.n_structural_indexes--; + // a valid JSON file cannot have zero structural indexes - we should have found something + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { return CAPACITY; } + } + // We truncate the input to the end of the last complete document (or zero). + auto new_structural_indexes = find_next_document_index(parser); + if (new_structural_indexes == 0 && parser.n_structural_indexes > 0) { + if(parser.structural_indexes[0] == 0) { + // If the buffer is partial and we started at index 0 but the document is + // incomplete, it's too big to parse. + return CAPACITY; + } else { + // It is possible that the document could be parsed, we just had a lot + // of white space. + parser.n_structural_indexes = 0; + return EMPTY; + } + } + + parser.n_structural_indexes = new_structural_indexes; + } else if (partial == stage1_mode::streaming_final) { + if(have_unclosed_string) { parser.n_structural_indexes--; } + // We truncate the input to the end of the last complete document (or zero). + // Because partial == stage1_mode::streaming_final, it means that we may + // silently ignore trailing garbage. Though it sounds bad, we do it + // deliberately because many people who have streams of JSON documents + // will truncate them for processing. E.g., imagine that you are uncompressing + // the data from a size file or receiving it in chunks from the network. You + // may not know where exactly the last document will be. Meanwhile the + // document_stream instances allow people to know the JSON documents they are + // parsing (see the iterator.source() method). + parser.n_structural_indexes = find_next_document_index(parser); + // We store the initial n_structural_indexes so that the client can see + // whether we used truncation. If initial_n_structural_indexes == parser.n_structural_indexes, + // then this will query parser.structural_indexes[parser.n_structural_indexes] which is len, + // otherwise, it will copy some prior index. + parser.structural_indexes[parser.n_structural_indexes + 1] = parser.structural_indexes[parser.n_structural_indexes]; + // This next line is critical, do not change it unless you understand what you are + // doing. + parser.structural_indexes[parser.n_structural_indexes] = uint32_t(len); + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { + // We tolerate an unclosed string at the very end of the stream. Indeed, users + // often load their data in bulk without being careful and they want us to ignore + // the trailing garbage. + return EMPTY; + } + } + checker.check_eof(); + return checker.errors(); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +// Clear CUSTOM_BIT_INDEXER so other implementations can set it if they need to. +#undef SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H +/* end file generic/stage1/json_structural_indexer.h for haswell */ +/* including generic/stage1/utf8_validator.h for haswell: #include */ +/* begin file generic/stage1/utf8_validator.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace stage1 { + +/** + * Validates that the string is actual UTF-8. + */ +template +bool generic_validate_utf8(const uint8_t * input, size_t length) { + checker c{}; + buf_block_reader<64> reader(input, length); + while (reader.has_full_block()) { + simd::simd8x64 in(reader.full_block()); + c.check_next_input(in); + reader.advance(); + } + uint8_t block[64]{}; + reader.get_remainder(block); + simd::simd8x64 in(block); + c.check_next_input(in); + reader.advance(); + c.check_eof(); + return c.errors() == error_code::SUCCESS; +} + +bool generic_validate_utf8(const char * input, size_t length) { + return generic_validate_utf8(reinterpret_cast(input),length); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H +/* end file generic/stage1/utf8_validator.h for haswell */ +/* end file generic/stage1/amalgamated.h for haswell */ +/* including generic/stage2/amalgamated.h for haswell: #include */ +/* begin file generic/stage2/amalgamated.h for haswell */ +// Stuff other things depend on +/* including generic/stage2/base.h for haswell: #include */ +/* begin file generic/stage2/base.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace stage2 { + +class json_iterator; +class structural_iterator; +struct tape_builder; +struct tape_writer; + +} // namespace stage2 +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_BASE_H +/* end file generic/stage2/base.h for haswell */ +/* including generic/stage2/tape_writer.h for haswell: #include */ +/* begin file generic/stage2/tape_writer.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace haswell { +namespace { +namespace stage2 { + +struct tape_writer { + /** The next place to write to tape */ + uint64_t *next_tape_loc; + + /** Write a signed 64-bit value to tape. */ + simdjson_inline void append_s64(int64_t value) noexcept; + + /** Write an unsigned 64-bit value to tape. */ + simdjson_inline void append_u64(uint64_t value) noexcept; + + /** Write a double value to tape. */ + simdjson_inline void append_double(double value) noexcept; + + /** + * Append a tape entry (an 8-bit type,and 56 bits worth of value). + */ + simdjson_inline void append(uint64_t val, internal::tape_type t) noexcept; + + /** + * Skip the current tape entry without writing. + * + * Used to skip the start of the container, since we'll come back later to fill it in when the + * container ends. + */ + simdjson_inline void skip() noexcept; + + /** + * Skip the number of tape entries necessary to write a large u64 or i64. + */ + simdjson_inline void skip_large_integer() noexcept; + + /** + * Skip the number of tape entries necessary to write a double. + */ + simdjson_inline void skip_double() noexcept; + + /** + * Write a value to a known location on tape. + * + * Used to go back and write out the start of a container after the container ends. + */ + simdjson_inline static void write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept; + +private: + /** + * Append both the tape entry, and a supplementary value following it. Used for types that need + * all 64 bits, such as double and uint64_t. + */ + template + simdjson_inline void append2(uint64_t val, T val2, internal::tape_type t) noexcept; +}; // struct tape_writer + +simdjson_inline void tape_writer::append_s64(int64_t value) noexcept { + append2(0, value, internal::tape_type::INT64); +} + +simdjson_inline void tape_writer::append_u64(uint64_t value) noexcept { + append(0, internal::tape_type::UINT64); + *next_tape_loc = value; + next_tape_loc++; +} + +/** Write a double value to tape. */ +simdjson_inline void tape_writer::append_double(double value) noexcept { + append2(0, value, internal::tape_type::DOUBLE); +} + +simdjson_inline void tape_writer::skip() noexcept { + next_tape_loc++; +} + +simdjson_inline void tape_writer::skip_large_integer() noexcept { + next_tape_loc += 2; +} + +simdjson_inline void tape_writer::skip_double() noexcept { + next_tape_loc += 2; +} + +simdjson_inline void tape_writer::append(uint64_t val, internal::tape_type t) noexcept { + *next_tape_loc = val | ((uint64_t(char(t))) << 56); + next_tape_loc++; +} + +template +simdjson_inline void tape_writer::append2(uint64_t val, T val2, internal::tape_type t) noexcept { + append(val, t); + static_assert(sizeof(val2) == sizeof(*next_tape_loc), "Type is not 64 bits!"); + memcpy(next_tape_loc, &val2, sizeof(val2)); + next_tape_loc++; +} + +simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept { + tape_loc = val | ((uint64_t(char(t))) << 56); +} + +} // namespace stage2 +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H +/* end file generic/stage2/tape_writer.h for haswell */ +/* including generic/stage2/logger.h for haswell: #include */ +/* begin file generic/stage2/logger.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_LOGGER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_LOGGER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + + +// This is for an internal-only stage 2 specific logger. +// Set LOG_ENABLED = true to log what stage 2 is doing! +namespace simdjson { +namespace haswell { +namespace { +namespace logger { + + static constexpr const char * DASHES = "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"; + +#if SIMDJSON_VERBOSE_LOGGING + static constexpr const bool LOG_ENABLED = true; +#else + static constexpr const bool LOG_ENABLED = false; +#endif + static constexpr const int LOG_EVENT_LEN = 20; + static constexpr const int LOG_BUFFER_LEN = 30; + static constexpr const int LOG_SMALL_BUFFER_LEN = 10; + static constexpr const int LOG_INDEX_LEN = 5; + + static int log_depth; // Not threadsafe. Log only. + + // Helper to turn unprintable or newline characters into spaces + static simdjson_inline char printable_char(char c) { + if (c >= 0x20) { + return c; + } else { + return ' '; + } + } + + // Print the header and set up log_start + static simdjson_inline void log_start() { + if (LOG_ENABLED) { + log_depth = 0; + printf("\n"); + printf("| %-*s | %-*s | %-*s | %-*s | Detail |\n", LOG_EVENT_LEN, "Event", LOG_BUFFER_LEN, "Buffer", LOG_SMALL_BUFFER_LEN, "Next", 5, "Next#"); + printf("|%.*s|%.*s|%.*s|%.*s|--------|\n", LOG_EVENT_LEN+2, DASHES, LOG_BUFFER_LEN+2, DASHES, LOG_SMALL_BUFFER_LEN+2, DASHES, 5+2, DASHES); + } + } + + simdjson_unused static simdjson_inline void log_string(const char *message) { + if (LOG_ENABLED) { + printf("%s\n", message); + } + } + + // Logs a single line from the stage 2 DOM parser + template + static simdjson_inline void log_line(S &structurals, const char *title_prefix, const char *title, const char *detail) { + if (LOG_ENABLED) { + printf("| %*s%s%-*s ", log_depth*2, "", title_prefix, LOG_EVENT_LEN - log_depth*2 - int(strlen(title_prefix)), title); + auto current_index = structurals.at_beginning() ? nullptr : structurals.next_structural-1; + auto next_index = structurals.next_structural; + auto current = current_index ? &structurals.buf[*current_index] : reinterpret_cast(" "); + auto next = &structurals.buf[*next_index]; + { + // Print the next N characters in the buffer. + printf("| "); + // Otherwise, print the characters starting from the buffer position. + // Print spaces for unprintable or newline characters. + for (int i=0;i */ +/* begin file generic/stage2/json_iterator.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace stage2 { + +class json_iterator { +public: + const uint8_t* const buf; + uint32_t *next_structural; + dom_parser_implementation &dom_parser; + uint32_t depth{0}; + + /** + * Walk the JSON document. + * + * The visitor receives callbacks when values are encountered. All callbacks pass the iterator as + * the first parameter; some callbacks have other parameters as well: + * + * - visit_document_start() - at the beginning. + * - visit_document_end() - at the end (if things were successful). + * + * - visit_array_start() - at the start `[` of a non-empty array. + * - visit_array_end() - at the end `]` of a non-empty array. + * - visit_empty_array() - when an empty array is encountered. + * + * - visit_object_end() - at the start `]` of a non-empty object. + * - visit_object_start() - at the end `]` of a non-empty object. + * - visit_empty_object() - when an empty object is encountered. + * - visit_key(const uint8_t *key) - when a key in an object field is encountered. key is + * guaranteed to point at the first quote of the string (`"key"`). + * - visit_primitive(const uint8_t *value) - when a value is a string, number, boolean or null. + * - visit_root_primitive(iter, uint8_t *value) - when the top-level value is a string, number, boolean or null. + * + * - increment_count(iter) - each time a value is found in an array or object. + */ + template + simdjson_warn_unused simdjson_inline error_code walk_document(V &visitor) noexcept; + + /** + * Create an iterator capable of walking a JSON document. + * + * The document must have already passed through stage 1. + */ + simdjson_inline json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index); + + /** + * Look at the next token. + * + * Tokens can be strings, numbers, booleans, null, or operators (`[{]},:`)). + * + * They may include invalid JSON as well (such as `1.2.3` or `ture`). + */ + simdjson_inline const uint8_t *peek() const noexcept; + /** + * Advance to the next token. + * + * Tokens can be strings, numbers, booleans, null, or operators (`[{]},:`)). + * + * They may include invalid JSON as well (such as `1.2.3` or `ture`). + */ + simdjson_inline const uint8_t *advance() noexcept; + /** + * Get the remaining length of the document, from the start of the current token. + */ + simdjson_inline size_t remaining_len() const noexcept; + /** + * Check if we are at the end of the document. + * + * If this is true, there are no more tokens. + */ + simdjson_inline bool at_eof() const noexcept; + /** + * Check if we are at the beginning of the document. + */ + simdjson_inline bool at_beginning() const noexcept; + simdjson_inline uint8_t last_structural() const noexcept; + + /** + * Log that a value has been found. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_value(const char *type) const noexcept; + /** + * Log the start of a multipart value. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_start_value(const char *type) const noexcept; + /** + * Log the end of a multipart value. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_end_value(const char *type) const noexcept; + /** + * Log an error. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_error(const char *error) const noexcept; + + template + simdjson_warn_unused simdjson_inline error_code visit_root_primitive(V &visitor, const uint8_t *value) noexcept; + template + simdjson_warn_unused simdjson_inline error_code visit_primitive(V &visitor, const uint8_t *value) noexcept; +}; + +template +simdjson_warn_unused simdjson_inline error_code json_iterator::walk_document(V &visitor) noexcept { + logger::log_start(); + + // + // Start the document + // + if (at_eof()) { return EMPTY; } + log_start_value("document"); + SIMDJSON_TRY( visitor.visit_document_start(*this) ); + + // + // Read first value + // + { + auto value = advance(); + + // Make sure the outer object or array is closed before continuing; otherwise, there are ways we + // could get into memory corruption. See https://github.com/simdjson/simdjson/issues/906 + if (!STREAMING) { + switch (*value) { + case '{': if (last_structural() != '}') { log_value("starting brace unmatched"); return TAPE_ERROR; }; break; + case '[': if (last_structural() != ']') { log_value("starting bracket unmatched"); return TAPE_ERROR; }; break; + } + } + + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_root_primitive(*this, value) ); break; + } + } + goto document_end; + +// +// Object parser states +// +object_begin: + log_start_value("object"); + depth++; + if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; } + dom_parser.is_array[depth] = false; + SIMDJSON_TRY( visitor.visit_object_start(*this) ); + + { + auto key = advance(); + if (*key != '"') { log_error("Object does not start with a key"); return TAPE_ERROR; } + SIMDJSON_TRY( visitor.increment_count(*this) ); + SIMDJSON_TRY( visitor.visit_key(*this, key) ); + } + +object_field: + if (simdjson_unlikely( *advance() != ':' )) { log_error("Missing colon after key in object"); return TAPE_ERROR; } + { + auto value = advance(); + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break; + } + } + +object_continue: + switch (*advance()) { + case ',': + SIMDJSON_TRY( visitor.increment_count(*this) ); + { + auto key = advance(); + if (simdjson_unlikely( *key != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; } + SIMDJSON_TRY( visitor.visit_key(*this, key) ); + } + goto object_field; + case '}': log_end_value("object"); SIMDJSON_TRY( visitor.visit_object_end(*this) ); goto scope_end; + default: log_error("No comma between object fields"); return TAPE_ERROR; + } + +scope_end: + depth--; + if (depth == 0) { goto document_end; } + if (dom_parser.is_array[depth]) { goto array_continue; } + goto object_continue; + +// +// Array parser states +// +array_begin: + log_start_value("array"); + depth++; + if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; } + dom_parser.is_array[depth] = true; + SIMDJSON_TRY( visitor.visit_array_start(*this) ); + SIMDJSON_TRY( visitor.increment_count(*this) ); + +array_value: + { + auto value = advance(); + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break; + } + } + +array_continue: + switch (*advance()) { + case ',': SIMDJSON_TRY( visitor.increment_count(*this) ); goto array_value; + case ']': log_end_value("array"); SIMDJSON_TRY( visitor.visit_array_end(*this) ); goto scope_end; + default: log_error("Missing comma between array values"); return TAPE_ERROR; + } + +document_end: + log_end_value("document"); + SIMDJSON_TRY( visitor.visit_document_end(*this) ); + + dom_parser.next_structural_index = uint32_t(next_structural - &dom_parser.structural_indexes[0]); + + // If we didn't make it to the end, it's an error + if ( !STREAMING && dom_parser.next_structural_index != dom_parser.n_structural_indexes ) { + log_error("More than one JSON value at the root of the document, or extra characters at the end of the JSON!"); + return TAPE_ERROR; + } + + return SUCCESS; + +} // walk_document() + +simdjson_inline json_iterator::json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index) + : buf{_dom_parser.buf}, + next_structural{&_dom_parser.structural_indexes[start_structural_index]}, + dom_parser{_dom_parser} { +} + +simdjson_inline const uint8_t *json_iterator::peek() const noexcept { + return &buf[*(next_structural)]; +} +simdjson_inline const uint8_t *json_iterator::advance() noexcept { + return &buf[*(next_structural++)]; +} +simdjson_inline size_t json_iterator::remaining_len() const noexcept { + return dom_parser.len - *(next_structural-1); +} + +simdjson_inline bool json_iterator::at_eof() const noexcept { + return next_structural == &dom_parser.structural_indexes[dom_parser.n_structural_indexes]; +} +simdjson_inline bool json_iterator::at_beginning() const noexcept { + return next_structural == dom_parser.structural_indexes.get(); +} +simdjson_inline uint8_t json_iterator::last_structural() const noexcept { + return buf[dom_parser.structural_indexes[dom_parser.n_structural_indexes - 1]]; +} + +simdjson_inline void json_iterator::log_value(const char *type) const noexcept { + logger::log_line(*this, "", type, ""); +} + +simdjson_inline void json_iterator::log_start_value(const char *type) const noexcept { + logger::log_line(*this, "+", type, ""); + if (logger::LOG_ENABLED) { logger::log_depth++; } +} + +simdjson_inline void json_iterator::log_end_value(const char *type) const noexcept { + if (logger::LOG_ENABLED) { logger::log_depth--; } + logger::log_line(*this, "-", type, ""); +} + +simdjson_inline void json_iterator::log_error(const char *error) const noexcept { + logger::log_line(*this, "", "ERROR", error); +} + +template +simdjson_warn_unused simdjson_inline error_code json_iterator::visit_root_primitive(V &visitor, const uint8_t *value) noexcept { + switch (*value) { + case '"': return visitor.visit_root_string(*this, value); + case 't': return visitor.visit_root_true_atom(*this, value); + case 'f': return visitor.visit_root_false_atom(*this, value); + case 'n': return visitor.visit_root_null_atom(*this, value); + case '-': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return visitor.visit_root_number(*this, value); + default: + log_error("Document starts with a non-value character"); + return TAPE_ERROR; + } +} +template +simdjson_warn_unused simdjson_inline error_code json_iterator::visit_primitive(V &visitor, const uint8_t *value) noexcept { + // Use the fact that most scalars are going to be either strings or numbers. + if(*value == '"') { + return visitor.visit_string(*this, value); + } else if (((*value - '0') < 10) || (*value == '-')) { + return visitor.visit_number(*this, value); + } + // true, false, null are uncommon. + switch (*value) { + case 't': return visitor.visit_true_atom(*this, value); + case 'f': return visitor.visit_false_atom(*this, value); + case 'n': return visitor.visit_null_atom(*this, value); + default: + log_error("Non-value found when value was expected!"); + return TAPE_ERROR; + } +} + +} // namespace stage2 +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H +/* end file generic/stage2/json_iterator.h for haswell */ +/* including generic/stage2/stringparsing.h for haswell: #include */ +/* begin file generic/stage2/stringparsing.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses +// It is intended to be included multiple times and compiled multiple times + +namespace simdjson { +namespace haswell { +namespace { +/// @private +namespace stringparsing { + +// begin copypasta +// These chars yield themselves: " \ / +// b -> backspace, f -> formfeed, n -> newline, r -> cr, t -> horizontal tab +// u not handled in this table as it's complex +static const uint8_t escape_map[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0x22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2f, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x4. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5c, 0, 0, 0, // 0x5. + 0, 0, 0x08, 0, 0, 0, 0x0c, 0, 0, 0, 0, 0, 0, 0, 0x0a, 0, // 0x6. + 0, 0, 0x0d, 0, 0x09, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x7. + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +// handle a unicode codepoint +// write appropriate values into dest +// src will advance 6 bytes or 12 bytes +// dest will advance a variable amount (return via pointer) +// return true if the unicode codepoint was valid +// We work in little-endian then swap at write time +simdjson_warn_unused +simdjson_inline bool handle_unicode_codepoint(const uint8_t **src_ptr, + uint8_t **dst_ptr, bool allow_replacement) { + // Use the default Unicode Character 'REPLACEMENT CHARACTER' (U+FFFD) + constexpr uint32_t substitution_code_point = 0xfffd; + // jsoncharutils::hex_to_u32_nocheck fills high 16 bits of the return value with 1s if the + // conversion isn't valid; we defer the check for this to inside the + // multilingual plane check + uint32_t code_point = jsoncharutils::hex_to_u32_nocheck(*src_ptr + 2); + *src_ptr += 6; + + // If we found a high surrogate, we must + // check for low surrogate for characters + // outside the Basic + // Multilingual Plane. + if (code_point >= 0xd800 && code_point < 0xdc00) { + const uint8_t *src_data = *src_ptr; + /* Compiler optimizations convert this to a single 16-bit load and compare on most platforms */ + if (((src_data[0] << 8) | src_data[1]) != ((static_cast ('\\') << 8) | static_cast ('u'))) { + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } else { + uint32_t code_point_2 = jsoncharutils::hex_to_u32_nocheck(src_data + 2); + + // We have already checked that the high surrogate is valid and + // (code_point - 0xd800) < 1024. + // + // Check that code_point_2 is in the range 0xdc00..0xdfff + // and that code_point_2 was parsed from valid hex. + uint32_t low_bit = code_point_2 - 0xdc00; + if (low_bit >> 10) { + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } else { + code_point = (((code_point - 0xd800) << 10) | low_bit) + 0x10000; + *src_ptr += 6; + } + + } + } else if (code_point >= 0xdc00 && code_point <= 0xdfff) { + // If we encounter a low surrogate (not preceded by a high surrogate) + // then we have an error. + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } + size_t offset = jsoncharutils::codepoint_to_utf8(code_point, *dst_ptr); + *dst_ptr += offset; + return offset > 0; +} + + +// handle a unicode codepoint using the wobbly convention +// https://simonsapin.github.io/wtf-8/ +// write appropriate values into dest +// src will advance 6 bytes or 12 bytes +// dest will advance a variable amount (return via pointer) +// return true if the unicode codepoint was valid +// We work in little-endian then swap at write time +simdjson_warn_unused +simdjson_inline bool handle_unicode_codepoint_wobbly(const uint8_t **src_ptr, + uint8_t **dst_ptr) { + // It is not ideal that this function is nearly identical to handle_unicode_codepoint. + // + // jsoncharutils::hex_to_u32_nocheck fills high 16 bits of the return value with 1s if the + // conversion isn't valid; we defer the check for this to inside the + // multilingual plane check + uint32_t code_point = jsoncharutils::hex_to_u32_nocheck(*src_ptr + 2); + *src_ptr += 6; + // If we found a high surrogate, we must + // check for low surrogate for characters + // outside the Basic + // Multilingual Plane. + if (code_point >= 0xd800 && code_point < 0xdc00) { + const uint8_t *src_data = *src_ptr; + /* Compiler optimizations convert this to a single 16-bit load and compare on most platforms */ + if (((src_data[0] << 8) | src_data[1]) == ((static_cast ('\\') << 8) | static_cast ('u'))) { + uint32_t code_point_2 = jsoncharutils::hex_to_u32_nocheck(src_data + 2); + uint32_t low_bit = code_point_2 - 0xdc00; + if ((low_bit >> 10) == 0) { + code_point = + (((code_point - 0xd800) << 10) | low_bit) + 0x10000; + *src_ptr += 6; + } + } + } + + size_t offset = jsoncharutils::codepoint_to_utf8(code_point, *dst_ptr); + *dst_ptr += offset; + return offset > 0; +} + + +/** + * Unescape a valid UTF-8 string from src to dst, stopping at a final unescaped quote. There + * must be an unescaped quote terminating the string. It returns the final output + * position as pointer. In case of error (e.g., the string has bad escaped codes), + * then null_nullptrptr is returned. It is assumed that the output buffer is large + * enough. E.g., if src points at 'joe"', then dst needs to have four free bytes + + * SIMDJSON_PADDING bytes. + */ +simdjson_warn_unused simdjson_inline uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) { + while (1) { + // Copy the next n bytes, and find the backslash and quote in them. + auto bs_quote = backslash_and_quote::copy_and_find(src, dst); + // If the next thing is the end quote, copy and return + if (bs_quote.has_quote_first()) { + // we encountered quotes first. Move dst to point to quotes and exit + return dst + bs_quote.quote_index(); + } + if (bs_quote.has_backslash()) { + /* find out where the backspace is */ + auto bs_dist = bs_quote.backslash_index(); + uint8_t escape_char = src[bs_dist + 1]; + /* we encountered backslash first. Handle backslash */ + if (escape_char == 'u') { + /* move src/dst up to the start; they will be further adjusted + within the unicode codepoint handling code. */ + src += bs_dist; + dst += bs_dist; + if (!handle_unicode_codepoint(&src, &dst, allow_replacement)) { + return nullptr; + } + } else { + /* simple 1:1 conversion. Will eat bs_dist+2 characters in input and + * write bs_dist+1 characters to output + * note this may reach beyond the part of the buffer we've actually + * seen. I think this is ok */ + uint8_t escape_result = escape_map[escape_char]; + if (escape_result == 0u) { + return nullptr; /* bogus escape value is an error */ + } + dst[bs_dist] = escape_result; + src += bs_dist + 2; + dst += bs_dist + 1; + } + } else { + /* they are the same. Since they can't co-occur, it means we + * encountered neither. */ + src += backslash_and_quote::BYTES_PROCESSED; + dst += backslash_and_quote::BYTES_PROCESSED; + } + } +} + +simdjson_warn_unused simdjson_inline uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) { + // It is not ideal that this function is nearly identical to parse_string. + while (1) { + // Copy the next n bytes, and find the backslash and quote in them. + auto bs_quote = backslash_and_quote::copy_and_find(src, dst); + // If the next thing is the end quote, copy and return + if (bs_quote.has_quote_first()) { + // we encountered quotes first. Move dst to point to quotes and exit + return dst + bs_quote.quote_index(); + } + if (bs_quote.has_backslash()) { + /* find out where the backspace is */ + auto bs_dist = bs_quote.backslash_index(); + uint8_t escape_char = src[bs_dist + 1]; + /* we encountered backslash first. Handle backslash */ + if (escape_char == 'u') { + /* move src/dst up to the start; they will be further adjusted + within the unicode codepoint handling code. */ + src += bs_dist; + dst += bs_dist; + if (!handle_unicode_codepoint_wobbly(&src, &dst)) { + return nullptr; + } + } else { + /* simple 1:1 conversion. Will eat bs_dist+2 characters in input and + * write bs_dist+1 characters to output + * note this may reach beyond the part of the buffer we've actually + * seen. I think this is ok */ + uint8_t escape_result = escape_map[escape_char]; + if (escape_result == 0u) { + return nullptr; /* bogus escape value is an error */ + } + dst[bs_dist] = escape_result; + src += bs_dist + 2; + dst += bs_dist + 1; + } + } else { + /* they are the same. Since they can't co-occur, it means we + * encountered neither. */ + src += backslash_and_quote::BYTES_PROCESSED; + dst += backslash_and_quote::BYTES_PROCESSED; + } + } +} + +} // namespace stringparsing +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H +/* end file generic/stage2/stringparsing.h for haswell */ +/* including generic/stage2/structural_iterator.h for haswell: #include */ +/* begin file generic/stage2/structural_iterator.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace stage2 { + +class structural_iterator { +public: + const uint8_t* const buf; + uint32_t *next_structural; + dom_parser_implementation &dom_parser; + + // Start a structural + simdjson_inline structural_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index) + : buf{_dom_parser.buf}, + next_structural{&_dom_parser.structural_indexes[start_structural_index]}, + dom_parser{_dom_parser} { + } + // Get the buffer position of the current structural character + simdjson_inline const uint8_t* current() { + return &buf[*(next_structural-1)]; + } + // Get the current structural character + simdjson_inline char current_char() { + return buf[*(next_structural-1)]; + } + // Get the next structural character without advancing + simdjson_inline char peek_next_char() { + return buf[*next_structural]; + } + simdjson_inline const uint8_t* peek() { + return &buf[*next_structural]; + } + simdjson_inline const uint8_t* advance() { + return &buf[*(next_structural++)]; + } + simdjson_inline char advance_char() { + return buf[*(next_structural++)]; + } + simdjson_inline size_t remaining_len() { + return dom_parser.len - *(next_structural-1); + } + + simdjson_inline bool at_end() { + return next_structural == &dom_parser.structural_indexes[dom_parser.n_structural_indexes]; + } + simdjson_inline bool at_beginning() { + return next_structural == dom_parser.structural_indexes.get(); + } +}; + +} // namespace stage2 +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H +/* end file generic/stage2/structural_iterator.h for haswell */ +/* including generic/stage2/tape_builder.h for haswell: #include */ +/* begin file generic/stage2/tape_builder.h for haswell */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + + +namespace simdjson { +namespace haswell { +namespace { +namespace stage2 { + +struct tape_builder { + template + simdjson_warn_unused static simdjson_inline error_code parse_document( + dom_parser_implementation &dom_parser, + dom::document &doc) noexcept; + + /** Called when a non-empty document starts. */ + simdjson_warn_unused simdjson_inline error_code visit_document_start(json_iterator &iter) noexcept; + /** Called when a non-empty document ends without error. */ + simdjson_warn_unused simdjson_inline error_code visit_document_end(json_iterator &iter) noexcept; + + /** Called when a non-empty array starts. */ + simdjson_warn_unused simdjson_inline error_code visit_array_start(json_iterator &iter) noexcept; + /** Called when a non-empty array ends. */ + simdjson_warn_unused simdjson_inline error_code visit_array_end(json_iterator &iter) noexcept; + /** Called when an empty array is found. */ + simdjson_warn_unused simdjson_inline error_code visit_empty_array(json_iterator &iter) noexcept; + + /** Called when a non-empty object starts. */ + simdjson_warn_unused simdjson_inline error_code visit_object_start(json_iterator &iter) noexcept; + /** + * Called when a key in a field is encountered. + * + * primitive, visit_object_start, visit_empty_object, visit_array_start, or visit_empty_array + * will be called after this with the field value. + */ + simdjson_warn_unused simdjson_inline error_code visit_key(json_iterator &iter, const uint8_t *key) noexcept; + /** Called when a non-empty object ends. */ + simdjson_warn_unused simdjson_inline error_code visit_object_end(json_iterator &iter) noexcept; + /** Called when an empty object is found. */ + simdjson_warn_unused simdjson_inline error_code visit_empty_object(json_iterator &iter) noexcept; + + /** + * Called when a string, number, boolean or null is found. + */ + simdjson_warn_unused simdjson_inline error_code visit_primitive(json_iterator &iter, const uint8_t *value) noexcept; + /** + * Called when a string, number, boolean or null is found at the top level of a document (i.e. + * when there is no array or object and the entire document is a single string, number, boolean or + * null. + * + * This is separate from primitive() because simdjson's normal primitive parsing routines assume + * there is at least one more token after the value, which is only true in an array or object. + */ + simdjson_warn_unused simdjson_inline error_code visit_root_primitive(json_iterator &iter, const uint8_t *value) noexcept; + + simdjson_warn_unused simdjson_inline error_code visit_string(json_iterator &iter, const uint8_t *value, bool key = false) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_number(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_true_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_false_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_null_atom(json_iterator &iter, const uint8_t *value) noexcept; + + simdjson_warn_unused simdjson_inline error_code visit_root_string(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_number(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_true_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_false_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_null_atom(json_iterator &iter, const uint8_t *value) noexcept; + + /** Called each time a new field or element in an array or object is found. */ + simdjson_warn_unused simdjson_inline error_code increment_count(json_iterator &iter) noexcept; + + /** Next location to write to tape */ + tape_writer tape; +private: + /** Next write location in the string buf for stage 2 parsing */ + uint8_t *current_string_buf_loc; + + simdjson_inline tape_builder(dom::document &doc) noexcept; + + simdjson_inline uint32_t next_tape_index(json_iterator &iter) const noexcept; + simdjson_inline void start_container(json_iterator &iter) noexcept; + simdjson_warn_unused simdjson_inline error_code end_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept; + simdjson_warn_unused simdjson_inline error_code empty_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept; + simdjson_inline uint8_t *on_start_string(json_iterator &iter) noexcept; + simdjson_inline void on_end_string(uint8_t *dst) noexcept; +}; // struct tape_builder + +template +simdjson_warn_unused simdjson_inline error_code tape_builder::parse_document( + dom_parser_implementation &dom_parser, + dom::document &doc) noexcept { + dom_parser.doc = &doc; + json_iterator iter(dom_parser, STREAMING ? dom_parser.next_structural_index : 0); + tape_builder builder(doc); + return iter.walk_document(builder); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_primitive(json_iterator &iter, const uint8_t *value) noexcept { + return iter.visit_root_primitive(*this, value); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_primitive(json_iterator &iter, const uint8_t *value) noexcept { + return iter.visit_primitive(*this, value); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_empty_object(json_iterator &iter) noexcept { + return empty_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_empty_array(json_iterator &iter) noexcept { + return empty_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_document_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_object_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_array_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_object_end(json_iterator &iter) noexcept { + return end_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_array_end(json_iterator &iter) noexcept { + return end_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_document_end(json_iterator &iter) noexcept { + constexpr uint32_t start_tape_index = 0; + tape.append(start_tape_index, internal::tape_type::ROOT); + tape_writer::write(iter.dom_parser.doc->tape[start_tape_index], next_tape_index(iter), internal::tape_type::ROOT); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_key(json_iterator &iter, const uint8_t *key) noexcept { + return visit_string(iter, key, true); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::increment_count(json_iterator &iter) noexcept { + iter.dom_parser.open_containers[iter.depth].count++; // we have a key value pair in the object at parser.dom_parser.depth - 1 + return SUCCESS; +} + +simdjson_inline tape_builder::tape_builder(dom::document &doc) noexcept : tape{doc.tape.get()}, current_string_buf_loc{doc.string_buf.get()} {} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_string(json_iterator &iter, const uint8_t *value, bool key) noexcept { + iter.log_value(key ? "key" : "string"); + uint8_t *dst = on_start_string(iter); + dst = stringparsing::parse_string(value+1, dst, false); // We do not allow replacement when the escape characters are invalid. + if (dst == nullptr) { + iter.log_error("Invalid escape in string"); + return STRING_ERROR; + } + on_end_string(dst); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(json_iterator &iter, const uint8_t *value) noexcept { + return visit_string(iter, value); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("number"); + return numberparsing::parse_number(value, tape); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept { + // + // We need to make a copy to make sure that the string is space terminated. + // This is not about padding the input, which should already padded up + // to len + SIMDJSON_PADDING. However, we have no control at this stage + // on how the padding was done. What if the input string was padded with nulls? + // It is quite common for an input string to have an extra null character (C string). + // We do not want to allow 9\0 (where \0 is the null character) inside a JSON + // document, but the string "9\0" by itself is fine. So we make a copy and + // pad the input with spaces when we know that there is just one input element. + // This copy is relatively expensive, but it will almost never be called in + // practice unless you are in the strange scenario where you have many JSON + // documents made of single atoms. + // + std::unique_ptrcopy(new (std::nothrow) uint8_t[iter.remaining_len() + SIMDJSON_PADDING]); + if (copy.get() == nullptr) { return MEMALLOC; } + std::memcpy(copy.get(), value, iter.remaining_len()); + std::memset(copy.get() + iter.remaining_len(), ' ', SIMDJSON_PADDING); + error_code error = visit_number(iter, copy.get()); + return error; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_true_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("true"); + if (!atomparsing::is_valid_true_atom(value)) { return T_ATOM_ERROR; } + tape.append(0, internal::tape_type::TRUE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_true_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("true"); + if (!atomparsing::is_valid_true_atom(value, iter.remaining_len())) { return T_ATOM_ERROR; } + tape.append(0, internal::tape_type::TRUE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_false_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("false"); + if (!atomparsing::is_valid_false_atom(value)) { return F_ATOM_ERROR; } + tape.append(0, internal::tape_type::FALSE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_false_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("false"); + if (!atomparsing::is_valid_false_atom(value, iter.remaining_len())) { return F_ATOM_ERROR; } + tape.append(0, internal::tape_type::FALSE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_null_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("null"); + if (!atomparsing::is_valid_null_atom(value)) { return N_ATOM_ERROR; } + tape.append(0, internal::tape_type::NULL_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_null_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("null"); + if (!atomparsing::is_valid_null_atom(value, iter.remaining_len())) { return N_ATOM_ERROR; } + tape.append(0, internal::tape_type::NULL_VALUE); + return SUCCESS; +} + +// private: + +simdjson_inline uint32_t tape_builder::next_tape_index(json_iterator &iter) const noexcept { + return uint32_t(tape.next_tape_loc - iter.dom_parser.doc->tape.get()); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::empty_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept { + auto start_index = next_tape_index(iter); + tape.append(start_index+2, start); + tape.append(start_index, end); + return SUCCESS; +} + +simdjson_inline void tape_builder::start_container(json_iterator &iter) noexcept { + iter.dom_parser.open_containers[iter.depth].tape_index = next_tape_index(iter); + iter.dom_parser.open_containers[iter.depth].count = 0; + tape.skip(); // We don't actually *write* the start element until the end. +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::end_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept { + // Write the ending tape element, pointing at the start location + const uint32_t start_tape_index = iter.dom_parser.open_containers[iter.depth].tape_index; + tape.append(start_tape_index, end); + // Write the start tape element, pointing at the end location (and including count) + // count can overflow if it exceeds 24 bits... so we saturate + // the convention being that a cnt of 0xffffff or more is undetermined in value (>= 0xffffff). + const uint32_t count = iter.dom_parser.open_containers[iter.depth].count; + const uint32_t cntsat = count > 0xFFFFFF ? 0xFFFFFF : count; + tape_writer::write(iter.dom_parser.doc->tape[start_tape_index], next_tape_index(iter) | (uint64_t(cntsat) << 32), start); + return SUCCESS; +} + +simdjson_inline uint8_t *tape_builder::on_start_string(json_iterator &iter) noexcept { + // we advance the point, accounting for the fact that we have a NULL termination + tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::STRING); + return current_string_buf_loc + sizeof(uint32_t); +} + +simdjson_inline void tape_builder::on_end_string(uint8_t *dst) noexcept { + uint32_t str_length = uint32_t(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 + // Currently unneeded because we refuse to parse docs larger or equal to 4GB. + memcpy(current_string_buf_loc, &str_length, sizeof(uint32_t)); + // NULL termination is still handy if you expect all your strings to + // be NULL terminated? It comes at a small cost + *dst = 0; + current_string_buf_loc = dst + 1; +} + +} // namespace stage2 +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H +/* end file generic/stage2/tape_builder.h for haswell */ +/* end file generic/stage2/amalgamated.h for haswell */ + +// +// Stage 1 +// + +namespace simdjson { +namespace haswell { + +simdjson_warn_unused error_code implementation::create_dom_parser_implementation( + size_t capacity, + size_t max_depth, + std::unique_ptr& dst +) const noexcept { + dst.reset( new (std::nothrow) dom_parser_implementation() ); + if (!dst) { return MEMALLOC; } + if (auto err = dst->set_capacity(capacity)) + return err; + if (auto err = dst->set_max_depth(max_depth)) + return err; + return SUCCESS; +} + +namespace { + +using namespace simd; + +// This identifies structural characters (comma, colon, braces, brackets), +// and ASCII white-space ('\r','\n','\t',' '). +simdjson_inline json_character_block json_character_block::classify(const simd::simd8x64& in) { + // These lookups rely on the fact that anything < 127 will match the lower 4 bits, which is why + // we can't use the generic lookup_16. + const auto whitespace_table = simd8::repeat_16(' ', 100, 100, 100, 17, 100, 113, 2, 100, '\t', '\n', 112, 100, '\r', 100, 100); + + // The 6 operators (:,[]{}) have these values: + // + // , 2C + // : 3A + // [ 5B + // { 7B + // ] 5D + // } 7D + // + // If you use | 0x20 to turn [ and ] into { and }, the lower 4 bits of each character is unique. + // We exploit this, using a simd 4-bit lookup to tell us which character match against, and then + // match it (against | 0x20). + // + // To prevent recognizing other characters, everything else gets compared with 0, which cannot + // match due to the | 0x20. + // + // NOTE: Due to the | 0x20, this ALSO treats and (control characters 0C and 1A) like , + // and :. This gets caught in stage 2, which checks the actual character to ensure the right + // operators are in the right places. + const auto op_table = simd8::repeat_16( + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, ':', '{', // : = 3A, [ = 5B, { = 7B + ',', '}', 0, 0 // , = 2C, ] = 5D, } = 7D + ); + + // We compute whitespace and op separately. If later code only uses one or the + // other, given the fact that all functions are aggressively inlined, we can + // hope that useless computations will be omitted. This is namely case when + // minifying (we only need whitespace). + + const uint64_t whitespace = in.eq({ + _mm256_shuffle_epi8(whitespace_table, in.chunks[0]), + _mm256_shuffle_epi8(whitespace_table, in.chunks[1]) + }); + // Turn [ and ] into { and } + const simd8x64 curlified{ + in.chunks[0] | 0x20, + in.chunks[1] | 0x20 + }; + const uint64_t op = curlified.eq({ + _mm256_shuffle_epi8(op_table, in.chunks[0]), + _mm256_shuffle_epi8(op_table, in.chunks[1]) + }); + + return { whitespace, op }; +} + +simdjson_inline bool is_ascii(const simd8x64& input) { + return input.reduce_or().is_ascii(); +} + +simdjson_unused simdjson_inline simd8 must_be_continuation(const simd8 prev1, const simd8 prev2, const simd8 prev3) { + simd8 is_second_byte = prev1.saturating_sub(0xc0u-1); // Only 11______ will be > 0 + simd8 is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0 + simd8 is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0 + // Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine. + return simd8(is_second_byte | is_third_byte | is_fourth_byte) > int8_t(0); +} + +simdjson_inline simd8 must_be_2_3_continuation(const simd8 prev2, const simd8 prev3) { + simd8 is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0 + simd8 is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0 + // Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine. + return simd8(is_third_byte | is_fourth_byte) > int8_t(0); +} + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +// +// Stage 2 +// + +// +// Implementation-specific overrides +// +namespace simdjson { +namespace haswell { + +simdjson_warn_unused error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept { + return haswell::stage1::json_minifier::minify<128>(buf, len, dst, dst_len); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, stage1_mode streaming) noexcept { + this->buf = _buf; + this->len = _len; + return haswell::stage1::json_structural_indexer::index<128>(_buf, _len, *this, streaming); +} + +simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t len) const noexcept { + return haswell::stage1::generic_validate_utf8(buf,len); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { + return stage2::tape_builder::parse_document(*this, _doc); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { + return stage2::tape_builder::parse_document(*this, _doc); +} + +simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { + return haswell::stringparsing::parse_string(src, dst, replacement_char); +} + +simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept { + return haswell::stringparsing::parse_wobbly_string(src, dst); +} + +simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { + auto error = stage1(_buf, _len, stage1_mode::regular); + if (error) { return error; } + return stage2(_doc); +} + +} // namespace haswell +} // namespace simdjson + +/* including simdjson/haswell/end.h: #include */ +/* begin file simdjson/haswell/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_HASWELL +SIMDJSON_UNTARGET_REGION +#endif + +/* undefining SIMDJSON_IMPLEMENTATION from "haswell" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/haswell/end.h */ + +#endif // SIMDJSON_SRC_HASWELL_CPP +/* end file haswell.cpp */ +#endif +#if SIMDJSON_IMPLEMENTATION_ICELAKE +/* including icelake.cpp: #include */ +/* begin file icelake.cpp */ +#ifndef SIMDJSON_SRC_ICELAKE_CPP +#define SIMDJSON_SRC_ICELAKE_CPP + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +/* including simdjson/icelake.h: #include */ +/* begin file simdjson/icelake.h */ +#ifndef SIMDJSON_ICELAKE_H +#define SIMDJSON_ICELAKE_H + +/* including simdjson/icelake/begin.h: #include "simdjson/icelake/begin.h" */ +/* begin file simdjson/icelake/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "icelake" */ +#define SIMDJSON_IMPLEMENTATION icelake +/* including simdjson/icelake/base.h: #include "simdjson/icelake/base.h" */ +/* begin file simdjson/icelake/base.h */ +#ifndef SIMDJSON_ICELAKE_BASE_H +#define SIMDJSON_ICELAKE_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_ICELAKE +namespace simdjson { +/** + * Implementation for Icelake (Intel AVX512). + */ +namespace icelake { + +class implementation; + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_BASE_H +/* end file simdjson/icelake/base.h */ +/* including simdjson/icelake/intrinsics.h: #include "simdjson/icelake/intrinsics.h" */ +/* begin file simdjson/icelake/intrinsics.h */ +#ifndef SIMDJSON_ICELAKE_INTRINSICS_H +#define SIMDJSON_ICELAKE_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + * e.g., if __AVX2__ is set... in turn, we normally set these + * macros by compiling against the corresponding architecture + * (e.g., arch:AVX2, -mavx2, etc.) which compiles the whole + * software with these advanced instructions. In simdjson, we + * want to compile the whole program for a generic target, + * and only target our specific kernels. As a workaround, + * we directly include the needed headers. These headers would + * normally guard against such usage, but we carefully included + * (or ) before, so the headers + * are fooled. + */ +#include // for _blsr_u64 +#include // for __lzcnt64 +#include // for most things (AVX2, AVX512, _popcnt64) +#include +#include +#include +#include +#include // for _mm_clmulepi64_si128 +// Important: we need the AVX-512 headers: +#include +#include +#include +#include +#include +#include +#include +// unfortunately, we may not get _blsr_u64, but, thankfully, clang +// has it as a macro. +#ifndef _blsr_u64 +// we roll our own +#define _blsr_u64(n) ((n - 1) & n) +#endif // _blsr_u64 +#endif // SIMDJSON_CLANG_VISUAL_STUDIO + +static_assert(sizeof(__m512i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for icelake"); + +#endif // SIMDJSON_ICELAKE_INTRINSICS_H +/* end file simdjson/icelake/intrinsics.h */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_ICELAKE +SIMDJSON_TARGET_REGION("avx512f,avx512dq,avx512cd,avx512bw,avx512vbmi,avx512vbmi2,avx512vl,avx2,bmi,pclmul,lzcnt,popcnt") +#endif + +/* including simdjson/icelake/bitmanipulation.h: #include "simdjson/icelake/bitmanipulation.h" */ +/* begin file simdjson/icelake/bitmanipulation.h */ +#ifndef SIMDJSON_ICELAKE_BITMANIPULATION_H +#define SIMDJSON_ICELAKE_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return (int)_tzcnt_u64(input_num); +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + //////// + // You might expect the next line to be equivalent to + // return (int)_tzcnt_u64(input_num); + // but the generated code differs and might be less efficient? + //////// + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return _blsr_u64(input_num); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { + return int(_lzcnt_u64(input_num)); +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_BITMANIPULATION_H +/* end file simdjson/icelake/bitmanipulation.h */ +/* including simdjson/icelake/bitmask.h: #include "simdjson/icelake/bitmask.h" */ +/* begin file simdjson/icelake/bitmask.h */ +#ifndef SIMDJSON_ICELAKE_BITMASK_H +#define SIMDJSON_ICELAKE_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(const uint64_t bitmask) { + // There should be no such thing with a processor supporting avx2 + // but not clmul. + __m128i all_ones = _mm_set1_epi8('\xFF'); + __m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0ULL, bitmask), all_ones, 0); + return _mm_cvtsi128_si64(result); +} + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_BITMASK_H +/* end file simdjson/icelake/bitmask.h */ +/* including simdjson/icelake/simd.h: #include "simdjson/icelake/simd.h" */ +/* begin file simdjson/icelake/simd.h */ +#ifndef SIMDJSON_ICELAKE_SIMD_H +#define SIMDJSON_ICELAKE_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if defined(__GNUC__) && !defined(__clang__) +#if __GNUC__ == 8 +#define SIMDJSON_GCC8 1 +#endif // __GNUC__ == 8 +#endif // defined(__GNUC__) && !defined(__clang__) + +#if SIMDJSON_GCC8 +/** + * GCC 8 fails to provide _mm512_set_epi8. We roll our own. + */ +inline __m512i _mm512_set_epi8(uint8_t a0, uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4, uint8_t a5, uint8_t a6, uint8_t a7, uint8_t a8, uint8_t a9, uint8_t a10, uint8_t a11, uint8_t a12, uint8_t a13, uint8_t a14, uint8_t a15, uint8_t a16, uint8_t a17, uint8_t a18, uint8_t a19, uint8_t a20, uint8_t a21, uint8_t a22, uint8_t a23, uint8_t a24, uint8_t a25, uint8_t a26, uint8_t a27, uint8_t a28, uint8_t a29, uint8_t a30, uint8_t a31, uint8_t a32, uint8_t a33, uint8_t a34, uint8_t a35, uint8_t a36, uint8_t a37, uint8_t a38, uint8_t a39, uint8_t a40, uint8_t a41, uint8_t a42, uint8_t a43, uint8_t a44, uint8_t a45, uint8_t a46, uint8_t a47, uint8_t a48, uint8_t a49, uint8_t a50, uint8_t a51, uint8_t a52, uint8_t a53, uint8_t a54, uint8_t a55, uint8_t a56, uint8_t a57, uint8_t a58, uint8_t a59, uint8_t a60, uint8_t a61, uint8_t a62, uint8_t a63) { + return _mm512_set_epi64(uint64_t(a7) + (uint64_t(a6) << 8) + (uint64_t(a5) << 16) + (uint64_t(a4) << 24) + (uint64_t(a3) << 32) + (uint64_t(a2) << 40) + (uint64_t(a1) << 48) + (uint64_t(a0) << 56), + uint64_t(a15) + (uint64_t(a14) << 8) + (uint64_t(a13) << 16) + (uint64_t(a12) << 24) + (uint64_t(a11) << 32) + (uint64_t(a10) << 40) + (uint64_t(a9) << 48) + (uint64_t(a8) << 56), + uint64_t(a23) + (uint64_t(a22) << 8) + (uint64_t(a21) << 16) + (uint64_t(a20) << 24) + (uint64_t(a19) << 32) + (uint64_t(a18) << 40) + (uint64_t(a17) << 48) + (uint64_t(a16) << 56), + uint64_t(a31) + (uint64_t(a30) << 8) + (uint64_t(a29) << 16) + (uint64_t(a28) << 24) + (uint64_t(a27) << 32) + (uint64_t(a26) << 40) + (uint64_t(a25) << 48) + (uint64_t(a24) << 56), + uint64_t(a39) + (uint64_t(a38) << 8) + (uint64_t(a37) << 16) + (uint64_t(a36) << 24) + (uint64_t(a35) << 32) + (uint64_t(a34) << 40) + (uint64_t(a33) << 48) + (uint64_t(a32) << 56), + uint64_t(a47) + (uint64_t(a46) << 8) + (uint64_t(a45) << 16) + (uint64_t(a44) << 24) + (uint64_t(a43) << 32) + (uint64_t(a42) << 40) + (uint64_t(a41) << 48) + (uint64_t(a40) << 56), + uint64_t(a55) + (uint64_t(a54) << 8) + (uint64_t(a53) << 16) + (uint64_t(a52) << 24) + (uint64_t(a51) << 32) + (uint64_t(a50) << 40) + (uint64_t(a49) << 48) + (uint64_t(a48) << 56), + uint64_t(a63) + (uint64_t(a62) << 8) + (uint64_t(a61) << 16) + (uint64_t(a60) << 24) + (uint64_t(a59) << 32) + (uint64_t(a58) << 40) + (uint64_t(a57) << 48) + (uint64_t(a56) << 56)); +} +#endif // SIMDJSON_GCC8 + + + +namespace simdjson { +namespace icelake { +namespace { +namespace simd { + + // Forward-declared so they can be used by splat and friends. + template + struct base { + __m512i value; + + // Zero constructor + simdjson_inline base() : value{__m512i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m512i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m512i&() const { return this->value; } + simdjson_inline operator __m512i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm512_or_si512(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm512_and_si512(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm512_xor_si512(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm512_andnot_si512(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + // Forward-declared so they can be used by splat and friends. + template + struct simd8; + + template> + struct base8: base> { + typedef uint32_t bitmask_t; + typedef uint64_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m512i _value) : base>(_value) {} + + friend simdjson_really_inline uint64_t operator==(const simd8 lhs, const simd8 rhs) { + return _mm512_cmpeq_epi8_mask(lhs, rhs); + } + + static const int SIZE = sizeof(base::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + // workaround for compilers unable to figure out that 16 - N is a constant (GCC 8) + constexpr int shift = 16 - N; + return _mm512_alignr_epi8(*this, _mm512_permutex2var_epi64(prev_chunk, _mm512_set_epi64(13, 12, 11, 10, 9, 8, 7, 6), *this), shift); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm512_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m512i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + simdjson_inline bool any() const { return !!_mm512_test_epi8_mask (*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm512_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm512_setzero_si512(); } + static simdjson_inline simd8 load(const T values[64]) { + return _mm512_loadu_si512(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m512i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[64]) const { return _mm512_storeu_si512(reinterpret_cast<__m512i *>(dst), *this); } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm512_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm512_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm512_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 32 - count_ones(mask) bytes of the result are significant but 32 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint64_t mask, L * output) const { + _mm512_mask_compressstoreu_epi8 (output,~mask,*this); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m512i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t values[64]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15, + int8_t v16, int8_t v17, int8_t v18, int8_t v19, int8_t v20, int8_t v21, int8_t v22, int8_t v23, + int8_t v24, int8_t v25, int8_t v26, int8_t v27, int8_t v28, int8_t v29, int8_t v30, int8_t v31, + int8_t v32, int8_t v33, int8_t v34, int8_t v35, int8_t v36, int8_t v37, int8_t v38, int8_t v39, + int8_t v40, int8_t v41, int8_t v42, int8_t v43, int8_t v44, int8_t v45, int8_t v46, int8_t v47, + int8_t v48, int8_t v49, int8_t v50, int8_t v51, int8_t v52, int8_t v53, int8_t v54, int8_t v55, + int8_t v56, int8_t v57, int8_t v58, int8_t v59, int8_t v60, int8_t v61, int8_t v62, int8_t v63 + ) : simd8(_mm512_set_epi8( + v63, v62, v61, v60, v59, v58, v57, v56, + v55, v54, v53, v52, v51, v50, v49, v48, + v47, v46, v45, v44, v43, v42, v41, v40, + v39, v38, v37, v36, v35, v34, v33, v32, + v31, v30, v29, v28, v27, v26, v25, v24, + v23, v22, v21, v20, v19, v18, v17, v16, + v15, v14, v13, v12, v11, v10, v9, v8, + v7, v6, v5, v4, v3, v2, v1, v0 + )) {} + + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm512_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm512_min_epi8(*this, other); } + + simdjson_inline simd8 operator>(const simd8 other) const { return _mm512_maskz_abs_epi8(_mm512_cmpgt_epi8_mask(*this, other),_mm512_set1_epi8(uint8_t(0x80))); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm512_maskz_abs_epi8(_mm512_cmpgt_epi8_mask(other, *this),_mm512_set1_epi8(uint8_t(0x80))); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m512i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t values[64]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15, + uint8_t v16, uint8_t v17, uint8_t v18, uint8_t v19, uint8_t v20, uint8_t v21, uint8_t v22, uint8_t v23, + uint8_t v24, uint8_t v25, uint8_t v26, uint8_t v27, uint8_t v28, uint8_t v29, uint8_t v30, uint8_t v31, + uint8_t v32, uint8_t v33, uint8_t v34, uint8_t v35, uint8_t v36, uint8_t v37, uint8_t v38, uint8_t v39, + uint8_t v40, uint8_t v41, uint8_t v42, uint8_t v43, uint8_t v44, uint8_t v45, uint8_t v46, uint8_t v47, + uint8_t v48, uint8_t v49, uint8_t v50, uint8_t v51, uint8_t v52, uint8_t v53, uint8_t v54, uint8_t v55, + uint8_t v56, uint8_t v57, uint8_t v58, uint8_t v59, uint8_t v60, uint8_t v61, uint8_t v62, uint8_t v63 + ) : simd8(_mm512_set_epi8( + v63, v62, v61, v60, v59, v58, v57, v56, + v55, v54, v53, v52, v51, v50, v49, v48, + v47, v46, v45, v44, v43, v42, v41, v40, + v39, v38, v37, v36, v35, v34, v33, v32, + v31, v30, v29, v28, v27, v26, v25, v24, + v23, v22, v21, v20, v19, v18, v17, v16, + v15, v14, v13, v12, v11, v10, v9, v8, + v7, v6, v5, v4, v3, v2, v1, v0 + )) {} + + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm512_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm512_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm512_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm512_min_epu8(other, *this); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline uint64_t operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline uint64_t operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->lt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return _mm512_mask_blend_epi8(*this == uint8_t(0), _mm512_set1_epi8(0), _mm512_set1_epi8(-1)); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + + simdjson_inline bool is_ascii() const { return _mm512_movepi8_mask(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { + return !_mm512_test_epi8_mask(*this, *this); + } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return !_mm512_test_epi8_mask(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm512_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm512_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline uint64_t get_bit() const { return _mm512_movepi8_mask(_mm512_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 1, "Icelake kernel should use one register per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1) : chunks{chunk0, chunk1} {} + simdjson_inline simd8x64(const simd8 chunk0) : chunks{chunk0} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr)} {} + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + this->chunks[0].compress(mask, output); + return 64 - count_ones(mask); + } + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + } + + simdjson_inline simd8 reduce_or() const { + return this->chunks[0]; + } + + simdjson_inline simd8x64 bit_or(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] | mask + ); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return this->chunks[0] == mask; + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return this->chunks[0] == other.chunks[0]; + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return this->chunks[0] <= mask; + } + }; // struct simd8x64 + +} // namespace simd + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_SIMD_H +/* end file simdjson/icelake/simd.h */ +/* including simdjson/icelake/stringparsing_defs.h: #include "simdjson/icelake/stringparsing_defs.h" */ +/* begin file simdjson/icelake/stringparsing_defs.h */ +#ifndef SIMDJSON_ICELAKE_STRINGPARSING_DEFS_H +#define SIMDJSON_ICELAKE_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/simd.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 64; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return ((quote_bits - 1) & bs_bits) != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint64_t bs_bits; + uint64_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 15 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v(src); + // store to dest unconditionally - we can overwrite the bits we don't like later + v.store(dst); + return { + static_cast(v == '\\'), // bs_bits + static_cast(v == '"'), // quote_bits + }; +} + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_STRINGPARSING_DEFS_H +/* end file simdjson/icelake/stringparsing_defs.h */ +/* including simdjson/icelake/numberparsing_defs.h: #include "simdjson/icelake/numberparsing_defs.h" */ +/* begin file simdjson/icelake/numberparsing_defs.h */ +#ifndef SIMDJSON_ICELAKE_NUMBERPARSING_DEFS_H +#define SIMDJSON_ICELAKE_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace numberparsing { + +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + // this actually computes *16* values so we are being wasteful. + const __m128i ascii0 = _mm_set1_epi8('0'); + const __m128i mul_1_10 = + _mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1); + const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1); + const __m128i mul_1_10000 = + _mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1); + const __m128i input = _mm_sub_epi8( + _mm_loadu_si128(reinterpret_cast(chars)), ascii0); + const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10); + const __m128i t2 = _mm_madd_epi16(t1, mul_1_100); + const __m128i t3 = _mm_packus_epi32(t2, t2); + const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000); + return _mm_cvtsi128_si32( + t4); // only captures the sum of the first 8 digits, drop the rest +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace icelake +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_ICELAKE_NUMBERPARSING_DEFS_H +/* end file simdjson/icelake/numberparsing_defs.h */ +/* end file simdjson/icelake/begin.h */ +/* including simdjson/generic/amalgamated.h for icelake: #include "simdjson/generic/amalgamated.h" */ +/* begin file simdjson/generic/amalgamated.h for icelake */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_DEPENDENCIES_H) +#error simdjson/generic/dependencies.h must be included before simdjson/generic/amalgamated.h! +#endif + +/* including simdjson/generic/base.h for icelake: #include "simdjson/generic/base.h" */ +/* begin file simdjson/generic/base.h for icelake */ +#ifndef SIMDJSON_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): // If we haven't got an implementation yet, we're in the editor, editing a generic file! Just */ +/* amalgamation skipped (editor-only): // use the most advanced one we can so the most possible stuff can be tested. */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation_detection.h" */ +/* amalgamation skipped (editor-only): #if SIMDJSON_IMPLEMENTATION_ICELAKE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_HASWELL */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_WESTMERE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_ARM64 */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_PPC64 */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_FALLBACK */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/begin.h" */ +/* amalgamation skipped (editor-only): #else */ +/* amalgamation skipped (editor-only): #error "All possible implementations (including fallback) have been disabled! simdjson will not run." */ +/* amalgamation skipped (editor-only): #endif */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { + +struct open_container; +class dom_parser_implementation; + +/** + * The type of a JSON number + */ +enum class number_type { + floating_point_number=1, /// a binary64 number + signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + unsigned_integer /// a positive integer larger or equal to 1<<63 +}; + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_BASE_H +/* end file simdjson/generic/base.h for icelake */ +/* including simdjson/generic/jsoncharutils.h for icelake: #include "simdjson/generic/jsoncharutils.h" */ +/* begin file simdjson/generic/jsoncharutils.h for icelake */ +#ifndef SIMDJSON_GENERIC_JSONCHARUTILS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_JSONCHARUTILS_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/jsoncharutils_tables.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { +namespace jsoncharutils { + +// return non-zero if not a structural or whitespace char +// zero otherwise +simdjson_inline uint32_t is_not_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace_negated[c]; +} + +simdjson_inline uint32_t is_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace[c]; +} + +// returns a value with the high 16 bits set if not valid +// otherwise returns the conversion of the 4 hex digits at src into the bottom +// 16 bits of the 32-bit return register +// +// see +// https://lemire.me/blog/2019/04/17/parsing-short-hexadecimal-strings-efficiently/ +static inline uint32_t hex_to_u32_nocheck( + const uint8_t *src) { // strictly speaking, static inline is a C-ism + uint32_t v1 = internal::digit_to_val32[630 + src[0]]; + uint32_t v2 = internal::digit_to_val32[420 + src[1]]; + uint32_t v3 = internal::digit_to_val32[210 + src[2]]; + uint32_t v4 = internal::digit_to_val32[0 + src[3]]; + return v1 | v2 | v3 | v4; +} + +// given a code point cp, writes to c +// the utf-8 code, outputting the length in +// bytes, if the length is zero, the code point +// is invalid +// +// This can possibly be made faster using pdep +// and clz and table lookups, but JSON documents +// have few escaped code points, and the following +// function looks cheap. +// +// Note: we assume that surrogates are treated separately +// +simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) { + if (cp <= 0x7F) { + c[0] = uint8_t(cp); + return 1; // ascii + } + if (cp <= 0x7FF) { + c[0] = uint8_t((cp >> 6) + 192); + c[1] = uint8_t((cp & 63) + 128); + return 2; // universal plane + // Surrogates are treated elsewhere... + //} //else if (0xd800 <= cp && cp <= 0xdfff) { + // return 0; // surrogates // could put assert here + } else if (cp <= 0xFFFF) { + c[0] = uint8_t((cp >> 12) + 224); + c[1] = uint8_t(((cp >> 6) & 63) + 128); + c[2] = uint8_t((cp & 63) + 128); + return 3; + } else if (cp <= 0x10FFFF) { // if you know you have a valid code point, this + // is not needed + c[0] = uint8_t((cp >> 18) + 240); + c[1] = uint8_t(((cp >> 12) & 63) + 128); + c[2] = uint8_t(((cp >> 6) & 63) + 128); + c[3] = uint8_t((cp & 63) + 128); + return 4; + } + // will return 0 when the code point was too large. + return 0; // bad r +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +} // namespace jsoncharutils +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_JSONCHARUTILS_H +/* end file simdjson/generic/jsoncharutils.h for icelake */ +/* including simdjson/generic/atomparsing.h for icelake: #include "simdjson/generic/atomparsing.h" */ +/* begin file simdjson/generic/atomparsing.h for icelake */ +#ifndef SIMDJSON_GENERIC_ATOMPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ATOMPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace icelake { +namespace { +/// @private +namespace atomparsing { + +// The string_to_uint32 is exclusively used to map literal strings to 32-bit values. +// We use memcpy instead of a pointer cast to avoid undefined behaviors since we cannot +// be certain that the character pointer will be properly aligned. +// You might think that using memcpy makes this function expensive, but you'd be wrong. +// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false"); +// to the compile-time constant 1936482662. +simdjson_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; } + + +// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive. +// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about. +simdjson_warn_unused +simdjson_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) { + uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++) + static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes"); + std::memcpy(&srcval, src, sizeof(uint32_t)); + return srcval ^ string_to_uint32(atom); +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src) { + return (str4ncmp(src, "true") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_true_atom(src); } + else if (len == 4) { return !str4ncmp(src, "true"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src) { + return (str4ncmp(src+1, "alse") | jsoncharutils::is_not_structural_or_whitespace(src[5])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src, size_t len) { + if (len > 5) { return is_valid_false_atom(src); } + else if (len == 5) { return !str4ncmp(src+1, "alse"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src) { + return (str4ncmp(src, "null") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_null_atom(src); } + else if (len == 4) { return !str4ncmp(src, "null"); } + else { return false; } +} + +} // namespace atomparsing +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ATOMPARSING_H +/* end file simdjson/generic/atomparsing.h for icelake */ +/* including simdjson/generic/dom_parser_implementation.h for icelake: #include "simdjson/generic/dom_parser_implementation.h" */ +/* begin file simdjson/generic/dom_parser_implementation.h for icelake */ +#ifndef SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { + +// expectation: sizeof(open_container) = 64/8. +struct open_container { + uint32_t tape_index; // where, on the tape, does the scope ([,{) begins + uint32_t count; // how many elements in the scope +}; // struct open_container + +static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits"); + +class dom_parser_implementation final : public internal::dom_parser_implementation { +public: + /** Tape location of each open { or [ */ + std::unique_ptr open_containers{}; + /** Whether each open container is a [ or { */ + std::unique_ptr is_array{}; + /** Buffer passed to stage 1 */ + const uint8_t *buf{}; + /** Length passed to stage 1 */ + size_t len{0}; + /** Document passed to stage 2 */ + dom::document *doc{}; + + inline dom_parser_implementation() noexcept; + inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; + inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; + dom_parser_implementation(const dom_parser_implementation &) = delete; + dom_parser_implementation &operator=(const dom_parser_implementation &) = delete; + + simdjson_warn_unused error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage1(const uint8_t *buf, size_t len, stage1_mode partial) noexcept final; + simdjson_warn_unused error_code stage2(dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage2_next(dom::document &doc) noexcept final; + simdjson_warn_unused uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept final; + simdjson_warn_unused uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept final; + inline simdjson_warn_unused error_code set_capacity(size_t capacity) noexcept final; + inline simdjson_warn_unused error_code set_max_depth(size_t max_depth) noexcept final; +private: + simdjson_inline simdjson_warn_unused error_code set_capacity_stage1(size_t capacity); + +}; + +} // namespace icelake +} // namespace simdjson + +namespace simdjson { +namespace icelake { + +inline dom_parser_implementation::dom_parser_implementation() noexcept = default; +inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; +inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; + +// Leaving these here so they can be inlined if so desired +inline simdjson_warn_unused error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept { + if(capacity > SIMDJSON_MAXSIZE_BYTES) { return CAPACITY; } + // Stage 1 index output + size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7; + structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] ); + if (!structural_indexes) { _capacity = 0; return MEMALLOC; } + structural_indexes[0] = 0; + n_structural_indexes = 0; + + _capacity = capacity; + return SUCCESS; +} + +inline simdjson_warn_unused error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept { + // Stage 2 stacks + open_containers.reset(new (std::nothrow) open_container[max_depth]); + is_array.reset(new (std::nothrow) bool[max_depth]); + if (!is_array || !open_containers) { _max_depth = 0; return MEMALLOC; } + + _max_depth = max_depth; + return SUCCESS; +} + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file simdjson/generic/dom_parser_implementation.h for icelake */ +/* including simdjson/generic/implementation_simdjson_result_base.h for icelake: #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base.h for icelake */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { + +// This is a near copy of include/error.h's implementation_simdjson_result_base, except it doesn't use std::pair +// so we can avoid inlining errors +// TODO reconcile these! +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + * + * This is a base class for implementations that want to add functions to the result type for + * chaining. + * + * Override like: + * + * struct simdjson_result : public internal::implementation_simdjson_result_base { + * simdjson_result() noexcept : internal::implementation_simdjson_result_base() {} + * simdjson_result(error_code error) noexcept : internal::implementation_simdjson_result_base(error) {} + * simdjson_result(T &&value) noexcept : internal::implementation_simdjson_result_base(std::forward(value)) {} + * simdjson_result(T &&value, error_code error) noexcept : internal::implementation_simdjson_result_base(value, error) {} + * // Your extra methods here + * } + * + * Then any method returning simdjson_result will be chainable with your methods. + */ +template +struct implementation_simdjson_result_base { + + /** + * Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline implementation_simdjson_result_base() noexcept = default; + + /** + * Create a new error result. + */ + simdjson_inline implementation_simdjson_result_base(error_code error) noexcept; + + /** + * Create a new successful result. + */ + simdjson_inline implementation_simdjson_result_base(T &&value) noexcept; + + /** + * Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline implementation_simdjson_result_base(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); + + +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T& value_unsafe() & noexcept; + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; +protected: + /** users should never directly access first and second. **/ + T first{}; /** Users should never directly access 'first'. **/ + error_code second{UNINITIALIZED}; /** Users should never directly access 'second'. **/ +}; // struct implementation_simdjson_result_base + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H +/* end file simdjson/generic/implementation_simdjson_result_base.h for icelake */ +/* including simdjson/generic/numberparsing.h for icelake: #include "simdjson/generic/numberparsing.h" */ +/* begin file simdjson/generic/numberparsing.h for icelake */ +#ifndef SIMDJSON_GENERIC_NUMBERPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_NUMBERPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include +#include + +namespace simdjson { +namespace icelake { +namespace numberparsing { + +#ifdef JSON_TEST_NUMBERS +#define INVALID_NUMBER(SRC) (found_invalid_number((SRC)), NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (found_integer((VALUE), (SRC)), (WRITER).append_s64((VALUE))) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (found_unsigned_integer((VALUE), (SRC)), (WRITER).append_u64((VALUE))) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (found_float((VALUE), (SRC)), (WRITER).append_double((VALUE))) +#else +#define INVALID_NUMBER(SRC) (NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (WRITER).append_s64((VALUE)) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (WRITER).append_u64((VALUE)) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (WRITER).append_double((VALUE)) +#endif + +namespace { + +// Convert a mantissa, an exponent and a sign bit into an ieee64 double. +// The real_exponent needs to be in [0, 2046] (technically real_exponent = 2047 would be acceptable). +// The mantissa should be in [0,1<<53). The bit at index (1ULL << 52) while be zeroed. +simdjson_inline double to_double(uint64_t mantissa, uint64_t real_exponent, bool negative) { + double d; + mantissa &= ~(1ULL << 52); + mantissa |= real_exponent << 52; + mantissa |= ((static_cast(negative)) << 63); + std::memcpy(&d, &mantissa, sizeof(d)); + return d; +} + +// Attempts to compute i * 10^(power) exactly; and if "negative" is +// true, negate the result. +// This function will only work in some cases, when it does not work, success is +// set to false. This should work *most of the time* (like 99% of the time). +// We assume that power is in the [smallest_power, +// largest_power] interval: the caller is responsible for this check. +simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative, double &d) { + // we start with a fast path + // It was described in + // Clinger WD. How to read floating point numbers accurately. + // ACM SIGPLAN Notices. 1990 +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + // We cannot be certain that x/y is rounded to nearest. + if (0 <= power && power <= 22 && i <= 9007199254740991) +#else + if (-22 <= power && power <= 22 && i <= 9007199254740991) +#endif + { + // convert the integer into a double. This is lossless since + // 0 <= i <= 2^53 - 1. + d = double(i); + // + // The general idea is as follows. + // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then + // 1) Both s and p can be represented exactly as 64-bit floating-point + // values + // (binary64). + // 2) Because s and p can be represented exactly as floating-point values, + // then s * p + // and s / p will produce correctly rounded values. + // + if (power < 0) { + d = d / simdjson::internal::power_of_ten[-power]; + } else { + d = d * simdjson::internal::power_of_ten[power]; + } + if (negative) { + d = -d; + } + return true; + } + // When 22 < power && power < 22 + 16, we could + // hope for another, secondary fast path. It was + // described by David M. Gay in "Correctly rounded + // binary-decimal and decimal-binary conversions." (1990) + // If you need to compute i * 10^(22 + x) for x < 16, + // first compute i * 10^x, if you know that result is exact + // (e.g., when i * 10^x < 2^53), + // then you can still proceed and do (i * 10^x) * 10^22. + // Is this worth your time? + // You need 22 < power *and* power < 22 + 16 *and* (i * 10^(x-22) < 2^53) + // for this second fast path to work. + // If you you have 22 < power *and* power < 22 + 16, and then you + // optimistically compute "i * 10^(x-22)", there is still a chance that you + // have wasted your time if i * 10^(x-22) >= 2^53. It makes the use cases of + // this optimization maybe less common than we would like. Source: + // http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + // also used in RapidJSON: https://rapidjson.org/strtod_8h_source.html + + // The fast path has now failed, so we are failing back on the slower path. + + // In the slow path, we need to adjust i so that it is > 1<<63 which is always + // possible, except if i == 0, so we handle i == 0 separately. + if(i == 0) { + d = negative ? -0.0 : 0.0; + return true; + } + + + // The exponent is 1024 + 63 + power + // + floor(log(5**power)/log(2)). + // The 1024 comes from the ieee64 standard. + // The 63 comes from the fact that we use a 64-bit word. + // + // Computing floor(log(5**power)/log(2)) could be + // slow. Instead we use a fast function. + // + // For power in (-400,350), we have that + // (((152170 + 65536) * power ) >> 16); + // is equal to + // floor(log(5**power)/log(2)) + power when power >= 0 + // and it is equal to + // ceil(log(5**-power)/log(2)) + power when power < 0 + // + // The 65536 is (1<<16) and corresponds to + // (65536 * power) >> 16 ---> power + // + // ((152170 * power ) >> 16) is equal to + // floor(log(5**power)/log(2)) + // + // Note that this is not magic: 152170/(1<<16) is + // approximatively equal to log(5)/log(2). + // The 1<<16 value is a power of two; we could use a + // larger power of 2 if we wanted to. + // + int64_t exponent = (((152170 + 65536) * power) >> 16) + 1024 + 63; + + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(i); + i <<= lz; + + + // We are going to need to do some 64-bit arithmetic to get a precise product. + // We use a table lookup approach. + // It is safe because + // power >= smallest_power + // and power <= largest_power + // We recover the mantissa of the power, it has a leading 1. It is always + // rounded down. + // + // We want the most significant 64 bits of the product. We know + // this will be non-zero because the most significant bit of i is + // 1. + const uint32_t index = 2 * uint32_t(power - simdjson::internal::smallest_power); + // Optimization: It may be that materializing the index as a variable might confuse some compilers and prevent effective complex-addressing loads. (Done for code clarity.) + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); + // Both i and power_of_five_128[index] have their most significant bit set to 1 which + // implies that the either the most or the second most significant bit of the product + // is 1. We pack values in this manner for efficiency reasons: it maximizes the use + // we make of the product. It also makes it easy to reason about the product: there + // is 0 or 1 leading zero in the product. + + // Unless the least significant 9 bits of the high (64-bit) part of the full + // product are all 1s, then we know that the most significant 55 bits are + // exact and no further work is needed. Having 55 bits is necessary because + // we need 53 bits for the mantissa but we have to have one rounding bit and + // we can waste a bit if the most significant bit of the product is zero. + if((firstproduct.high & 0x1FF) == 0x1FF) { + // We want to compute i * 5^q, but only care about the top 55 bits at most. + // Consider the scenario where q>=0. Then 5^q may not fit in 64-bits. Doing + // the full computation is wasteful. So we do what is called a "truncated + // multiplication". + // We take the most significant 64-bits, and we put them in + // power_of_five_128[index]. Usually, that's good enough to approximate i * 5^q + // to the desired approximation using one multiplication. Sometimes it does not suffice. + // Then we store the next most significant 64 bits in power_of_five_128[index + 1], and + // then we get a better approximation to i * 5^q. + // + // That's for when q>=0. The logic for q<0 is somewhat similar but it is somewhat + // more complicated. + // + // There is an extra layer of complexity in that we need more than 55 bits of + // accuracy in the round-to-even scenario. + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if(secondproduct.high > firstproduct.low) { firstproduct.high++; } + // As it has been proven by Noble Mushtak and Daniel Lemire in "Fast Number Parsing Without + // Fallback" (https://arxiv.org/abs/2212.06644), at this point we are sure that the product + // is sufficiently accurate, and more computation is not needed. + } + uint64_t lower = firstproduct.low; + uint64_t upper = firstproduct.high; + // The final mantissa should be 53 bits with a leading 1. + // We shift it so that it occupies 54 bits with a leading 1. + /////// + uint64_t upperbit = upper >> 63; + uint64_t mantissa = upper >> (upperbit + 9); + lz += int(1 ^ upperbit); + + // Here we have mantissa < (1<<54). + int64_t real_exponent = exponent - lz; + if (simdjson_unlikely(real_exponent <= 0)) { // we have a subnormal? + // Here have that real_exponent <= 0 so -real_exponent >= 0 + if(-real_exponent + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure. + d = negative ? -0.0 : 0.0; + return true; + } + // next line is safe because -real_exponent + 1 < 0 + mantissa >>= -real_exponent + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0. + mantissa += (mantissa & 1); // round up + mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + real_exponent = (mantissa < (uint64_t(1) << 52)) ? 0 : 1; + d = to_double(mantissa, real_exponent, negative); + return true; + } + // We have to round to even. The "to even" part + // is only a problem when we are right in between two floats + // which we guard against. + // If we have lots of trailing zeros, we may fall right between two + // floating-point values. + // + // The round-to-even cases take the form of a number 2m+1 which is in (2^53,2^54] + // times a power of two. That is, it is right between a number with binary significand + // m and another number with binary significand m+1; and it must be the case + // that it cannot be represented by a float itself. + // + // We must have that w * 10 ^q == (2m+1) * 2^p for some power of two 2^p. + // Recall that 10^q = 5^q * 2^q. + // When q >= 0, we must have that (2m+1) is divible by 5^q, so 5^q <= 2^54. We have that + // 5^23 <= 2^54 and it is the last power of five to qualify, so q <= 23. + // When q<0, we have w >= (2m+1) x 5^{-q}. We must have that w<2^{64} so + // (2m+1) x 5^{-q} < 2^{64}. We have that 2m+1>2^{53}. Hence, we must have + // 2^{53} x 5^{-q} < 2^{64}. + // Hence we have 5^{-q} < 2^{11}$ or q>= -4. + // + // We require lower <= 1 and not lower == 0 because we could not prove that + // that lower == 0 is implied; but we could prove that lower <= 1 is a necessary and sufficient test. + if (simdjson_unlikely((lower <= 1) && (power >= -4) && (power <= 23) && ((mantissa & 3) == 1))) { + if((mantissa << (upperbit + 64 - 53 - 2)) == upper) { + mantissa &= ~1; // flip it so that we do not round up + } + } + + mantissa += mantissa & 1; + mantissa >>= 1; + + // Here we have mantissa < (1<<53), unless there was an overflow + if (mantissa >= (1ULL << 53)) { + ////////// + // This will happen when parsing values such as 7.2057594037927933e+16 + //////// + mantissa = (1ULL << 52); + real_exponent++; + } + mantissa &= ~(1ULL << 52); + // we have to check that real_exponent is in range, otherwise we bail out + if (simdjson_unlikely(real_exponent > 2046)) { + // We have an infinite value!!! We could actually throw an error here if we could. + return false; + } + d = to_double(mantissa, real_exponent, negative); + return true; +} + +// We call a fallback floating-point parser that might be slow. Note +// it will accept JSON numbers, but the JSON spec. is more restrictive so +// before you call parse_float_fallback, you need to have validated the input +// string with the JSON grammar. +// It will return an error (false) if the parsed number is infinite. +// The string parsing itself always succeeds. We know that there is at least +// one digit. +static bool parse_float_fallback(const uint8_t *ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +static bool parse_float_fallback(const uint8_t *ptr, const uint8_t *end_ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr), reinterpret_cast(end_ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +// check quickly whether the next 8 chars are made of digits +// at a glance, it looks better than Mula's +// http://0x80.pl/articles/swar-digits-validate.html +simdjson_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) { + uint64_t val; + // this can read up to 7 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(7 <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be bigger than 7"); + std::memcpy(&val, chars, 8); + // a branchy method might be faster: + // return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030) + // && (( (val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0 ) == + // 0x3030303030303030); + return (((val & 0xF0F0F0F0F0F0F0F0) | + (((val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4)) == + 0x3333333333333333); +} + +template +SIMDJSON_NO_SANITIZE_UNDEFINED // We deliberately allow overflow here and check later +simdjson_inline bool parse_digit(const uint8_t c, I &i) { + const uint8_t digit = static_cast(c - '0'); + if (digit > 9) { + return false; + } + // PERF NOTE: multiplication by 10 is cheaper than arbitrary integer multiplication + i = 10 * i + digit; // might overflow, we will handle the overflow later + return true; +} + +simdjson_inline error_code parse_decimal_after_separator(simdjson_unused const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) { + // we continue with the fiction that we have an integer. If the + // floating point number is representable as x * 10^z for some integer + // z that fits in 53 bits, then we will be able to convert back the + // the integer into a float in a lossless manner. + const uint8_t *const first_after_period = p; + +#ifdef SIMDJSON_SWAR_NUMBER_PARSING +#if SIMDJSON_SWAR_NUMBER_PARSING + // this helps if we have lots of decimals! + // this turns out to be frequent enough. + if (is_made_of_eight_digits_fast(p)) { + i = i * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + } +#endif // SIMDJSON_SWAR_NUMBER_PARSING +#endif // #ifdef SIMDJSON_SWAR_NUMBER_PARSING + // Unrolling the first digit makes a small difference on some implementations (e.g. westmere) + if (parse_digit(*p, i)) { ++p; } + while (parse_digit(*p, i)) { p++; } + exponent = first_after_period - p; + // Decimal without digits (123.) is illegal + if (exponent == 0) { + return INVALID_NUMBER(src); + } + return SUCCESS; +} + +simdjson_inline error_code parse_exponent(simdjson_unused const uint8_t *const src, const uint8_t *&p, int64_t &exponent) { + // Exp Sign: -123.456e[-]78 + bool neg_exp = ('-' == *p); + if (neg_exp || '+' == *p) { p++; } // Skip + as well + + // Exponent: -123.456e-[78] + auto start_exp = p; + int64_t exp_number = 0; + while (parse_digit(*p, exp_number)) { ++p; } + // It is possible for parse_digit to overflow. + // In particular, it could overflow to INT64_MIN, and we cannot do - INT64_MIN. + // Thus we *must* check for possible overflow before we negate exp_number. + + // Performance notes: it may seem like combining the two "simdjson_unlikely checks" below into + // a single simdjson_unlikely path would be faster. The reasoning is sound, but the compiler may + // not oblige and may, in fact, generate two distinct paths in any case. It might be + // possible to do uint64_t(p - start_exp - 1) >= 18 but it could end up trading off + // instructions for a simdjson_likely branch, an unconclusive gain. + + // If there were no digits, it's an error. + if (simdjson_unlikely(p == start_exp)) { + return INVALID_NUMBER(src); + } + // We have a valid positive exponent in exp_number at this point, except that + // it may have overflowed. + + // If there were more than 18 digits, we may have overflowed the integer. We have to do + // something!!!! + if (simdjson_unlikely(p > start_exp+18)) { + // Skip leading zeroes: 1e000000000000000000001 is technically valid and doesn't overflow + while (*start_exp == '0') { start_exp++; } + // 19 digits could overflow int64_t and is kind of absurd anyway. We don't + // support exponents smaller than -999,999,999,999,999,999 and bigger + // than 999,999,999,999,999,999. + // We can truncate. + // Note that 999999999999999999 is assuredly too large. The maximal ieee64 value before + // infinity is ~1.8e308. The smallest subnormal is ~5e-324. So, actually, we could + // truncate at 324. + // Note that there is no reason to fail per se at this point in time. + // E.g., 0e999999999999999999999 is a fine number. + if (p > start_exp+18) { exp_number = 999999999999999999; } + } + // At this point, we know that exp_number is a sane, positive, signed integer. + // It is <= 999,999,999,999,999,999. As long as 'exponent' is in + // [-8223372036854775808, 8223372036854775808], we won't overflow. Because 'exponent' + // is bounded in magnitude by the size of the JSON input, we are fine in this universe. + // To sum it up: the next line should never overflow. + exponent += (neg_exp ? -exp_number : exp_number); + return SUCCESS; +} + +simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t digit_count) { + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + const uint8_t *start = start_digits; + while ((*start == '0') || (*start == '.')) { ++start; } + // we over-decrement by one when there is a '.' + return digit_count - size_t(start - start_digits); +} + +} // unnamed namespace + +/** @private */ +static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) { + if (parse_float_fallback(src, answer)) { + return SUCCESS; + } + return INVALID_NUMBER(src); +} + +/** @private */ +template +simdjson_inline error_code write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer) { + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon in practice. + // + // 9999999999999999999 < 2**64 so we can accommodate 19 digits. + // If we have a decimal separator, then digit_count - 1 is the number of digits, but we + // may not have a decimal separator! + if (simdjson_unlikely(digit_count > 19 && significant_digits(start_digits, digit_count) > 19)) { + // Ok, chances are good that we had an overflow! + // this is almost never going to get called!!! + // we start anew, going slowly!!! + // This will happen in the following examples: + // 10000000000000000000000000000000000000000000e+308 + // 3.1415926535897932384626433832795028841971693993751 + // + // NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer + // reference to it, it would force it to be stored in memory, preventing the compiler from + // picking it apart and putting into registers. i.e. if we pass it as reference, + // it gets slow. + double d; + error_code error = slow_float_parsing(src, &d); + writer.append_double(d); + return error; + } + // NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other + // way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331 + // To future reader: we'd love if someone found a better way, or at least could explain this result! + if (simdjson_unlikely(exponent < simdjson::internal::smallest_power) || (exponent > simdjson::internal::largest_power)) { + // + // Important: smallest_power is such that it leads to a zero value. + // Observe that 18446744073709551615e-343 == 0, i.e. (2**64 - 1) e -343 is zero + // so something x 10^-343 goes to zero, but not so with something x 10^-342. + static_assert(simdjson::internal::smallest_power <= -342, "smallest_power is not small enough"); + // + if((exponent < simdjson::internal::smallest_power) || (i == 0)) { + // E.g. Parse "-0.0e-999" into the same value as "-0.0". See https://en.wikipedia.org/wiki/Signed_zero + WRITE_DOUBLE(negative ? -0.0 : 0.0, src, writer); + return SUCCESS; + } else { // (exponent > largest_power) and (i != 0) + // We have, for sure, an infinite value and simdjson refuses to parse infinite values. + return INVALID_NUMBER(src); + } + } + double d; + if (!compute_float_64(exponent, i, negative, d)) { + // we are almost never going to get here. + if (!parse_float_fallback(src, &d)) { return INVALID_NUMBER(src); } + } + WRITE_DOUBLE(d, src, writer); + return SUCCESS; +} + +// for performance analysis, it is sometimes useful to skip parsing +#ifdef SIMDJSON_SKIPNUMBERPARSING + +template +simdjson_inline error_code parse_number(const uint8_t *const, W &writer) { + writer.append_s64(0); // always write zero + return SUCCESS; // always succeeds +} + +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { return number_type::signed_integer; } +#else + +// parse the number at src +// define JSON_TEST_NUMBERS for unit testing +// +// It is assumed that the number is followed by a structural ({,},],[) character +// or a white space character. If that is not the case (e.g., when the JSON +// document is made of a single number), then it is necessary to copy the +// content and append a space before calling this function. +// +// Our objective is accurate parsing (ULP of 0) at high speed. +template +simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) { + + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + if (digit_count == 0 || ('0' == *start_digits && digit_count > 1)) { return INVALID_NUMBER(src); } + + // + // Handle floats if there is a . or e (or both) + // + int64_t exponent = 0; + bool is_float = false; + if ('.' == *p) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) ); + digit_count = int(p - start_digits); // used later to guard against overflows + } + if (('e' == *p) || ('E' == *p)) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_exponent(src, p, exponent) ); + } + if (is_float) { + const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p); + SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) ); + if (dirty_end) { return INVALID_NUMBER(src); } + return SUCCESS; + } + + // The longest negative 64-bit number is 19 digits. + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + size_t longest_digit_count = negative ? 19 : 20; + if (digit_count > longest_digit_count) { return INVALID_NUMBER(src); } + if (digit_count == longest_digit_count) { + if (negative) { + // Anything negative above INT64_MAX+1 is invalid + if (i > uint64_t(INT64_MAX)+1) { return INVALID_NUMBER(src); } + WRITE_INTEGER(~i+1, src, writer); + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + } else if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INVALID_NUMBER(src); } + } + + // Write unsigned if it doesn't fit in a signed integer. + if (i > uint64_t(INT64_MAX)) { + WRITE_UNSIGNED(i, src, writer); + } else { + WRITE_INTEGER(negative ? (~i+1) : i, src, writer); + } + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; +} + +// Inlineable functions +namespace { + +// This table can be used to characterize the final character of an integer +// string. For JSON structural character and allowable white space characters, +// we return SUCCESS. For 'e', '.' and 'E', we return INCORRECT_TYPE. Otherwise +// we return NUMBER_ERROR. +// Optimization note: we could easily reduce the size of the table by half (to 128) +// at the cost of an extra branch. +// Optimization note: we want the values to use at most 8 bits (not, e.g., 32 bits): +static_assert(error_code(uint8_t(NUMBER_ERROR))== NUMBER_ERROR, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(SUCCESS))== SUCCESS, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(INCORRECT_TYPE))== INCORRECT_TYPE, "bad NUMBER_ERROR cast"); + +const uint8_t integer_string_finisher[256] = { + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, INCORRECT_TYPE, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, SUCCESS, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR}; + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + + +// Parse any number from 0 to 18,446,744,073,709,551,615 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src, const uint8_t * const src_end) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if ((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { + const uint8_t *p = src + 1; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (*p != '"') { return NUMBER_ERROR; } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + // Note: we use src[1] and not src[0] because src[0] is the quote character in this + // instance. + if (src[1] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src, const uint8_t * const src_end) noexcept { + // + // Check for minus sign + // + if(src == src_end) { return NUMBER_ERROR; } + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = src; + uint64_t i = 0; + while (parse_digit(*src, i)) { src++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(src - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*src)) { + // return (*src == '.' || *src == 'e' || *src == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(*src != '"') { return NUMBER_ERROR; } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { + return (*src == '-'); +} + +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { return true; } + return false; +} + +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { + // We have an integer. + // If the number is negative and valid, it must be a signed integer. + if(negative) { return number_type::signed_integer; } + // We want values larger or equal to 9223372036854775808 to be unsigned + // integers, and the other values to be signed integers. + int digit_count = int(p - src); + if(digit_count >= 19) { + const uint8_t * smaller_big_integer = reinterpret_cast("9223372036854775808"); + if((digit_count >= 20) || (memcmp(src, smaller_big_integer, 19) >= 0)) { + return number_type::unsigned_integer; + } + } + return number_type::signed_integer; + } + // Hopefully, we have 'e' or 'E' or '.'. + return number_type::floating_point_number; +} + +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src, const uint8_t * const src_end) noexcept { + if(src == src_end) { return NUMBER_ERROR; } + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + if(p == src_end) { return NUMBER_ERROR; } + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while ((p != src_end) && parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely((p != src_end) && (*p == '.'))) { + p++; + const uint8_t *start_decimal_digits = p; + if ((p == src_end) || !parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = start_digits-src > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if ((p != src_end) && (*p == 'e' || *p == 'E')) { + p++; + if(p == src_end) { return NUMBER_ERROR; } + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while ((p != src_end) && parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (*p != '"') { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +} // unnamed namespace +#endif // SIMDJSON_SKIPNUMBERPARSING + +} // namespace numberparsing + +inline std::ostream& operator<<(std::ostream& out, number_type type) noexcept { + switch (type) { + case number_type::signed_integer: out << "integer in [-9223372036854775808,9223372036854775808)"; break; + case number_type::unsigned_integer: out << "unsigned integer in [9223372036854775808,18446744073709551616)"; break; + case number_type::floating_point_number: out << "floating-point number (binary64)"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_NUMBERPARSING_H +/* end file simdjson/generic/numberparsing.h for icelake */ + +/* including simdjson/generic/implementation_simdjson_result_base-inl.h for icelake: #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { + +// +// internal::implementation_simdjson_result_base inline implementation +// + +template +simdjson_inline void implementation_simdjson_result_base::tie(T &value, error_code &error) && noexcept { + error = this->second; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +simdjson_warn_unused simdjson_inline error_code implementation_simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; +} + +template +simdjson_inline error_code implementation_simdjson_result_base::error() const noexcept { + return this->second; +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& implementation_simdjson_result_base::value() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline T&& implementation_simdjson_result_base::take_value() && noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& implementation_simdjson_result_base::value_unsafe() const& noexcept { + return this->first; +} + +template +simdjson_inline T& implementation_simdjson_result_base::value_unsafe() & noexcept { + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value_unsafe() && noexcept { + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value, error_code error) noexcept + : first{std::forward(value)}, second{error} {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(error_code error) noexcept + : implementation_simdjson_result_base(T{}, error) {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value) noexcept + : implementation_simdjson_result_base(std::forward(value), SUCCESS) {} + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H +/* end file simdjson/generic/implementation_simdjson_result_base-inl.h for icelake */ +/* end file simdjson/generic/amalgamated.h for icelake */ +/* including simdjson/icelake/end.h: #include "simdjson/icelake/end.h" */ +/* begin file simdjson/icelake/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_ICELAKE +SIMDJSON_UNTARGET_REGION +#endif + +/* undefining SIMDJSON_IMPLEMENTATION from "icelake" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/icelake/end.h */ + +#endif // SIMDJSON_ICELAKE_H +/* end file simdjson/icelake.h */ +/* including simdjson/icelake/implementation.h: #include */ +/* begin file simdjson/icelake/implementation.h */ +#ifndef SIMDJSON_ICELAKE_IMPLEMENTATION_H +#define SIMDJSON_ICELAKE_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_ICELAKE +namespace simdjson { +namespace icelake { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation( + "icelake", + "Intel/AMD AVX512", + internal::instruction_set::AVX2 | internal::instruction_set::PCLMULQDQ | internal::instruction_set::BMI1 | internal::instruction_set::BMI2 | internal::instruction_set::AVX512F | internal::instruction_set::AVX512DQ | internal::instruction_set::AVX512CD | internal::instruction_set::AVX512BW | internal::instruction_set::AVX512VL | internal::instruction_set::AVX512VBMI2 + ) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_IMPLEMENTATION_H +/* end file simdjson/icelake/implementation.h */ + +// defining SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER allows us to provide our own bit_indexer::write +#define SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + +/* including simdjson/icelake/begin.h: #include */ +/* begin file simdjson/icelake/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "icelake" */ +#define SIMDJSON_IMPLEMENTATION icelake +/* including simdjson/icelake/base.h: #include "simdjson/icelake/base.h" */ +/* begin file simdjson/icelake/base.h */ +#ifndef SIMDJSON_ICELAKE_BASE_H +#define SIMDJSON_ICELAKE_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_ICELAKE +namespace simdjson { +/** + * Implementation for Icelake (Intel AVX512). + */ +namespace icelake { + +class implementation; + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_BASE_H +/* end file simdjson/icelake/base.h */ +/* including simdjson/icelake/intrinsics.h: #include "simdjson/icelake/intrinsics.h" */ +/* begin file simdjson/icelake/intrinsics.h */ +#ifndef SIMDJSON_ICELAKE_INTRINSICS_H +#define SIMDJSON_ICELAKE_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + * e.g., if __AVX2__ is set... in turn, we normally set these + * macros by compiling against the corresponding architecture + * (e.g., arch:AVX2, -mavx2, etc.) which compiles the whole + * software with these advanced instructions. In simdjson, we + * want to compile the whole program for a generic target, + * and only target our specific kernels. As a workaround, + * we directly include the needed headers. These headers would + * normally guard against such usage, but we carefully included + * (or ) before, so the headers + * are fooled. + */ +#include // for _blsr_u64 +#include // for __lzcnt64 +#include // for most things (AVX2, AVX512, _popcnt64) +#include +#include +#include +#include +#include // for _mm_clmulepi64_si128 +// Important: we need the AVX-512 headers: +#include +#include +#include +#include +#include +#include +#include +// unfortunately, we may not get _blsr_u64, but, thankfully, clang +// has it as a macro. +#ifndef _blsr_u64 +// we roll our own +#define _blsr_u64(n) ((n - 1) & n) +#endif // _blsr_u64 +#endif // SIMDJSON_CLANG_VISUAL_STUDIO + +static_assert(sizeof(__m512i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for icelake"); + +#endif // SIMDJSON_ICELAKE_INTRINSICS_H +/* end file simdjson/icelake/intrinsics.h */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_ICELAKE +SIMDJSON_TARGET_REGION("avx512f,avx512dq,avx512cd,avx512bw,avx512vbmi,avx512vbmi2,avx512vl,avx2,bmi,pclmul,lzcnt,popcnt") +#endif + +/* including simdjson/icelake/bitmanipulation.h: #include "simdjson/icelake/bitmanipulation.h" */ +/* begin file simdjson/icelake/bitmanipulation.h */ +#ifndef SIMDJSON_ICELAKE_BITMANIPULATION_H +#define SIMDJSON_ICELAKE_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return (int)_tzcnt_u64(input_num); +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + //////// + // You might expect the next line to be equivalent to + // return (int)_tzcnt_u64(input_num); + // but the generated code differs and might be less efficient? + //////// + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return _blsr_u64(input_num); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { + return int(_lzcnt_u64(input_num)); +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_BITMANIPULATION_H +/* end file simdjson/icelake/bitmanipulation.h */ +/* including simdjson/icelake/bitmask.h: #include "simdjson/icelake/bitmask.h" */ +/* begin file simdjson/icelake/bitmask.h */ +#ifndef SIMDJSON_ICELAKE_BITMASK_H +#define SIMDJSON_ICELAKE_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(const uint64_t bitmask) { + // There should be no such thing with a processor supporting avx2 + // but not clmul. + __m128i all_ones = _mm_set1_epi8('\xFF'); + __m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0ULL, bitmask), all_ones, 0); + return _mm_cvtsi128_si64(result); +} + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_BITMASK_H +/* end file simdjson/icelake/bitmask.h */ +/* including simdjson/icelake/simd.h: #include "simdjson/icelake/simd.h" */ +/* begin file simdjson/icelake/simd.h */ +#ifndef SIMDJSON_ICELAKE_SIMD_H +#define SIMDJSON_ICELAKE_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if defined(__GNUC__) && !defined(__clang__) +#if __GNUC__ == 8 +#define SIMDJSON_GCC8 1 +#endif // __GNUC__ == 8 +#endif // defined(__GNUC__) && !defined(__clang__) + +#if SIMDJSON_GCC8 +/** + * GCC 8 fails to provide _mm512_set_epi8. We roll our own. + */ +inline __m512i _mm512_set_epi8(uint8_t a0, uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4, uint8_t a5, uint8_t a6, uint8_t a7, uint8_t a8, uint8_t a9, uint8_t a10, uint8_t a11, uint8_t a12, uint8_t a13, uint8_t a14, uint8_t a15, uint8_t a16, uint8_t a17, uint8_t a18, uint8_t a19, uint8_t a20, uint8_t a21, uint8_t a22, uint8_t a23, uint8_t a24, uint8_t a25, uint8_t a26, uint8_t a27, uint8_t a28, uint8_t a29, uint8_t a30, uint8_t a31, uint8_t a32, uint8_t a33, uint8_t a34, uint8_t a35, uint8_t a36, uint8_t a37, uint8_t a38, uint8_t a39, uint8_t a40, uint8_t a41, uint8_t a42, uint8_t a43, uint8_t a44, uint8_t a45, uint8_t a46, uint8_t a47, uint8_t a48, uint8_t a49, uint8_t a50, uint8_t a51, uint8_t a52, uint8_t a53, uint8_t a54, uint8_t a55, uint8_t a56, uint8_t a57, uint8_t a58, uint8_t a59, uint8_t a60, uint8_t a61, uint8_t a62, uint8_t a63) { + return _mm512_set_epi64(uint64_t(a7) + (uint64_t(a6) << 8) + (uint64_t(a5) << 16) + (uint64_t(a4) << 24) + (uint64_t(a3) << 32) + (uint64_t(a2) << 40) + (uint64_t(a1) << 48) + (uint64_t(a0) << 56), + uint64_t(a15) + (uint64_t(a14) << 8) + (uint64_t(a13) << 16) + (uint64_t(a12) << 24) + (uint64_t(a11) << 32) + (uint64_t(a10) << 40) + (uint64_t(a9) << 48) + (uint64_t(a8) << 56), + uint64_t(a23) + (uint64_t(a22) << 8) + (uint64_t(a21) << 16) + (uint64_t(a20) << 24) + (uint64_t(a19) << 32) + (uint64_t(a18) << 40) + (uint64_t(a17) << 48) + (uint64_t(a16) << 56), + uint64_t(a31) + (uint64_t(a30) << 8) + (uint64_t(a29) << 16) + (uint64_t(a28) << 24) + (uint64_t(a27) << 32) + (uint64_t(a26) << 40) + (uint64_t(a25) << 48) + (uint64_t(a24) << 56), + uint64_t(a39) + (uint64_t(a38) << 8) + (uint64_t(a37) << 16) + (uint64_t(a36) << 24) + (uint64_t(a35) << 32) + (uint64_t(a34) << 40) + (uint64_t(a33) << 48) + (uint64_t(a32) << 56), + uint64_t(a47) + (uint64_t(a46) << 8) + (uint64_t(a45) << 16) + (uint64_t(a44) << 24) + (uint64_t(a43) << 32) + (uint64_t(a42) << 40) + (uint64_t(a41) << 48) + (uint64_t(a40) << 56), + uint64_t(a55) + (uint64_t(a54) << 8) + (uint64_t(a53) << 16) + (uint64_t(a52) << 24) + (uint64_t(a51) << 32) + (uint64_t(a50) << 40) + (uint64_t(a49) << 48) + (uint64_t(a48) << 56), + uint64_t(a63) + (uint64_t(a62) << 8) + (uint64_t(a61) << 16) + (uint64_t(a60) << 24) + (uint64_t(a59) << 32) + (uint64_t(a58) << 40) + (uint64_t(a57) << 48) + (uint64_t(a56) << 56)); +} +#endif // SIMDJSON_GCC8 + + + +namespace simdjson { +namespace icelake { +namespace { +namespace simd { + + // Forward-declared so they can be used by splat and friends. + template + struct base { + __m512i value; + + // Zero constructor + simdjson_inline base() : value{__m512i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m512i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m512i&() const { return this->value; } + simdjson_inline operator __m512i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm512_or_si512(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm512_and_si512(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm512_xor_si512(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm512_andnot_si512(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + // Forward-declared so they can be used by splat and friends. + template + struct simd8; + + template> + struct base8: base> { + typedef uint32_t bitmask_t; + typedef uint64_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m512i _value) : base>(_value) {} + + friend simdjson_really_inline uint64_t operator==(const simd8 lhs, const simd8 rhs) { + return _mm512_cmpeq_epi8_mask(lhs, rhs); + } + + static const int SIZE = sizeof(base::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + // workaround for compilers unable to figure out that 16 - N is a constant (GCC 8) + constexpr int shift = 16 - N; + return _mm512_alignr_epi8(*this, _mm512_permutex2var_epi64(prev_chunk, _mm512_set_epi64(13, 12, 11, 10, 9, 8, 7, 6), *this), shift); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm512_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m512i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + simdjson_inline bool any() const { return !!_mm512_test_epi8_mask (*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm512_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm512_setzero_si512(); } + static simdjson_inline simd8 load(const T values[64]) { + return _mm512_loadu_si512(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m512i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[64]) const { return _mm512_storeu_si512(reinterpret_cast<__m512i *>(dst), *this); } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm512_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm512_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm512_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 32 - count_ones(mask) bytes of the result are significant but 32 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint64_t mask, L * output) const { + _mm512_mask_compressstoreu_epi8 (output,~mask,*this); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m512i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t values[64]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15, + int8_t v16, int8_t v17, int8_t v18, int8_t v19, int8_t v20, int8_t v21, int8_t v22, int8_t v23, + int8_t v24, int8_t v25, int8_t v26, int8_t v27, int8_t v28, int8_t v29, int8_t v30, int8_t v31, + int8_t v32, int8_t v33, int8_t v34, int8_t v35, int8_t v36, int8_t v37, int8_t v38, int8_t v39, + int8_t v40, int8_t v41, int8_t v42, int8_t v43, int8_t v44, int8_t v45, int8_t v46, int8_t v47, + int8_t v48, int8_t v49, int8_t v50, int8_t v51, int8_t v52, int8_t v53, int8_t v54, int8_t v55, + int8_t v56, int8_t v57, int8_t v58, int8_t v59, int8_t v60, int8_t v61, int8_t v62, int8_t v63 + ) : simd8(_mm512_set_epi8( + v63, v62, v61, v60, v59, v58, v57, v56, + v55, v54, v53, v52, v51, v50, v49, v48, + v47, v46, v45, v44, v43, v42, v41, v40, + v39, v38, v37, v36, v35, v34, v33, v32, + v31, v30, v29, v28, v27, v26, v25, v24, + v23, v22, v21, v20, v19, v18, v17, v16, + v15, v14, v13, v12, v11, v10, v9, v8, + v7, v6, v5, v4, v3, v2, v1, v0 + )) {} + + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm512_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm512_min_epi8(*this, other); } + + simdjson_inline simd8 operator>(const simd8 other) const { return _mm512_maskz_abs_epi8(_mm512_cmpgt_epi8_mask(*this, other),_mm512_set1_epi8(uint8_t(0x80))); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm512_maskz_abs_epi8(_mm512_cmpgt_epi8_mask(other, *this),_mm512_set1_epi8(uint8_t(0x80))); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m512i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t values[64]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15, + uint8_t v16, uint8_t v17, uint8_t v18, uint8_t v19, uint8_t v20, uint8_t v21, uint8_t v22, uint8_t v23, + uint8_t v24, uint8_t v25, uint8_t v26, uint8_t v27, uint8_t v28, uint8_t v29, uint8_t v30, uint8_t v31, + uint8_t v32, uint8_t v33, uint8_t v34, uint8_t v35, uint8_t v36, uint8_t v37, uint8_t v38, uint8_t v39, + uint8_t v40, uint8_t v41, uint8_t v42, uint8_t v43, uint8_t v44, uint8_t v45, uint8_t v46, uint8_t v47, + uint8_t v48, uint8_t v49, uint8_t v50, uint8_t v51, uint8_t v52, uint8_t v53, uint8_t v54, uint8_t v55, + uint8_t v56, uint8_t v57, uint8_t v58, uint8_t v59, uint8_t v60, uint8_t v61, uint8_t v62, uint8_t v63 + ) : simd8(_mm512_set_epi8( + v63, v62, v61, v60, v59, v58, v57, v56, + v55, v54, v53, v52, v51, v50, v49, v48, + v47, v46, v45, v44, v43, v42, v41, v40, + v39, v38, v37, v36, v35, v34, v33, v32, + v31, v30, v29, v28, v27, v26, v25, v24, + v23, v22, v21, v20, v19, v18, v17, v16, + v15, v14, v13, v12, v11, v10, v9, v8, + v7, v6, v5, v4, v3, v2, v1, v0 + )) {} + + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm512_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm512_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm512_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm512_min_epu8(other, *this); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline uint64_t operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline uint64_t operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->lt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return _mm512_mask_blend_epi8(*this == uint8_t(0), _mm512_set1_epi8(0), _mm512_set1_epi8(-1)); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + + simdjson_inline bool is_ascii() const { return _mm512_movepi8_mask(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { + return !_mm512_test_epi8_mask(*this, *this); + } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return !_mm512_test_epi8_mask(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm512_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm512_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline uint64_t get_bit() const { return _mm512_movepi8_mask(_mm512_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 1, "Icelake kernel should use one register per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1) : chunks{chunk0, chunk1} {} + simdjson_inline simd8x64(const simd8 chunk0) : chunks{chunk0} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr)} {} + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + this->chunks[0].compress(mask, output); + return 64 - count_ones(mask); + } + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + } + + simdjson_inline simd8 reduce_or() const { + return this->chunks[0]; + } + + simdjson_inline simd8x64 bit_or(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] | mask + ); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return this->chunks[0] == mask; + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return this->chunks[0] == other.chunks[0]; + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return this->chunks[0] <= mask; + } + }; // struct simd8x64 + +} // namespace simd + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_SIMD_H +/* end file simdjson/icelake/simd.h */ +/* including simdjson/icelake/stringparsing_defs.h: #include "simdjson/icelake/stringparsing_defs.h" */ +/* begin file simdjson/icelake/stringparsing_defs.h */ +#ifndef SIMDJSON_ICELAKE_STRINGPARSING_DEFS_H +#define SIMDJSON_ICELAKE_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/simd.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 64; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return ((quote_bits - 1) & bs_bits) != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint64_t bs_bits; + uint64_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 15 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v(src); + // store to dest unconditionally - we can overwrite the bits we don't like later + v.store(dst); + return { + static_cast(v == '\\'), // bs_bits + static_cast(v == '"'), // quote_bits + }; +} + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_STRINGPARSING_DEFS_H +/* end file simdjson/icelake/stringparsing_defs.h */ +/* including simdjson/icelake/numberparsing_defs.h: #include "simdjson/icelake/numberparsing_defs.h" */ +/* begin file simdjson/icelake/numberparsing_defs.h */ +#ifndef SIMDJSON_ICELAKE_NUMBERPARSING_DEFS_H +#define SIMDJSON_ICELAKE_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace numberparsing { + +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + // this actually computes *16* values so we are being wasteful. + const __m128i ascii0 = _mm_set1_epi8('0'); + const __m128i mul_1_10 = + _mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1); + const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1); + const __m128i mul_1_10000 = + _mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1); + const __m128i input = _mm_sub_epi8( + _mm_loadu_si128(reinterpret_cast(chars)), ascii0); + const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10); + const __m128i t2 = _mm_madd_epi16(t1, mul_1_100); + const __m128i t3 = _mm_packus_epi32(t2, t2); + const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000); + return _mm_cvtsi128_si32( + t4); // only captures the sum of the first 8 digits, drop the rest +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace icelake +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_ICELAKE_NUMBERPARSING_DEFS_H +/* end file simdjson/icelake/numberparsing_defs.h */ +/* end file simdjson/icelake/begin.h */ +/* including generic/amalgamated.h for icelake: #include */ +/* begin file generic/amalgamated.h for icelake */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_SRC_GENERIC_DEPENDENCIES_H) +#error generic/dependencies.h must be included before generic/amalgamated.h! +#endif + +/* including generic/base.h for icelake: #include */ +/* begin file generic/base.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { + +struct json_character_block; + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_BASE_H +/* end file generic/base.h for icelake */ +/* including generic/dom_parser_implementation.h for icelake: #include */ +/* begin file generic/dom_parser_implementation.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// Interface a dom parser implementation must fulfill +namespace simdjson { +namespace icelake { +namespace { + +simdjson_inline simd8 must_be_2_3_continuation(const simd8 prev2, const simd8 prev3); +simdjson_inline bool is_ascii(const simd8x64& input); + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file generic/dom_parser_implementation.h for icelake */ +/* including generic/json_character_block.h for icelake: #include */ +/* begin file generic/json_character_block.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { + +struct json_character_block { + static simdjson_inline json_character_block classify(const simd::simd8x64& in); + + simdjson_inline uint64_t whitespace() const noexcept { return _whitespace; } + simdjson_inline uint64_t op() const noexcept { return _op; } + simdjson_inline uint64_t scalar() const noexcept { return ~(op() | whitespace()); } + + uint64_t _whitespace; + uint64_t _op; +}; + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H +/* end file generic/json_character_block.h for icelake */ +/* end file generic/amalgamated.h for icelake */ +/* including generic/stage1/amalgamated.h for icelake: #include */ +/* begin file generic/stage1/amalgamated.h for icelake */ +// Stuff other things depend on +/* including generic/stage1/base.h for icelake: #include */ +/* begin file generic/stage1/base.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { +namespace stage1 { + +class bit_indexer; +template +struct buf_block_reader; +struct json_block; +class json_minifier; +class json_scanner; +struct json_string_block; +class json_string_scanner; +class json_structural_indexer; + +} // namespace stage1 + +namespace utf8_validation { +struct utf8_checker; +} // namespace utf8_validation + +using utf8_validation::utf8_checker; + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_BASE_H +/* end file generic/stage1/base.h for icelake */ +/* including generic/stage1/buf_block_reader.h for icelake: #include */ +/* begin file generic/stage1/buf_block_reader.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace icelake { +namespace { +namespace stage1 { + +// Walks through a buffer in block-sized increments, loading the last part with spaces +template +struct buf_block_reader { +public: + simdjson_inline buf_block_reader(const uint8_t *_buf, size_t _len); + simdjson_inline size_t block_index(); + simdjson_inline bool has_full_block() const; + simdjson_inline const uint8_t *full_block() const; + /** + * Get the last block, padded with spaces. + * + * There will always be a last block, with at least 1 byte, unless len == 0 (in which case this + * function fills the buffer with spaces and returns 0. In particular, if len == STEP_SIZE there + * will be 0 full_blocks and 1 remainder block with STEP_SIZE bytes and no spaces for padding. + * + * @return the number of effective characters in the last block. + */ + simdjson_inline size_t get_remainder(uint8_t *dst) const; + simdjson_inline void advance(); +private: + const uint8_t *buf; + const size_t len; + const size_t lenminusstep; + size_t idx; +}; + +// Routines to print masks and text for debugging bitmask operations +simdjson_unused static char * format_input_text_64(const uint8_t *text) { + static char buf[sizeof(simd8x64) + 1]; + for (size_t i=0; i); i++) { + buf[i] = int8_t(text[i]) < ' ' ? '_' : int8_t(text[i]); + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +// Routines to print masks and text for debugging bitmask operations +simdjson_unused static char * format_input_text(const simd8x64& in) { + static char buf[sizeof(simd8x64) + 1]; + in.store(reinterpret_cast(buf)); + for (size_t i=0; i); i++) { + if (buf[i] < ' ') { buf[i] = '_'; } + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +simdjson_unused static char * format_input_text(const simd8x64& in, uint64_t mask) { + static char buf[sizeof(simd8x64) + 1]; + in.store(reinterpret_cast(buf)); + for (size_t i=0; i); i++) { + if (buf[i] <= ' ') { buf[i] = '_'; } + if (!(mask & (size_t(1) << i))) { buf[i] = ' '; } + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +simdjson_unused static char * format_mask(uint64_t mask) { + static char buf[sizeof(simd8x64) + 1]; + for (size_t i=0; i<64; i++) { + buf[i] = (mask & (size_t(1) << i)) ? 'X' : ' '; + } + buf[64] = '\0'; + return buf; +} + +template +simdjson_inline buf_block_reader::buf_block_reader(const uint8_t *_buf, size_t _len) : buf{_buf}, len{_len}, lenminusstep{len < STEP_SIZE ? 0 : len - STEP_SIZE}, idx{0} {} + +template +simdjson_inline size_t buf_block_reader::block_index() { return idx; } + +template +simdjson_inline bool buf_block_reader::has_full_block() const { + return idx < lenminusstep; +} + +template +simdjson_inline const uint8_t *buf_block_reader::full_block() const { + return &buf[idx]; +} + +template +simdjson_inline size_t buf_block_reader::get_remainder(uint8_t *dst) const { + if(len == idx) { return 0; } // memcpy(dst, null, 0) will trigger an error with some sanitizers + std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it's more efficient to write out 8 or 16 bytes at once. + std::memcpy(dst, buf + idx, len - idx); + return len - idx; +} + +template +simdjson_inline void buf_block_reader::advance() { + idx += STEP_SIZE; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H +/* end file generic/stage1/buf_block_reader.h for icelake */ +/* including generic/stage1/json_escape_scanner.h for icelake: #include */ +/* begin file generic/stage1/json_escape_scanner.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_ESCAPE_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_ESCAPE_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { +namespace stage1 { + +/** + * Scans for escape characters in JSON, taking care with multiple backslashes (\\n vs. \n). + */ +struct json_escape_scanner { + /** The actual escape characters (the backslashes themselves). */ + uint64_t next_is_escaped = 0ULL; + + struct escaped_and_escape { + /** + * Mask of escaped characters. + * + * ``` + * \n \\n \\\n \\\\n \ + * 0100100010100101000 + * n \ \ n \ \ + * ``` + */ + uint64_t escaped; + /** + * Mask of escape characters. + * + * ``` + * \n \\n \\\n \\\\n \ + * 1001000101001010001 + * \ \ \ \ \ \ \ + * ``` + */ + uint64_t escape; + }; + + /** + * Get a mask of both escape and escaped characters (the characters following a backslash). + * + * @param potential_escape A mask of the character that can escape others (but could be + * escaped itself). e.g. block.eq('\\') + */ + simdjson_really_inline escaped_and_escape next(uint64_t backslash) noexcept { + +#if !SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT + if (!backslash) { return {next_escaped_without_backslashes(), 0}; } +#endif + + // | | Mask (shows characters instead of 1's) | Depth | Instructions | + // |--------------------------------|----------------------------------------|-------|---------------------| + // | string | `\\n_\\\n___\\\n___\\\\___\\\\__\\\` | | | + // | | ` even odd even odd odd` | | | + // | potential_escape | ` \ \\\ \\\ \\\\ \\\\ \\\` | 1 | 1 (backslash & ~first_is_escaped) + // | escape_and_terminal_code | ` \n \ \n \ \n \ \ \ \ \ \` | 5 | 5 (next_escape_and_terminal_code()) + // | escaped | `\ \ n \ n \ \ \ \ \ ` X | 6 | 7 (escape_and_terminal_code ^ (potential_escape | first_is_escaped)) + // | escape | ` \ \ \ \ \ \ \ \ \ \` | 6 | 8 (escape_and_terminal_code & backslash) + // | first_is_escaped | `\ ` | 7 (*) | 9 (escape >> 63) () + // (*) this is not needed until the next iteration + uint64_t escape_and_terminal_code = next_escape_and_terminal_code(backslash & ~this->next_is_escaped); + uint64_t escaped = escape_and_terminal_code ^ (backslash | this->next_is_escaped); + uint64_t escape = escape_and_terminal_code & backslash; + this->next_is_escaped = escape >> 63; + return {escaped, escape}; + } + +private: + static constexpr const uint64_t ODD_BITS = 0xAAAAAAAAAAAAAAAAULL; + + simdjson_really_inline uint64_t next_escaped_without_backslashes() noexcept { + uint64_t escaped = this->next_is_escaped; + this->next_is_escaped = 0; + return escaped; + } + + /** + * Returns a mask of the next escape characters (masking out escaped backslashes), along with + * any non-backslash escape codes. + * + * \n \\n \\\n \\\\n returns: + * \n \ \ \n \ \ + * 11 100 1011 10100 + * + * You are expected to mask out the first bit yourself if the previous block had a trailing + * escape. + * + * & the result with potential_escape to get just the escape characters. + * ^ the result with (potential_escape | first_is_escaped) to get escaped characters. + */ + static simdjson_really_inline uint64_t next_escape_and_terminal_code(uint64_t potential_escape) noexcept { + // If we were to just shift and mask out any odd bits, we'd actually get a *half* right answer: + // any even-aligned backslash runs would be correct! Odd-aligned backslash runs would be + // inverted (\\\ would be 010 instead of 101). + // + // ``` + // string: | ____\\\\_\\\\_____ | + // maybe_escaped | ODD | \ \ \ \ | + // even-aligned ^^^ ^^^^ odd-aligned + // ``` + // + // Taking that into account, our basic strategy is: + // + // 1. Use subtraction to produce a mask with 1's for even-aligned runs and 0's for + // odd-aligned runs. + // 2. XOR all odd bits, which masks out the odd bits in even-aligned runs, and brings IN the + // odd bits in odd-aligned runs. + // 3. & with backslash to clean up any stray bits. + // runs are set to 0, and then XORing with "odd": + // + // | | Mask (shows characters instead of 1's) | Instructions | + // |--------------------------------|----------------------------------------|---------------------| + // | string | `\\n_\\\n___\\\n___\\\\___\\\\__\\\` | + // | | ` even odd even odd odd` | + // | maybe_escaped | ` n \\n \\n \\\_ \\\_ \\` X | 1 (potential_escape << 1) + // | maybe_escaped_and_odd | ` \n_ \\n _ \\\n_ _ \\\__ _\\\_ \\\` | 1 (maybe_escaped | odd) + // | even_series_codes_and_odd | ` n_\\\ _ n_ _\\\\ _ _ ` | 1 (maybe_escaped_and_odd - potential_escape) + // | escape_and_terminal_code | ` \n \ \n \ \n \ \ \ \ \ \` | 1 (^ odd) + // + + // Escaped characters are characters following an escape. + uint64_t maybe_escaped = potential_escape << 1; + + // To distinguish odd from even escape sequences, therefore, we turn on any *starting* + // escapes that are on an odd byte. (We actually bring in all odd bits, for speed.) + // - Odd runs of backslashes are 0000, and the code at the end ("n" in \n or \\n) is 1. + // - Odd runs of backslashes are 1111, and the code at the end ("n" in \n or \\n) is 0. + // - All other odd bytes are 1, and even bytes are 0. + uint64_t maybe_escaped_and_odd_bits = maybe_escaped | ODD_BITS; + uint64_t even_series_codes_and_odd_bits = maybe_escaped_and_odd_bits - potential_escape; + + // Now we flip all odd bytes back with xor. This: + // - Makes odd runs of backslashes go from 0000 to 1010 + // - Makes even runs of backslashes go from 1111 to 1010 + // - Sets actually-escaped codes to 1 (the n in \n and \\n: \n = 11, \\n = 100) + // - Resets all other bytes to 0 + return even_series_codes_and_odd_bits ^ ODD_BITS; + } +}; + +} // namespace stage1 +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H +/* end file generic/stage1/json_escape_scanner.h for icelake */ +/* including generic/stage1/json_string_scanner.h for icelake: #include */ +/* begin file generic/stage1/json_string_scanner.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { +namespace stage1 { + +struct json_string_block { + // We spell out the constructors in the hope of resolving inlining issues with Visual Studio 2017 + simdjson_really_inline json_string_block(uint64_t escaped, uint64_t quote, uint64_t in_string) : + _escaped(escaped), _quote(quote), _in_string(in_string) {} + + // Escaped characters (characters following an escape() character) + simdjson_really_inline uint64_t escaped() const { return _escaped; } + // Real (non-backslashed) quotes + simdjson_really_inline uint64_t quote() const { return _quote; } + // Only characters inside the string (not including the quotes) + simdjson_really_inline uint64_t string_content() const { return _in_string & ~_quote; } + // Return a mask of whether the given characters are inside a string (only works on non-quotes) + simdjson_really_inline uint64_t non_quote_inside_string(uint64_t mask) const { return mask & _in_string; } + // Return a mask of whether the given characters are inside a string (only works on non-quotes) + simdjson_really_inline uint64_t non_quote_outside_string(uint64_t mask) const { return mask & ~_in_string; } + // Tail of string (everything except the start quote) + simdjson_really_inline uint64_t string_tail() const { return _in_string ^ _quote; } + + // escaped characters (backslashed--does not include the hex characters after \u) + uint64_t _escaped; + // real quotes (non-escaped ones) + uint64_t _quote; + // string characters (includes start quote but not end quote) + uint64_t _in_string; +}; + +// Scans blocks for string characters, storing the state necessary to do so +class json_string_scanner { +public: + simdjson_really_inline json_string_block next(const simd::simd8x64& in); + // Returns either UNCLOSED_STRING or SUCCESS + simdjson_really_inline error_code finish(); + +private: + // Scans for escape characters + json_escape_scanner escape_scanner{}; + // Whether the last iteration was still inside a string (all 1's = true, all 0's = false). + uint64_t prev_in_string = 0ULL; +}; + +// +// Return a mask of all string characters plus end quotes. +// +// prev_escaped is overflow saying whether the next character is escaped. +// prev_in_string is overflow saying whether we're still in a string. +// +// Backslash sequences outside of quotes will be detected in stage 2. +// +simdjson_really_inline json_string_block json_string_scanner::next(const simd::simd8x64& in) { + const uint64_t backslash = in.eq('\\'); + const uint64_t escaped = escape_scanner.next(backslash).escaped; + const uint64_t quote = in.eq('"') & ~escaped; + + // + // prefix_xor flips on bits inside the string (and flips off the end quote). + // + // Then we xor with prev_in_string: if we were in a string already, its effect is flipped + // (characters inside strings are outside, and characters outside strings are inside). + // + const uint64_t in_string = prefix_xor(quote) ^ prev_in_string; + + // + // Check if we're still in a string at the end of the box so the next block will know + // + prev_in_string = uint64_t(static_cast(in_string) >> 63); + + // Use ^ to turn the beginning quote off, and the end quote on. + + // We are returning a function-local object so either we get a move constructor + // or we get copy elision. + return json_string_block(escaped, quote, in_string); +} + +simdjson_really_inline error_code json_string_scanner::finish() { + if (prev_in_string) { + return UNCLOSED_STRING; + } + return SUCCESS; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H +/* end file generic/stage1/json_string_scanner.h for icelake */ +/* including generic/stage1/utf8_lookup4_algorithm.h for icelake: #include */ +/* begin file generic/stage1/utf8_lookup4_algorithm.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { +namespace utf8_validation { + +using namespace simd; + + simdjson_inline simd8 check_special_cases(const simd8 input, const simd8 prev1) { +// Bit 0 = Too Short (lead byte/ASCII followed by lead byte/ASCII) +// Bit 1 = Too Long (ASCII followed by continuation) +// Bit 2 = Overlong 3-byte +// Bit 4 = Surrogate +// Bit 5 = Overlong 2-byte +// Bit 7 = Two Continuations + constexpr const uint8_t TOO_SHORT = 1<<0; // 11______ 0_______ + // 11______ 11______ + constexpr const uint8_t TOO_LONG = 1<<1; // 0_______ 10______ + constexpr const uint8_t OVERLONG_3 = 1<<2; // 11100000 100_____ + constexpr const uint8_t SURROGATE = 1<<4; // 11101101 101_____ + constexpr const uint8_t OVERLONG_2 = 1<<5; // 1100000_ 10______ + constexpr const uint8_t TWO_CONTS = 1<<7; // 10______ 10______ + constexpr const uint8_t TOO_LARGE = 1<<3; // 11110100 1001____ + // 11110100 101_____ + // 11110101 1001____ + // 11110101 101_____ + // 1111011_ 1001____ + // 1111011_ 101_____ + // 11111___ 1001____ + // 11111___ 101_____ + constexpr const uint8_t TOO_LARGE_1000 = 1<<6; + // 11110101 1000____ + // 1111011_ 1000____ + // 11111___ 1000____ + constexpr const uint8_t OVERLONG_4 = 1<<6; // 11110000 1000____ + + const simd8 byte_1_high = prev1.shr<4>().lookup_16( + // 0_______ ________ + TOO_LONG, TOO_LONG, TOO_LONG, TOO_LONG, + TOO_LONG, TOO_LONG, TOO_LONG, TOO_LONG, + // 10______ ________ + TWO_CONTS, TWO_CONTS, TWO_CONTS, TWO_CONTS, + // 1100____ ________ + TOO_SHORT | OVERLONG_2, + // 1101____ ________ + TOO_SHORT, + // 1110____ ________ + TOO_SHORT | OVERLONG_3 | SURROGATE, + // 1111____ ________ + TOO_SHORT | TOO_LARGE | TOO_LARGE_1000 | OVERLONG_4 + ); + constexpr const uint8_t CARRY = TOO_SHORT | TOO_LONG | TWO_CONTS; // These all have ____ in byte 1 . + const simd8 byte_1_low = (prev1 & 0x0F).lookup_16( + // ____0000 ________ + CARRY | OVERLONG_3 | OVERLONG_2 | OVERLONG_4, + // ____0001 ________ + CARRY | OVERLONG_2, + // ____001_ ________ + CARRY, + CARRY, + + // ____0100 ________ + CARRY | TOO_LARGE, + // ____0101 ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + // ____011_ ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + + // ____1___ ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + // ____1101 ________ + CARRY | TOO_LARGE | TOO_LARGE_1000 | SURROGATE, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000 + ); + const simd8 byte_2_high = input.shr<4>().lookup_16( + // ________ 0_______ + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT, + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT, + + // ________ 1000____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | OVERLONG_3 | TOO_LARGE_1000 | OVERLONG_4, + // ________ 1001____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | OVERLONG_3 | TOO_LARGE, + // ________ 101_____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | SURROGATE | TOO_LARGE, + TOO_LONG | OVERLONG_2 | TWO_CONTS | SURROGATE | TOO_LARGE, + + // ________ 11______ + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT + ); + return (byte_1_high & byte_1_low & byte_2_high); + } + simdjson_inline simd8 check_multibyte_lengths(const simd8 input, + const simd8 prev_input, const simd8 sc) { + simd8 prev2 = input.prev<2>(prev_input); + simd8 prev3 = input.prev<3>(prev_input); + simd8 must23 = simd8(must_be_2_3_continuation(prev2, prev3)); + simd8 must23_80 = must23 & uint8_t(0x80); + return must23_80 ^ sc; + } + + // + // Return nonzero if there are incomplete multibyte characters at the end of the block: + // e.g. if there is a 4-byte character, but it's 3 bytes from the end. + // + simdjson_inline simd8 is_incomplete(const simd8 input) { + // If the previous input's last 3 bytes match this, they're too short (they ended at EOF): + // ... 1111____ 111_____ 11______ +#if SIMDJSON_IMPLEMENTATION_ICELAKE + static const uint8_t max_array[64] = { + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 0xf0u-1, 0xe0u-1, 0xc0u-1 + }; +#else + static const uint8_t max_array[32] = { + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 0xf0u-1, 0xe0u-1, 0xc0u-1 + }; +#endif + const simd8 max_value(&max_array[sizeof(max_array)-sizeof(simd8)]); + return input.gt_bits(max_value); + } + + struct utf8_checker { + // If this is nonzero, there has been a UTF-8 error. + simd8 error; + // The last input we received + simd8 prev_input_block; + // Whether the last input we received was incomplete (used for ASCII fast path) + simd8 prev_incomplete; + + // + // Check whether the current bytes are valid UTF-8. + // + simdjson_inline void check_utf8_bytes(const simd8 input, const simd8 prev_input) { + // Flip prev1...prev3 so we can easily determine if they are 2+, 3+ or 4+ lead bytes + // (2, 3, 4-byte leads become large positive numbers instead of small negative numbers) + simd8 prev1 = input.prev<1>(prev_input); + simd8 sc = check_special_cases(input, prev1); + this->error |= check_multibyte_lengths(input, prev_input, sc); + } + + // The only problem that can happen at EOF is that a multibyte character is too short + // or a byte value too large in the last bytes: check_special_cases only checks for bytes + // too large in the first of two bytes. + simdjson_inline void check_eof() { + // If the previous block had incomplete UTF-8 characters at the end, an ASCII block can't + // possibly finish them. + this->error |= this->prev_incomplete; + } + + simdjson_inline void check_next_input(const simd8x64& input) { + if(simdjson_likely(is_ascii(input))) { + this->error |= this->prev_incomplete; + } else { + // you might think that a for-loop would work, but under Visual Studio, it is not good enough. + static_assert((simd8x64::NUM_CHUNKS == 1) + ||(simd8x64::NUM_CHUNKS == 2) + || (simd8x64::NUM_CHUNKS == 4), + "We support one, two or four chunks per 64-byte block."); + SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 1) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + } else SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 2) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + this->check_utf8_bytes(input.chunks[1], input.chunks[0]); + } else SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 4) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + this->check_utf8_bytes(input.chunks[1], input.chunks[0]); + this->check_utf8_bytes(input.chunks[2], input.chunks[1]); + this->check_utf8_bytes(input.chunks[3], input.chunks[2]); + } + this->prev_incomplete = is_incomplete(input.chunks[simd8x64::NUM_CHUNKS-1]); + this->prev_input_block = input.chunks[simd8x64::NUM_CHUNKS-1]; + } + } + // do not forget to call check_eof! + simdjson_inline error_code errors() { + return this->error.any_bits_set_anywhere() ? error_code::UTF8_ERROR : error_code::SUCCESS; + } + + }; // struct utf8_checker +} // namespace utf8_validation + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H +/* end file generic/stage1/utf8_lookup4_algorithm.h for icelake */ +/* including generic/stage1/json_scanner.h for icelake: #include */ +/* begin file generic/stage1/json_scanner.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { +namespace stage1 { + +/** + * A block of scanned json, with information on operators and scalars. + * + * We seek to identify pseudo-structural characters. Anything that is inside + * a string must be omitted (hence & ~_string.string_tail()). + * Otherwise, pseudo-structural characters come in two forms. + * 1. We have the structural characters ([,],{,},:, comma). The + * term 'structural character' is from the JSON RFC. + * 2. We have the 'scalar pseudo-structural characters'. + * Scalars are quotes, and any character except structural characters and white space. + * + * To identify the scalar pseudo-structural characters, we must look at what comes + * before them: it must be a space, a quote or a structural characters. + * Starting with simdjson v0.3, we identify them by + * negation: we identify everything that is followed by a non-quote scalar, + * and we negate that. Whatever remains must be a 'scalar pseudo-structural character'. + */ +struct json_block { +public: + // We spell out the constructors in the hope of resolving inlining issues with Visual Studio 2017 + simdjson_inline json_block(json_string_block&& string, json_character_block characters, uint64_t follows_potential_nonquote_scalar) : + _string(std::move(string)), _characters(characters), _follows_potential_nonquote_scalar(follows_potential_nonquote_scalar) {} + simdjson_inline json_block(json_string_block string, json_character_block characters, uint64_t follows_potential_nonquote_scalar) : + _string(string), _characters(characters), _follows_potential_nonquote_scalar(follows_potential_nonquote_scalar) {} + + /** + * The start of structurals. + * In simdjson prior to v0.3, these were called the pseudo-structural characters. + **/ + simdjson_inline uint64_t structural_start() const noexcept { return potential_structural_start() & ~_string.string_tail(); } + /** All JSON whitespace (i.e. not in a string) */ + simdjson_inline uint64_t whitespace() const noexcept { return non_quote_outside_string(_characters.whitespace()); } + + // Helpers + + /** Whether the given characters are inside a string (only works on non-quotes) */ + simdjson_inline uint64_t non_quote_inside_string(uint64_t mask) const noexcept { return _string.non_quote_inside_string(mask); } + /** Whether the given characters are outside a string (only works on non-quotes) */ + simdjson_inline uint64_t non_quote_outside_string(uint64_t mask) const noexcept { return _string.non_quote_outside_string(mask); } + + // string and escape characters + json_string_block _string; + // whitespace, structural characters ('operators'), scalars + json_character_block _characters; + // whether the previous character was a scalar + uint64_t _follows_potential_nonquote_scalar; +private: + // Potential structurals (i.e. disregarding strings) + + /** + * structural elements ([,],{,},:, comma) plus scalar starts like 123, true and "abc". + * They may reside inside a string. + **/ + simdjson_inline uint64_t potential_structural_start() const noexcept { return _characters.op() | potential_scalar_start(); } + /** + * The start of non-operator runs, like 123, true and "abc". + * It main reside inside a string. + **/ + simdjson_inline uint64_t potential_scalar_start() const noexcept { + // The term "scalar" refers to anything except structural characters and white space + // (so letters, numbers, quotes). + // Whenever it is preceded by something that is not a structural element ({,},[,],:, ") nor a white-space + // then we know that it is irrelevant structurally. + return _characters.scalar() & ~follows_potential_scalar(); + } + /** + * Whether the given character is immediately after a non-operator like 123, true. + * The characters following a quote are not included. + */ + simdjson_inline uint64_t follows_potential_scalar() const noexcept { + // _follows_potential_nonquote_scalar: is defined as marking any character that follows a character + // that is not a structural element ({,},[,],:, comma) nor a quote (") and that is not a + // white space. + // It is understood that within quoted region, anything at all could be marked (irrelevant). + return _follows_potential_nonquote_scalar; + } +}; + +/** + * Scans JSON for important bits: structural characters or 'operators', strings, and scalars. + * + * The scanner starts by calculating two distinct things: + * - string characters (taking \" into account) + * - structural characters or 'operators' ([]{},:, comma) + * and scalars (runs of non-operators like 123, true and "abc") + * + * To minimize data dependency (a key component of the scanner's speed), it finds these in parallel: + * in particular, the operator/scalar bit will find plenty of things that are actually part of + * strings. When we're done, json_block will fuse the two together by masking out tokens that are + * part of a string. + */ +class json_scanner { +public: + json_scanner() = default; + simdjson_inline json_block next(const simd::simd8x64& in); + // Returns either UNCLOSED_STRING or SUCCESS + simdjson_inline error_code finish(); + +private: + // Whether the last character of the previous iteration is part of a scalar token + // (anything except whitespace or a structural character/'operator'). + uint64_t prev_scalar = 0ULL; + json_string_scanner string_scanner{}; +}; + + +// +// Check if the current character immediately follows a matching character. +// +// For example, this checks for quotes with backslashes in front of them: +// +// const uint64_t backslashed_quote = in.eq('"') & immediately_follows(in.eq('\'), prev_backslash); +// +simdjson_inline uint64_t follows(const uint64_t match, uint64_t &overflow) { + const uint64_t result = match << 1 | overflow; + overflow = match >> 63; + return result; +} + +simdjson_inline json_block json_scanner::next(const simd::simd8x64& in) { + json_string_block strings = string_scanner.next(in); + // identifies the white-space and the structural characters + json_character_block characters = json_character_block::classify(in); + // The term "scalar" refers to anything except structural characters and white space + // (so letters, numbers, quotes). + // We want follows_scalar to mark anything that follows a non-quote scalar (so letters and numbers). + // + // A terminal quote should either be followed by a structural character (comma, brace, bracket, colon) + // or nothing. However, we still want ' "a string"true ' to mark the 't' of 'true' as a potential + // pseudo-structural character just like we would if we had ' "a string" true '; otherwise we + // may need to add an extra check when parsing strings. + // + // Performance: there are many ways to skin this cat. + const uint64_t nonquote_scalar = characters.scalar() & ~strings.quote(); + uint64_t follows_nonquote_scalar = follows(nonquote_scalar, prev_scalar); + // We are returning a function-local object so either we get a move constructor + // or we get copy elision. + return json_block( + strings,// strings is a function-local object so either it moves or the copy is elided. + characters, + follows_nonquote_scalar + ); +} + +simdjson_inline error_code json_scanner::finish() { + return string_scanner.finish(); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H +/* end file generic/stage1/json_scanner.h for icelake */ + +// All other declarations +/* including generic/stage1/find_next_document_index.h for icelake: #include */ +/* begin file generic/stage1/find_next_document_index.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { +namespace stage1 { + +/** + * This algorithm is used to quickly identify the last structural position that + * makes up a complete document. + * + * It does this by going backwards and finding the last *document boundary* (a + * place where one value follows another without a comma between them). If the + * last document (the characters after the boundary) has an equal number of + * start and end brackets, it is considered complete. + * + * Simply put, we iterate over the structural characters, starting from + * the end. We consider that we found the end of a JSON document when the + * first element of the pair is NOT one of these characters: '{' '[' ':' ',' + * and when the second element is NOT one of these characters: '}' ']' ':' ','. + * + * This simple comparison works most of the time, but it does not cover cases + * where the batch's structural indexes contain a perfect amount of documents. + * In such a case, we do not have access to the structural index which follows + * the last document, therefore, we do not have access to the second element in + * the pair, and that means we cannot identify the last document. To fix this + * issue, we keep a count of the open and closed curly/square braces we found + * while searching for the pair. When we find a pair AND the count of open and + * closed curly/square braces is the same, we know that we just passed a + * complete document, therefore the last json buffer location is the end of the + * batch. + */ +simdjson_inline uint32_t find_next_document_index(dom_parser_implementation &parser) { + // Variant: do not count separately, just figure out depth + if(parser.n_structural_indexes == 0) { return 0; } + auto arr_cnt = 0; + auto obj_cnt = 0; + for (auto i = parser.n_structural_indexes - 1; i > 0; i--) { + auto idxb = parser.structural_indexes[i]; + switch (parser.buf[idxb]) { + case ':': + case ',': + continue; + case '}': + obj_cnt--; + continue; + case ']': + arr_cnt--; + continue; + case '{': + obj_cnt++; + break; + case '[': + arr_cnt++; + break; + } + auto idxa = parser.structural_indexes[i - 1]; + switch (parser.buf[idxa]) { + case '{': + case '[': + case ':': + case ',': + continue; + } + // Last document is complete, so the next document will appear after! + if (!arr_cnt && !obj_cnt) { + return parser.n_structural_indexes; + } + // Last document is incomplete; mark the document at i + 1 as the next one + return i; + } + // If we made it to the end, we want to finish counting to see if we have a full document. + switch (parser.buf[parser.structural_indexes[0]]) { + case '}': + obj_cnt--; + break; + case ']': + arr_cnt--; + break; + case '{': + obj_cnt++; + break; + case '[': + arr_cnt++; + break; + } + if (!arr_cnt && !obj_cnt) { + // We have a complete document. + return parser.n_structural_indexes; + } + return 0; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H +/* end file generic/stage1/find_next_document_index.h for icelake */ +/* including generic/stage1/json_minifier.h for icelake: #include */ +/* begin file generic/stage1/json_minifier.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses in stage1 +// It is intended to be included multiple times and compiled multiple times +// We assume the file in which it is included already includes +// "simdjson/stage1.h" (this simplifies amalgation) + +namespace simdjson { +namespace icelake { +namespace { +namespace stage1 { + +class json_minifier { +public: + template + static error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept; + +private: + simdjson_inline json_minifier(uint8_t *_dst) + : dst{_dst} + {} + template + simdjson_inline void step(const uint8_t *block_buf, buf_block_reader &reader) noexcept; + simdjson_inline void next(const simd::simd8x64& in, const json_block& block); + simdjson_inline error_code finish(uint8_t *dst_start, size_t &dst_len); + json_scanner scanner{}; + uint8_t *dst; +}; + +simdjson_inline void json_minifier::next(const simd::simd8x64& in, const json_block& block) { + uint64_t mask = block.whitespace(); + dst += in.compress(mask, dst); +} + +simdjson_inline error_code json_minifier::finish(uint8_t *dst_start, size_t &dst_len) { + error_code error = scanner.finish(); + if (error) { dst_len = 0; return error; } + dst_len = dst - dst_start; + return SUCCESS; +} + +template<> +simdjson_inline void json_minifier::step<128>(const uint8_t *block_buf, buf_block_reader<128> &reader) noexcept { + simd::simd8x64 in_1(block_buf); + simd::simd8x64 in_2(block_buf+64); + json_block block_1 = scanner.next(in_1); + json_block block_2 = scanner.next(in_2); + this->next(in_1, block_1); + this->next(in_2, block_2); + reader.advance(); +} + +template<> +simdjson_inline void json_minifier::step<64>(const uint8_t *block_buf, buf_block_reader<64> &reader) noexcept { + simd::simd8x64 in_1(block_buf); + json_block block_1 = scanner.next(in_1); + this->next(block_buf, block_1); + reader.advance(); +} + +template +error_code json_minifier::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept { + buf_block_reader reader(buf, len); + json_minifier minifier(dst); + + // Index the first n-1 blocks + while (reader.has_full_block()) { + minifier.step(reader.full_block(), reader); + } + + // Index the last (remainder) block, padded with spaces + uint8_t block[STEP_SIZE]; + size_t remaining_bytes = reader.get_remainder(block); + if (remaining_bytes > 0) { + // We do not want to write directly to the output stream. Rather, we write + // to a local buffer (for safety). + uint8_t out_block[STEP_SIZE]; + uint8_t * const guarded_dst{minifier.dst}; + minifier.dst = out_block; + minifier.step(block, reader); + size_t to_write = minifier.dst - out_block; + // In some cases, we could be enticed to consider the padded spaces + // as part of the string. This is fine as long as we do not write more + // than we consumed. + if(to_write > remaining_bytes) { to_write = remaining_bytes; } + memcpy(guarded_dst, out_block, to_write); + minifier.dst = guarded_dst + to_write; + } + return minifier.finish(dst, dst_len); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H +/* end file generic/stage1/json_minifier.h for icelake */ +/* including generic/stage1/json_structural_indexer.h for icelake: #include */ +/* begin file generic/stage1/json_structural_indexer.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses in stage1 +// It is intended to be included multiple times and compiled multiple times +// We assume the file in which it is included already includes +// "simdjson/stage1.h" (this simplifies amalgation) + +namespace simdjson { +namespace icelake { +namespace { +namespace stage1 { + +class bit_indexer { +public: + uint32_t *tail; + + simdjson_inline bit_indexer(uint32_t *index_buf) : tail(index_buf) {} + +#if SIMDJSON_PREFER_REVERSE_BITS + /** + * ARM lacks a fast trailing zero instruction, but it has a fast + * bit reversal instruction and a fast leading zero instruction. + * Thus it may be profitable to reverse the bits (once) and then + * to rely on a sequence of instructions that call the leading + * zero instruction. + * + * Performance notes: + * The chosen routine is not optimal in terms of data dependency + * since zero_leading_bit might require two instructions. However, + * it tends to minimize the total number of instructions which is + * beneficial. + */ + simdjson_inline void write_index(uint32_t idx, uint64_t& rev_bits, int i) { + int lz = leading_zeroes(rev_bits); + this->tail[i] = static_cast(idx) + lz; + rev_bits = zero_leading_bit(rev_bits, lz); + } +#else + /** + * Under recent x64 systems, we often have both a fast trailing zero + * instruction and a fast 'clear-lower-bit' instruction so the following + * algorithm can be competitive. + */ + + simdjson_inline void write_index(uint32_t idx, uint64_t& bits, int i) { + this->tail[i] = idx + trailing_zeroes(bits); + bits = clear_lowest_bit(bits); + } +#endif // SIMDJSON_PREFER_REVERSE_BITS + + template + simdjson_inline int write_indexes(uint32_t idx, uint64_t& bits) { + write_index(idx, bits, START); + SIMDJSON_IF_CONSTEXPR (N > 1) { + write_indexes<(N-1>0?START+1:START), (N-1>=0?N-1:1)>(idx, bits); + } + return START+N; + } + + template + simdjson_inline int write_indexes_stepped(uint32_t idx, uint64_t& bits, int cnt) { + write_indexes(idx, bits); + SIMDJSON_IF_CONSTEXPR ((START+STEP) < END) { + if (simdjson_unlikely((START+STEP) < cnt)) { + write_indexes_stepped<(START+STEP(idx, bits, cnt); + } + } + return ((END-START) % STEP) == 0 ? END : (END-START) - ((END-START) % STEP) + STEP; + } + + // flatten out values in 'bits' assuming that they are are to have values of idx + // plus their position in the bitvector, and store these indexes at + // base_ptr[base] incrementing base as we go + // will potentially store extra values beyond end of valid bits, so base_ptr + // needs to be large enough to handle this + // + // If the kernel sets SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER, then it + // will provide its own version of the code. +#ifdef SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + simdjson_inline void write(uint32_t idx, uint64_t bits); +#else + simdjson_inline void write(uint32_t idx, uint64_t bits) { + // In some instances, the next branch is expensive because it is mispredicted. + // Unfortunately, in other cases, + // it helps tremendously. + if (bits == 0) + return; + + int cnt = static_cast(count_ones(bits)); + +#if SIMDJSON_PREFER_REVERSE_BITS + bits = reverse_bits(bits); +#endif +#ifdef SIMDJSON_STRUCTURAL_INDEXER_STEP + static constexpr const int STEP = SIMDJSON_STRUCTURAL_INDEXER_STEP; +#else + static constexpr const int STEP = 4; +#endif + static constexpr const int STEP_UNTIL = 24; + + write_indexes_stepped<0, STEP_UNTIL, STEP>(idx, bits, cnt); + SIMDJSON_IF_CONSTEXPR (STEP_UNTIL < 64) { + if (simdjson_unlikely(STEP_UNTIL < cnt)) { + for (int i=STEP_UNTIL; itail += cnt; + } +#endif // SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + +}; + +class json_structural_indexer { +public: + /** + * Find the important bits of JSON in a 128-byte chunk, and add them to structural_indexes. + * + * @param partial Setting the partial parameter to true allows the find_structural_bits to + * tolerate unclosed strings. 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 + static error_code index(const uint8_t *buf, size_t len, dom_parser_implementation &parser, stage1_mode partial) noexcept; + +private: + simdjson_inline json_structural_indexer(uint32_t *structural_indexes); + template + simdjson_inline void step(const uint8_t *block, buf_block_reader &reader) noexcept; + simdjson_inline void next(const simd::simd8x64& in, const json_block& block, size_t idx); + simdjson_inline error_code finish(dom_parser_implementation &parser, size_t idx, size_t len, stage1_mode partial); + + json_scanner scanner{}; + utf8_checker checker{}; + bit_indexer indexer; + uint64_t prev_structurals = 0; + uint64_t unescaped_chars_error = 0; +}; + +simdjson_inline json_structural_indexer::json_structural_indexer(uint32_t *structural_indexes) : indexer{structural_indexes} {} + +// Skip the last character if it is partial +simdjson_inline size_t trim_partial_utf8(const uint8_t *buf, size_t len) { + if (simdjson_unlikely(len < 3)) { + switch (len) { + case 2: + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + if (buf[len-2] >= 0xe0) { return len-2; } // 3- and 4-byte characters with only 2 bytes left + return len; + case 1: + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + return len; + case 0: + return len; + } + } + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + if (buf[len-2] >= 0xe0) { return len-2; } // 3- and 4-byte characters with only 1 byte left + if (buf[len-3] >= 0xf0) { return len-3; } // 4-byte characters with only 3 bytes left + return len; +} + +// +// PERF NOTES: +// We pipe 2 inputs through these stages: +// 1. Load JSON into registers. This takes a long time and is highly parallelizable, so we load +// 2 inputs' worth at once so that by the time step 2 is looking for them input, it's available. +// 2. Scan the JSON for critical data: strings, scalars and operators. This is the critical path. +// The output of step 1 depends entirely on this information. These functions don't quite use +// up enough CPU: the second half of the functions is highly serial, only using 1 execution core +// at a time. The second input's scans has some dependency on the first ones finishing it, but +// they can make a lot of progress before they need that information. +// 3. Step 1 doesn't use enough capacity, so we run some extra stuff while we're waiting for that +// to finish: utf-8 checks and generating the output from the last iteration. +// +// The reason we run 2 inputs at a time, is steps 2 and 3 are *still* not enough to soak up all +// available capacity with just one input. Running 2 at a time seems to give the CPU a good enough +// workout. +// +template +error_code json_structural_indexer::index(const uint8_t *buf, size_t len, dom_parser_implementation &parser, stage1_mode partial) noexcept { + if (simdjson_unlikely(len > parser.capacity())) { return CAPACITY; } + // We guard the rest of the code so that we can assume that len > 0 throughout. + if (len == 0) { return EMPTY; } + if (is_streaming(partial)) { + len = trim_partial_utf8(buf, len); + // If you end up with an empty window after trimming + // the partial UTF-8 bytes, then chances are good that you + // have an UTF-8 formatting error. + if(len == 0) { return UTF8_ERROR; } + } + buf_block_reader reader(buf, len); + json_structural_indexer indexer(parser.structural_indexes.get()); + + // Read all but the last block + while (reader.has_full_block()) { + indexer.step(reader.full_block(), reader); + } + // Take care of the last block (will always be there unless file is empty which is + // not supposed to happen.) + uint8_t block[STEP_SIZE]; + if (simdjson_unlikely(reader.get_remainder(block) == 0)) { return UNEXPECTED_ERROR; } + indexer.step(block, reader); + return indexer.finish(parser, reader.block_index(), len, partial); +} + +template<> +simdjson_inline void json_structural_indexer::step<128>(const uint8_t *block, buf_block_reader<128> &reader) noexcept { + simd::simd8x64 in_1(block); + simd::simd8x64 in_2(block+64); + json_block block_1 = scanner.next(in_1); + json_block block_2 = scanner.next(in_2); + this->next(in_1, block_1, reader.block_index()); + this->next(in_2, block_2, reader.block_index()+64); + reader.advance(); +} + +template<> +simdjson_inline void json_structural_indexer::step<64>(const uint8_t *block, buf_block_reader<64> &reader) noexcept { + simd::simd8x64 in_1(block); + json_block block_1 = scanner.next(in_1); + this->next(in_1, block_1, reader.block_index()); + reader.advance(); +} + +simdjson_inline void json_structural_indexer::next(const simd::simd8x64& in, const json_block& block, size_t idx) { + uint64_t unescaped = in.lteq(0x1F); +#if SIMDJSON_UTF8VALIDATION + checker.check_next_input(in); +#endif + indexer.write(uint32_t(idx-64), prev_structurals); // Output *last* iteration's structurals to the parser + prev_structurals = block.structural_start(); + unescaped_chars_error |= block.non_quote_inside_string(unescaped); +} + +simdjson_inline error_code json_structural_indexer::finish(dom_parser_implementation &parser, size_t idx, size_t len, stage1_mode partial) { + // Write out the final iteration's structurals + indexer.write(uint32_t(idx-64), prev_structurals); + error_code error = scanner.finish(); + // We deliberately break down the next expression so that it is + // human readable. + const bool should_we_exit = is_streaming(partial) ? + ((error != SUCCESS) && (error != UNCLOSED_STRING)) // when partial we tolerate UNCLOSED_STRING + : (error != SUCCESS); // if partial is false, we must have SUCCESS + const bool have_unclosed_string = (error == UNCLOSED_STRING); + if (simdjson_unlikely(should_we_exit)) { return error; } + + if (unescaped_chars_error) { + return UNESCAPED_CHARS; + } + parser.n_structural_indexes = uint32_t(indexer.tail - parser.structural_indexes.get()); + /*** + * The On Demand API requires special padding. + * + * This is related to https://github.com/simdjson/simdjson/issues/906 + * Basically, we want to make sure that if the parsing continues beyond the last (valid) + * structural character, it quickly stops. + * Only three structural characters can be repeated without triggering an error in JSON: [,] and }. + * We repeat the padding character (at 'len'). We don't know what it is, but if the parsing + * continues, then it must be [,] or }. + * Suppose it is ] or }. We backtrack to the first character, what could it be that would + * not trigger an error? It could be ] or } but no, because you can't start a document that way. + * It can't be a comma, a colon or any simple value. So the only way we could continue is + * if the repeated character is [. But if so, the document must start with [. But if the document + * starts with [, it should end with ]. If we enforce that rule, then we would get + * ][[ which is invalid. + * + * This is illustrated with the test array_iterate_unclosed_error() on the following input: + * R"({ "a": [,,)" + **/ + parser.structural_indexes[parser.n_structural_indexes] = uint32_t(len); // used later in partial == stage1_mode::streaming_final + parser.structural_indexes[parser.n_structural_indexes + 1] = uint32_t(len); + parser.structural_indexes[parser.n_structural_indexes + 2] = 0; + parser.next_structural_index = 0; + // a valid JSON file cannot have zero structural indexes - we should have found something + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { + return EMPTY; + } + if (simdjson_unlikely(parser.structural_indexes[parser.n_structural_indexes - 1] > len)) { + return UNEXPECTED_ERROR; + } + if (partial == stage1_mode::streaming_partial) { + // If we have an unclosed string, then the last structural + // will be the quote and we want to make sure to omit it. + if(have_unclosed_string) { + parser.n_structural_indexes--; + // a valid JSON file cannot have zero structural indexes - we should have found something + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { return CAPACITY; } + } + // We truncate the input to the end of the last complete document (or zero). + auto new_structural_indexes = find_next_document_index(parser); + if (new_structural_indexes == 0 && parser.n_structural_indexes > 0) { + if(parser.structural_indexes[0] == 0) { + // If the buffer is partial and we started at index 0 but the document is + // incomplete, it's too big to parse. + return CAPACITY; + } else { + // It is possible that the document could be parsed, we just had a lot + // of white space. + parser.n_structural_indexes = 0; + return EMPTY; + } + } + + parser.n_structural_indexes = new_structural_indexes; + } else if (partial == stage1_mode::streaming_final) { + if(have_unclosed_string) { parser.n_structural_indexes--; } + // We truncate the input to the end of the last complete document (or zero). + // Because partial == stage1_mode::streaming_final, it means that we may + // silently ignore trailing garbage. Though it sounds bad, we do it + // deliberately because many people who have streams of JSON documents + // will truncate them for processing. E.g., imagine that you are uncompressing + // the data from a size file or receiving it in chunks from the network. You + // may not know where exactly the last document will be. Meanwhile the + // document_stream instances allow people to know the JSON documents they are + // parsing (see the iterator.source() method). + parser.n_structural_indexes = find_next_document_index(parser); + // We store the initial n_structural_indexes so that the client can see + // whether we used truncation. If initial_n_structural_indexes == parser.n_structural_indexes, + // then this will query parser.structural_indexes[parser.n_structural_indexes] which is len, + // otherwise, it will copy some prior index. + parser.structural_indexes[parser.n_structural_indexes + 1] = parser.structural_indexes[parser.n_structural_indexes]; + // This next line is critical, do not change it unless you understand what you are + // doing. + parser.structural_indexes[parser.n_structural_indexes] = uint32_t(len); + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { + // We tolerate an unclosed string at the very end of the stream. Indeed, users + // often load their data in bulk without being careful and they want us to ignore + // the trailing garbage. + return EMPTY; + } + } + checker.check_eof(); + return checker.errors(); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +// Clear CUSTOM_BIT_INDEXER so other implementations can set it if they need to. +#undef SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H +/* end file generic/stage1/json_structural_indexer.h for icelake */ +/* including generic/stage1/utf8_validator.h for icelake: #include */ +/* begin file generic/stage1/utf8_validator.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { +namespace stage1 { + +/** + * Validates that the string is actual UTF-8. + */ +template +bool generic_validate_utf8(const uint8_t * input, size_t length) { + checker c{}; + buf_block_reader<64> reader(input, length); + while (reader.has_full_block()) { + simd::simd8x64 in(reader.full_block()); + c.check_next_input(in); + reader.advance(); + } + uint8_t block[64]{}; + reader.get_remainder(block); + simd::simd8x64 in(block); + c.check_next_input(in); + reader.advance(); + c.check_eof(); + return c.errors() == error_code::SUCCESS; +} + +bool generic_validate_utf8(const char * input, size_t length) { + return generic_validate_utf8(reinterpret_cast(input),length); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H +/* end file generic/stage1/utf8_validator.h for icelake */ +/* end file generic/stage1/amalgamated.h for icelake */ +/* including generic/stage2/amalgamated.h for icelake: #include */ +/* begin file generic/stage2/amalgamated.h for icelake */ +// Stuff other things depend on +/* including generic/stage2/base.h for icelake: #include */ +/* begin file generic/stage2/base.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { +namespace stage2 { + +class json_iterator; +class structural_iterator; +struct tape_builder; +struct tape_writer; + +} // namespace stage2 +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_BASE_H +/* end file generic/stage2/base.h for icelake */ +/* including generic/stage2/tape_writer.h for icelake: #include */ +/* begin file generic/stage2/tape_writer.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace icelake { +namespace { +namespace stage2 { + +struct tape_writer { + /** The next place to write to tape */ + uint64_t *next_tape_loc; + + /** Write a signed 64-bit value to tape. */ + simdjson_inline void append_s64(int64_t value) noexcept; + + /** Write an unsigned 64-bit value to tape. */ + simdjson_inline void append_u64(uint64_t value) noexcept; + + /** Write a double value to tape. */ + simdjson_inline void append_double(double value) noexcept; + + /** + * Append a tape entry (an 8-bit type,and 56 bits worth of value). + */ + simdjson_inline void append(uint64_t val, internal::tape_type t) noexcept; + + /** + * Skip the current tape entry without writing. + * + * Used to skip the start of the container, since we'll come back later to fill it in when the + * container ends. + */ + simdjson_inline void skip() noexcept; + + /** + * Skip the number of tape entries necessary to write a large u64 or i64. + */ + simdjson_inline void skip_large_integer() noexcept; + + /** + * Skip the number of tape entries necessary to write a double. + */ + simdjson_inline void skip_double() noexcept; + + /** + * Write a value to a known location on tape. + * + * Used to go back and write out the start of a container after the container ends. + */ + simdjson_inline static void write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept; + +private: + /** + * Append both the tape entry, and a supplementary value following it. Used for types that need + * all 64 bits, such as double and uint64_t. + */ + template + simdjson_inline void append2(uint64_t val, T val2, internal::tape_type t) noexcept; +}; // struct tape_writer + +simdjson_inline void tape_writer::append_s64(int64_t value) noexcept { + append2(0, value, internal::tape_type::INT64); +} + +simdjson_inline void tape_writer::append_u64(uint64_t value) noexcept { + append(0, internal::tape_type::UINT64); + *next_tape_loc = value; + next_tape_loc++; +} + +/** Write a double value to tape. */ +simdjson_inline void tape_writer::append_double(double value) noexcept { + append2(0, value, internal::tape_type::DOUBLE); +} + +simdjson_inline void tape_writer::skip() noexcept { + next_tape_loc++; +} + +simdjson_inline void tape_writer::skip_large_integer() noexcept { + next_tape_loc += 2; +} + +simdjson_inline void tape_writer::skip_double() noexcept { + next_tape_loc += 2; +} + +simdjson_inline void tape_writer::append(uint64_t val, internal::tape_type t) noexcept { + *next_tape_loc = val | ((uint64_t(char(t))) << 56); + next_tape_loc++; +} + +template +simdjson_inline void tape_writer::append2(uint64_t val, T val2, internal::tape_type t) noexcept { + append(val, t); + static_assert(sizeof(val2) == sizeof(*next_tape_loc), "Type is not 64 bits!"); + memcpy(next_tape_loc, &val2, sizeof(val2)); + next_tape_loc++; +} + +simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept { + tape_loc = val | ((uint64_t(char(t))) << 56); +} + +} // namespace stage2 +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H +/* end file generic/stage2/tape_writer.h for icelake */ +/* including generic/stage2/logger.h for icelake: #include */ +/* begin file generic/stage2/logger.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_LOGGER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_LOGGER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + + +// This is for an internal-only stage 2 specific logger. +// Set LOG_ENABLED = true to log what stage 2 is doing! +namespace simdjson { +namespace icelake { +namespace { +namespace logger { + + static constexpr const char * DASHES = "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"; + +#if SIMDJSON_VERBOSE_LOGGING + static constexpr const bool LOG_ENABLED = true; +#else + static constexpr const bool LOG_ENABLED = false; +#endif + static constexpr const int LOG_EVENT_LEN = 20; + static constexpr const int LOG_BUFFER_LEN = 30; + static constexpr const int LOG_SMALL_BUFFER_LEN = 10; + static constexpr const int LOG_INDEX_LEN = 5; + + static int log_depth; // Not threadsafe. Log only. + + // Helper to turn unprintable or newline characters into spaces + static simdjson_inline char printable_char(char c) { + if (c >= 0x20) { + return c; + } else { + return ' '; + } + } + + // Print the header and set up log_start + static simdjson_inline void log_start() { + if (LOG_ENABLED) { + log_depth = 0; + printf("\n"); + printf("| %-*s | %-*s | %-*s | %-*s | Detail |\n", LOG_EVENT_LEN, "Event", LOG_BUFFER_LEN, "Buffer", LOG_SMALL_BUFFER_LEN, "Next", 5, "Next#"); + printf("|%.*s|%.*s|%.*s|%.*s|--------|\n", LOG_EVENT_LEN+2, DASHES, LOG_BUFFER_LEN+2, DASHES, LOG_SMALL_BUFFER_LEN+2, DASHES, 5+2, DASHES); + } + } + + simdjson_unused static simdjson_inline void log_string(const char *message) { + if (LOG_ENABLED) { + printf("%s\n", message); + } + } + + // Logs a single line from the stage 2 DOM parser + template + static simdjson_inline void log_line(S &structurals, const char *title_prefix, const char *title, const char *detail) { + if (LOG_ENABLED) { + printf("| %*s%s%-*s ", log_depth*2, "", title_prefix, LOG_EVENT_LEN - log_depth*2 - int(strlen(title_prefix)), title); + auto current_index = structurals.at_beginning() ? nullptr : structurals.next_structural-1; + auto next_index = structurals.next_structural; + auto current = current_index ? &structurals.buf[*current_index] : reinterpret_cast(" "); + auto next = &structurals.buf[*next_index]; + { + // Print the next N characters in the buffer. + printf("| "); + // Otherwise, print the characters starting from the buffer position. + // Print spaces for unprintable or newline characters. + for (int i=0;i */ +/* begin file generic/stage2/json_iterator.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { +namespace stage2 { + +class json_iterator { +public: + const uint8_t* const buf; + uint32_t *next_structural; + dom_parser_implementation &dom_parser; + uint32_t depth{0}; + + /** + * Walk the JSON document. + * + * The visitor receives callbacks when values are encountered. All callbacks pass the iterator as + * the first parameter; some callbacks have other parameters as well: + * + * - visit_document_start() - at the beginning. + * - visit_document_end() - at the end (if things were successful). + * + * - visit_array_start() - at the start `[` of a non-empty array. + * - visit_array_end() - at the end `]` of a non-empty array. + * - visit_empty_array() - when an empty array is encountered. + * + * - visit_object_end() - at the start `]` of a non-empty object. + * - visit_object_start() - at the end `]` of a non-empty object. + * - visit_empty_object() - when an empty object is encountered. + * - visit_key(const uint8_t *key) - when a key in an object field is encountered. key is + * guaranteed to point at the first quote of the string (`"key"`). + * - visit_primitive(const uint8_t *value) - when a value is a string, number, boolean or null. + * - visit_root_primitive(iter, uint8_t *value) - when the top-level value is a string, number, boolean or null. + * + * - increment_count(iter) - each time a value is found in an array or object. + */ + template + simdjson_warn_unused simdjson_inline error_code walk_document(V &visitor) noexcept; + + /** + * Create an iterator capable of walking a JSON document. + * + * The document must have already passed through stage 1. + */ + simdjson_inline json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index); + + /** + * Look at the next token. + * + * Tokens can be strings, numbers, booleans, null, or operators (`[{]},:`)). + * + * They may include invalid JSON as well (such as `1.2.3` or `ture`). + */ + simdjson_inline const uint8_t *peek() const noexcept; + /** + * Advance to the next token. + * + * Tokens can be strings, numbers, booleans, null, or operators (`[{]},:`)). + * + * They may include invalid JSON as well (such as `1.2.3` or `ture`). + */ + simdjson_inline const uint8_t *advance() noexcept; + /** + * Get the remaining length of the document, from the start of the current token. + */ + simdjson_inline size_t remaining_len() const noexcept; + /** + * Check if we are at the end of the document. + * + * If this is true, there are no more tokens. + */ + simdjson_inline bool at_eof() const noexcept; + /** + * Check if we are at the beginning of the document. + */ + simdjson_inline bool at_beginning() const noexcept; + simdjson_inline uint8_t last_structural() const noexcept; + + /** + * Log that a value has been found. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_value(const char *type) const noexcept; + /** + * Log the start of a multipart value. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_start_value(const char *type) const noexcept; + /** + * Log the end of a multipart value. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_end_value(const char *type) const noexcept; + /** + * Log an error. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_error(const char *error) const noexcept; + + template + simdjson_warn_unused simdjson_inline error_code visit_root_primitive(V &visitor, const uint8_t *value) noexcept; + template + simdjson_warn_unused simdjson_inline error_code visit_primitive(V &visitor, const uint8_t *value) noexcept; +}; + +template +simdjson_warn_unused simdjson_inline error_code json_iterator::walk_document(V &visitor) noexcept { + logger::log_start(); + + // + // Start the document + // + if (at_eof()) { return EMPTY; } + log_start_value("document"); + SIMDJSON_TRY( visitor.visit_document_start(*this) ); + + // + // Read first value + // + { + auto value = advance(); + + // Make sure the outer object or array is closed before continuing; otherwise, there are ways we + // could get into memory corruption. See https://github.com/simdjson/simdjson/issues/906 + if (!STREAMING) { + switch (*value) { + case '{': if (last_structural() != '}') { log_value("starting brace unmatched"); return TAPE_ERROR; }; break; + case '[': if (last_structural() != ']') { log_value("starting bracket unmatched"); return TAPE_ERROR; }; break; + } + } + + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_root_primitive(*this, value) ); break; + } + } + goto document_end; + +// +// Object parser states +// +object_begin: + log_start_value("object"); + depth++; + if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; } + dom_parser.is_array[depth] = false; + SIMDJSON_TRY( visitor.visit_object_start(*this) ); + + { + auto key = advance(); + if (*key != '"') { log_error("Object does not start with a key"); return TAPE_ERROR; } + SIMDJSON_TRY( visitor.increment_count(*this) ); + SIMDJSON_TRY( visitor.visit_key(*this, key) ); + } + +object_field: + if (simdjson_unlikely( *advance() != ':' )) { log_error("Missing colon after key in object"); return TAPE_ERROR; } + { + auto value = advance(); + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break; + } + } + +object_continue: + switch (*advance()) { + case ',': + SIMDJSON_TRY( visitor.increment_count(*this) ); + { + auto key = advance(); + if (simdjson_unlikely( *key != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; } + SIMDJSON_TRY( visitor.visit_key(*this, key) ); + } + goto object_field; + case '}': log_end_value("object"); SIMDJSON_TRY( visitor.visit_object_end(*this) ); goto scope_end; + default: log_error("No comma between object fields"); return TAPE_ERROR; + } + +scope_end: + depth--; + if (depth == 0) { goto document_end; } + if (dom_parser.is_array[depth]) { goto array_continue; } + goto object_continue; + +// +// Array parser states +// +array_begin: + log_start_value("array"); + depth++; + if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; } + dom_parser.is_array[depth] = true; + SIMDJSON_TRY( visitor.visit_array_start(*this) ); + SIMDJSON_TRY( visitor.increment_count(*this) ); + +array_value: + { + auto value = advance(); + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break; + } + } + +array_continue: + switch (*advance()) { + case ',': SIMDJSON_TRY( visitor.increment_count(*this) ); goto array_value; + case ']': log_end_value("array"); SIMDJSON_TRY( visitor.visit_array_end(*this) ); goto scope_end; + default: log_error("Missing comma between array values"); return TAPE_ERROR; + } + +document_end: + log_end_value("document"); + SIMDJSON_TRY( visitor.visit_document_end(*this) ); + + dom_parser.next_structural_index = uint32_t(next_structural - &dom_parser.structural_indexes[0]); + + // If we didn't make it to the end, it's an error + if ( !STREAMING && dom_parser.next_structural_index != dom_parser.n_structural_indexes ) { + log_error("More than one JSON value at the root of the document, or extra characters at the end of the JSON!"); + return TAPE_ERROR; + } + + return SUCCESS; + +} // walk_document() + +simdjson_inline json_iterator::json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index) + : buf{_dom_parser.buf}, + next_structural{&_dom_parser.structural_indexes[start_structural_index]}, + dom_parser{_dom_parser} { +} + +simdjson_inline const uint8_t *json_iterator::peek() const noexcept { + return &buf[*(next_structural)]; +} +simdjson_inline const uint8_t *json_iterator::advance() noexcept { + return &buf[*(next_structural++)]; +} +simdjson_inline size_t json_iterator::remaining_len() const noexcept { + return dom_parser.len - *(next_structural-1); +} + +simdjson_inline bool json_iterator::at_eof() const noexcept { + return next_structural == &dom_parser.structural_indexes[dom_parser.n_structural_indexes]; +} +simdjson_inline bool json_iterator::at_beginning() const noexcept { + return next_structural == dom_parser.structural_indexes.get(); +} +simdjson_inline uint8_t json_iterator::last_structural() const noexcept { + return buf[dom_parser.structural_indexes[dom_parser.n_structural_indexes - 1]]; +} + +simdjson_inline void json_iterator::log_value(const char *type) const noexcept { + logger::log_line(*this, "", type, ""); +} + +simdjson_inline void json_iterator::log_start_value(const char *type) const noexcept { + logger::log_line(*this, "+", type, ""); + if (logger::LOG_ENABLED) { logger::log_depth++; } +} + +simdjson_inline void json_iterator::log_end_value(const char *type) const noexcept { + if (logger::LOG_ENABLED) { logger::log_depth--; } + logger::log_line(*this, "-", type, ""); +} + +simdjson_inline void json_iterator::log_error(const char *error) const noexcept { + logger::log_line(*this, "", "ERROR", error); +} + +template +simdjson_warn_unused simdjson_inline error_code json_iterator::visit_root_primitive(V &visitor, const uint8_t *value) noexcept { + switch (*value) { + case '"': return visitor.visit_root_string(*this, value); + case 't': return visitor.visit_root_true_atom(*this, value); + case 'f': return visitor.visit_root_false_atom(*this, value); + case 'n': return visitor.visit_root_null_atom(*this, value); + case '-': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return visitor.visit_root_number(*this, value); + default: + log_error("Document starts with a non-value character"); + return TAPE_ERROR; + } +} +template +simdjson_warn_unused simdjson_inline error_code json_iterator::visit_primitive(V &visitor, const uint8_t *value) noexcept { + // Use the fact that most scalars are going to be either strings or numbers. + if(*value == '"') { + return visitor.visit_string(*this, value); + } else if (((*value - '0') < 10) || (*value == '-')) { + return visitor.visit_number(*this, value); + } + // true, false, null are uncommon. + switch (*value) { + case 't': return visitor.visit_true_atom(*this, value); + case 'f': return visitor.visit_false_atom(*this, value); + case 'n': return visitor.visit_null_atom(*this, value); + default: + log_error("Non-value found when value was expected!"); + return TAPE_ERROR; + } +} + +} // namespace stage2 +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H +/* end file generic/stage2/json_iterator.h for icelake */ +/* including generic/stage2/stringparsing.h for icelake: #include */ +/* begin file generic/stage2/stringparsing.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses +// It is intended to be included multiple times and compiled multiple times + +namespace simdjson { +namespace icelake { +namespace { +/// @private +namespace stringparsing { + +// begin copypasta +// These chars yield themselves: " \ / +// b -> backspace, f -> formfeed, n -> newline, r -> cr, t -> horizontal tab +// u not handled in this table as it's complex +static const uint8_t escape_map[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0x22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2f, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x4. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5c, 0, 0, 0, // 0x5. + 0, 0, 0x08, 0, 0, 0, 0x0c, 0, 0, 0, 0, 0, 0, 0, 0x0a, 0, // 0x6. + 0, 0, 0x0d, 0, 0x09, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x7. + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +// handle a unicode codepoint +// write appropriate values into dest +// src will advance 6 bytes or 12 bytes +// dest will advance a variable amount (return via pointer) +// return true if the unicode codepoint was valid +// We work in little-endian then swap at write time +simdjson_warn_unused +simdjson_inline bool handle_unicode_codepoint(const uint8_t **src_ptr, + uint8_t **dst_ptr, bool allow_replacement) { + // Use the default Unicode Character 'REPLACEMENT CHARACTER' (U+FFFD) + constexpr uint32_t substitution_code_point = 0xfffd; + // jsoncharutils::hex_to_u32_nocheck fills high 16 bits of the return value with 1s if the + // conversion isn't valid; we defer the check for this to inside the + // multilingual plane check + uint32_t code_point = jsoncharutils::hex_to_u32_nocheck(*src_ptr + 2); + *src_ptr += 6; + + // If we found a high surrogate, we must + // check for low surrogate for characters + // outside the Basic + // Multilingual Plane. + if (code_point >= 0xd800 && code_point < 0xdc00) { + const uint8_t *src_data = *src_ptr; + /* Compiler optimizations convert this to a single 16-bit load and compare on most platforms */ + if (((src_data[0] << 8) | src_data[1]) != ((static_cast ('\\') << 8) | static_cast ('u'))) { + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } else { + uint32_t code_point_2 = jsoncharutils::hex_to_u32_nocheck(src_data + 2); + + // We have already checked that the high surrogate is valid and + // (code_point - 0xd800) < 1024. + // + // Check that code_point_2 is in the range 0xdc00..0xdfff + // and that code_point_2 was parsed from valid hex. + uint32_t low_bit = code_point_2 - 0xdc00; + if (low_bit >> 10) { + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } else { + code_point = (((code_point - 0xd800) << 10) | low_bit) + 0x10000; + *src_ptr += 6; + } + + } + } else if (code_point >= 0xdc00 && code_point <= 0xdfff) { + // If we encounter a low surrogate (not preceded by a high surrogate) + // then we have an error. + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } + size_t offset = jsoncharutils::codepoint_to_utf8(code_point, *dst_ptr); + *dst_ptr += offset; + return offset > 0; +} + + +// handle a unicode codepoint using the wobbly convention +// https://simonsapin.github.io/wtf-8/ +// write appropriate values into dest +// src will advance 6 bytes or 12 bytes +// dest will advance a variable amount (return via pointer) +// return true if the unicode codepoint was valid +// We work in little-endian then swap at write time +simdjson_warn_unused +simdjson_inline bool handle_unicode_codepoint_wobbly(const uint8_t **src_ptr, + uint8_t **dst_ptr) { + // It is not ideal that this function is nearly identical to handle_unicode_codepoint. + // + // jsoncharutils::hex_to_u32_nocheck fills high 16 bits of the return value with 1s if the + // conversion isn't valid; we defer the check for this to inside the + // multilingual plane check + uint32_t code_point = jsoncharutils::hex_to_u32_nocheck(*src_ptr + 2); + *src_ptr += 6; + // If we found a high surrogate, we must + // check for low surrogate for characters + // outside the Basic + // Multilingual Plane. + if (code_point >= 0xd800 && code_point < 0xdc00) { + const uint8_t *src_data = *src_ptr; + /* Compiler optimizations convert this to a single 16-bit load and compare on most platforms */ + if (((src_data[0] << 8) | src_data[1]) == ((static_cast ('\\') << 8) | static_cast ('u'))) { + uint32_t code_point_2 = jsoncharutils::hex_to_u32_nocheck(src_data + 2); + uint32_t low_bit = code_point_2 - 0xdc00; + if ((low_bit >> 10) == 0) { + code_point = + (((code_point - 0xd800) << 10) | low_bit) + 0x10000; + *src_ptr += 6; + } + } + } + + size_t offset = jsoncharutils::codepoint_to_utf8(code_point, *dst_ptr); + *dst_ptr += offset; + return offset > 0; +} + + +/** + * Unescape a valid UTF-8 string from src to dst, stopping at a final unescaped quote. There + * must be an unescaped quote terminating the string. It returns the final output + * position as pointer. In case of error (e.g., the string has bad escaped codes), + * then null_nullptrptr is returned. It is assumed that the output buffer is large + * enough. E.g., if src points at 'joe"', then dst needs to have four free bytes + + * SIMDJSON_PADDING bytes. + */ +simdjson_warn_unused simdjson_inline uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) { + while (1) { + // Copy the next n bytes, and find the backslash and quote in them. + auto bs_quote = backslash_and_quote::copy_and_find(src, dst); + // If the next thing is the end quote, copy and return + if (bs_quote.has_quote_first()) { + // we encountered quotes first. Move dst to point to quotes and exit + return dst + bs_quote.quote_index(); + } + if (bs_quote.has_backslash()) { + /* find out where the backspace is */ + auto bs_dist = bs_quote.backslash_index(); + uint8_t escape_char = src[bs_dist + 1]; + /* we encountered backslash first. Handle backslash */ + if (escape_char == 'u') { + /* move src/dst up to the start; they will be further adjusted + within the unicode codepoint handling code. */ + src += bs_dist; + dst += bs_dist; + if (!handle_unicode_codepoint(&src, &dst, allow_replacement)) { + return nullptr; + } + } else { + /* simple 1:1 conversion. Will eat bs_dist+2 characters in input and + * write bs_dist+1 characters to output + * note this may reach beyond the part of the buffer we've actually + * seen. I think this is ok */ + uint8_t escape_result = escape_map[escape_char]; + if (escape_result == 0u) { + return nullptr; /* bogus escape value is an error */ + } + dst[bs_dist] = escape_result; + src += bs_dist + 2; + dst += bs_dist + 1; + } + } else { + /* they are the same. Since they can't co-occur, it means we + * encountered neither. */ + src += backslash_and_quote::BYTES_PROCESSED; + dst += backslash_and_quote::BYTES_PROCESSED; + } + } +} + +simdjson_warn_unused simdjson_inline uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) { + // It is not ideal that this function is nearly identical to parse_string. + while (1) { + // Copy the next n bytes, and find the backslash and quote in them. + auto bs_quote = backslash_and_quote::copy_and_find(src, dst); + // If the next thing is the end quote, copy and return + if (bs_quote.has_quote_first()) { + // we encountered quotes first. Move dst to point to quotes and exit + return dst + bs_quote.quote_index(); + } + if (bs_quote.has_backslash()) { + /* find out where the backspace is */ + auto bs_dist = bs_quote.backslash_index(); + uint8_t escape_char = src[bs_dist + 1]; + /* we encountered backslash first. Handle backslash */ + if (escape_char == 'u') { + /* move src/dst up to the start; they will be further adjusted + within the unicode codepoint handling code. */ + src += bs_dist; + dst += bs_dist; + if (!handle_unicode_codepoint_wobbly(&src, &dst)) { + return nullptr; + } + } else { + /* simple 1:1 conversion. Will eat bs_dist+2 characters in input and + * write bs_dist+1 characters to output + * note this may reach beyond the part of the buffer we've actually + * seen. I think this is ok */ + uint8_t escape_result = escape_map[escape_char]; + if (escape_result == 0u) { + return nullptr; /* bogus escape value is an error */ + } + dst[bs_dist] = escape_result; + src += bs_dist + 2; + dst += bs_dist + 1; + } + } else { + /* they are the same. Since they can't co-occur, it means we + * encountered neither. */ + src += backslash_and_quote::BYTES_PROCESSED; + dst += backslash_and_quote::BYTES_PROCESSED; + } + } +} + +} // namespace stringparsing +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H +/* end file generic/stage2/stringparsing.h for icelake */ +/* including generic/stage2/structural_iterator.h for icelake: #include */ +/* begin file generic/stage2/structural_iterator.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { +namespace stage2 { + +class structural_iterator { +public: + const uint8_t* const buf; + uint32_t *next_structural; + dom_parser_implementation &dom_parser; + + // Start a structural + simdjson_inline structural_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index) + : buf{_dom_parser.buf}, + next_structural{&_dom_parser.structural_indexes[start_structural_index]}, + dom_parser{_dom_parser} { + } + // Get the buffer position of the current structural character + simdjson_inline const uint8_t* current() { + return &buf[*(next_structural-1)]; + } + // Get the current structural character + simdjson_inline char current_char() { + return buf[*(next_structural-1)]; + } + // Get the next structural character without advancing + simdjson_inline char peek_next_char() { + return buf[*next_structural]; + } + simdjson_inline const uint8_t* peek() { + return &buf[*next_structural]; + } + simdjson_inline const uint8_t* advance() { + return &buf[*(next_structural++)]; + } + simdjson_inline char advance_char() { + return buf[*(next_structural++)]; + } + simdjson_inline size_t remaining_len() { + return dom_parser.len - *(next_structural-1); + } + + simdjson_inline bool at_end() { + return next_structural == &dom_parser.structural_indexes[dom_parser.n_structural_indexes]; + } + simdjson_inline bool at_beginning() { + return next_structural == dom_parser.structural_indexes.get(); + } +}; + +} // namespace stage2 +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H +/* end file generic/stage2/structural_iterator.h for icelake */ +/* including generic/stage2/tape_builder.h for icelake: #include */ +/* begin file generic/stage2/tape_builder.h for icelake */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + + +namespace simdjson { +namespace icelake { +namespace { +namespace stage2 { + +struct tape_builder { + template + simdjson_warn_unused static simdjson_inline error_code parse_document( + dom_parser_implementation &dom_parser, + dom::document &doc) noexcept; + + /** Called when a non-empty document starts. */ + simdjson_warn_unused simdjson_inline error_code visit_document_start(json_iterator &iter) noexcept; + /** Called when a non-empty document ends without error. */ + simdjson_warn_unused simdjson_inline error_code visit_document_end(json_iterator &iter) noexcept; + + /** Called when a non-empty array starts. */ + simdjson_warn_unused simdjson_inline error_code visit_array_start(json_iterator &iter) noexcept; + /** Called when a non-empty array ends. */ + simdjson_warn_unused simdjson_inline error_code visit_array_end(json_iterator &iter) noexcept; + /** Called when an empty array is found. */ + simdjson_warn_unused simdjson_inline error_code visit_empty_array(json_iterator &iter) noexcept; + + /** Called when a non-empty object starts. */ + simdjson_warn_unused simdjson_inline error_code visit_object_start(json_iterator &iter) noexcept; + /** + * Called when a key in a field is encountered. + * + * primitive, visit_object_start, visit_empty_object, visit_array_start, or visit_empty_array + * will be called after this with the field value. + */ + simdjson_warn_unused simdjson_inline error_code visit_key(json_iterator &iter, const uint8_t *key) noexcept; + /** Called when a non-empty object ends. */ + simdjson_warn_unused simdjson_inline error_code visit_object_end(json_iterator &iter) noexcept; + /** Called when an empty object is found. */ + simdjson_warn_unused simdjson_inline error_code visit_empty_object(json_iterator &iter) noexcept; + + /** + * Called when a string, number, boolean or null is found. + */ + simdjson_warn_unused simdjson_inline error_code visit_primitive(json_iterator &iter, const uint8_t *value) noexcept; + /** + * Called when a string, number, boolean or null is found at the top level of a document (i.e. + * when there is no array or object and the entire document is a single string, number, boolean or + * null. + * + * This is separate from primitive() because simdjson's normal primitive parsing routines assume + * there is at least one more token after the value, which is only true in an array or object. + */ + simdjson_warn_unused simdjson_inline error_code visit_root_primitive(json_iterator &iter, const uint8_t *value) noexcept; + + simdjson_warn_unused simdjson_inline error_code visit_string(json_iterator &iter, const uint8_t *value, bool key = false) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_number(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_true_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_false_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_null_atom(json_iterator &iter, const uint8_t *value) noexcept; + + simdjson_warn_unused simdjson_inline error_code visit_root_string(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_number(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_true_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_false_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_null_atom(json_iterator &iter, const uint8_t *value) noexcept; + + /** Called each time a new field or element in an array or object is found. */ + simdjson_warn_unused simdjson_inline error_code increment_count(json_iterator &iter) noexcept; + + /** Next location to write to tape */ + tape_writer tape; +private: + /** Next write location in the string buf for stage 2 parsing */ + uint8_t *current_string_buf_loc; + + simdjson_inline tape_builder(dom::document &doc) noexcept; + + simdjson_inline uint32_t next_tape_index(json_iterator &iter) const noexcept; + simdjson_inline void start_container(json_iterator &iter) noexcept; + simdjson_warn_unused simdjson_inline error_code end_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept; + simdjson_warn_unused simdjson_inline error_code empty_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept; + simdjson_inline uint8_t *on_start_string(json_iterator &iter) noexcept; + simdjson_inline void on_end_string(uint8_t *dst) noexcept; +}; // struct tape_builder + +template +simdjson_warn_unused simdjson_inline error_code tape_builder::parse_document( + dom_parser_implementation &dom_parser, + dom::document &doc) noexcept { + dom_parser.doc = &doc; + json_iterator iter(dom_parser, STREAMING ? dom_parser.next_structural_index : 0); + tape_builder builder(doc); + return iter.walk_document(builder); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_primitive(json_iterator &iter, const uint8_t *value) noexcept { + return iter.visit_root_primitive(*this, value); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_primitive(json_iterator &iter, const uint8_t *value) noexcept { + return iter.visit_primitive(*this, value); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_empty_object(json_iterator &iter) noexcept { + return empty_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_empty_array(json_iterator &iter) noexcept { + return empty_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_document_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_object_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_array_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_object_end(json_iterator &iter) noexcept { + return end_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_array_end(json_iterator &iter) noexcept { + return end_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_document_end(json_iterator &iter) noexcept { + constexpr uint32_t start_tape_index = 0; + tape.append(start_tape_index, internal::tape_type::ROOT); + tape_writer::write(iter.dom_parser.doc->tape[start_tape_index], next_tape_index(iter), internal::tape_type::ROOT); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_key(json_iterator &iter, const uint8_t *key) noexcept { + return visit_string(iter, key, true); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::increment_count(json_iterator &iter) noexcept { + iter.dom_parser.open_containers[iter.depth].count++; // we have a key value pair in the object at parser.dom_parser.depth - 1 + return SUCCESS; +} + +simdjson_inline tape_builder::tape_builder(dom::document &doc) noexcept : tape{doc.tape.get()}, current_string_buf_loc{doc.string_buf.get()} {} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_string(json_iterator &iter, const uint8_t *value, bool key) noexcept { + iter.log_value(key ? "key" : "string"); + uint8_t *dst = on_start_string(iter); + dst = stringparsing::parse_string(value+1, dst, false); // We do not allow replacement when the escape characters are invalid. + if (dst == nullptr) { + iter.log_error("Invalid escape in string"); + return STRING_ERROR; + } + on_end_string(dst); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(json_iterator &iter, const uint8_t *value) noexcept { + return visit_string(iter, value); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("number"); + return numberparsing::parse_number(value, tape); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept { + // + // We need to make a copy to make sure that the string is space terminated. + // This is not about padding the input, which should already padded up + // to len + SIMDJSON_PADDING. However, we have no control at this stage + // on how the padding was done. What if the input string was padded with nulls? + // It is quite common for an input string to have an extra null character (C string). + // We do not want to allow 9\0 (where \0 is the null character) inside a JSON + // document, but the string "9\0" by itself is fine. So we make a copy and + // pad the input with spaces when we know that there is just one input element. + // This copy is relatively expensive, but it will almost never be called in + // practice unless you are in the strange scenario where you have many JSON + // documents made of single atoms. + // + std::unique_ptrcopy(new (std::nothrow) uint8_t[iter.remaining_len() + SIMDJSON_PADDING]); + if (copy.get() == nullptr) { return MEMALLOC; } + std::memcpy(copy.get(), value, iter.remaining_len()); + std::memset(copy.get() + iter.remaining_len(), ' ', SIMDJSON_PADDING); + error_code error = visit_number(iter, copy.get()); + return error; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_true_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("true"); + if (!atomparsing::is_valid_true_atom(value)) { return T_ATOM_ERROR; } + tape.append(0, internal::tape_type::TRUE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_true_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("true"); + if (!atomparsing::is_valid_true_atom(value, iter.remaining_len())) { return T_ATOM_ERROR; } + tape.append(0, internal::tape_type::TRUE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_false_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("false"); + if (!atomparsing::is_valid_false_atom(value)) { return F_ATOM_ERROR; } + tape.append(0, internal::tape_type::FALSE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_false_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("false"); + if (!atomparsing::is_valid_false_atom(value, iter.remaining_len())) { return F_ATOM_ERROR; } + tape.append(0, internal::tape_type::FALSE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_null_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("null"); + if (!atomparsing::is_valid_null_atom(value)) { return N_ATOM_ERROR; } + tape.append(0, internal::tape_type::NULL_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_null_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("null"); + if (!atomparsing::is_valid_null_atom(value, iter.remaining_len())) { return N_ATOM_ERROR; } + tape.append(0, internal::tape_type::NULL_VALUE); + return SUCCESS; +} + +// private: + +simdjson_inline uint32_t tape_builder::next_tape_index(json_iterator &iter) const noexcept { + return uint32_t(tape.next_tape_loc - iter.dom_parser.doc->tape.get()); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::empty_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept { + auto start_index = next_tape_index(iter); + tape.append(start_index+2, start); + tape.append(start_index, end); + return SUCCESS; +} + +simdjson_inline void tape_builder::start_container(json_iterator &iter) noexcept { + iter.dom_parser.open_containers[iter.depth].tape_index = next_tape_index(iter); + iter.dom_parser.open_containers[iter.depth].count = 0; + tape.skip(); // We don't actually *write* the start element until the end. +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::end_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept { + // Write the ending tape element, pointing at the start location + const uint32_t start_tape_index = iter.dom_parser.open_containers[iter.depth].tape_index; + tape.append(start_tape_index, end); + // Write the start tape element, pointing at the end location (and including count) + // count can overflow if it exceeds 24 bits... so we saturate + // the convention being that a cnt of 0xffffff or more is undetermined in value (>= 0xffffff). + const uint32_t count = iter.dom_parser.open_containers[iter.depth].count; + const uint32_t cntsat = count > 0xFFFFFF ? 0xFFFFFF : count; + tape_writer::write(iter.dom_parser.doc->tape[start_tape_index], next_tape_index(iter) | (uint64_t(cntsat) << 32), start); + return SUCCESS; +} + +simdjson_inline uint8_t *tape_builder::on_start_string(json_iterator &iter) noexcept { + // we advance the point, accounting for the fact that we have a NULL termination + tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::STRING); + return current_string_buf_loc + sizeof(uint32_t); +} + +simdjson_inline void tape_builder::on_end_string(uint8_t *dst) noexcept { + uint32_t str_length = uint32_t(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 + // Currently unneeded because we refuse to parse docs larger or equal to 4GB. + memcpy(current_string_buf_loc, &str_length, sizeof(uint32_t)); + // NULL termination is still handy if you expect all your strings to + // be NULL terminated? It comes at a small cost + *dst = 0; + current_string_buf_loc = dst + 1; +} + +} // namespace stage2 +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H +/* end file generic/stage2/tape_builder.h for icelake */ +/* end file generic/stage2/amalgamated.h for icelake */ + +#undef SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + +// +// Stage 1 +// + +namespace simdjson { +namespace icelake { + +simdjson_warn_unused error_code implementation::create_dom_parser_implementation( + size_t capacity, + size_t max_depth, + std::unique_ptr& dst +) const noexcept { + dst.reset( new (std::nothrow) dom_parser_implementation() ); + if (!dst) { return MEMALLOC; } + if (auto err = dst->set_capacity(capacity)) + return err; + if (auto err = dst->set_max_depth(max_depth)) + return err; + return SUCCESS; +} + +namespace { + +using namespace simd; + +// This identifies structural characters (comma, colon, braces, brackets), +// and ASCII white-space ('\r','\n','\t',' '). +simdjson_inline json_character_block json_character_block::classify(const simd::simd8x64& in) { + // These lookups rely on the fact that anything < 127 will match the lower 4 bits, which is why + // we can't use the generic lookup_16. + const auto whitespace_table = simd8::repeat_16(' ', 100, 100, 100, 17, 100, 113, 2, 100, '\t', '\n', 112, 100, '\r', 100, 100); + + // The 6 operators (:,[]{}) have these values: + // + // , 2C + // : 3A + // [ 5B + // { 7B + // ] 5D + // } 7D + // + // If you use | 0x20 to turn [ and ] into { and }, the lower 4 bits of each character is unique. + // We exploit this, using a simd 4-bit lookup to tell us which character match against, and then + // match it (against | 0x20). + // + // To prevent recognizing other characters, everything else gets compared with 0, which cannot + // match due to the | 0x20. + // + // NOTE: Due to the | 0x20, this ALSO treats and (control characters 0C and 1A) like , + // and :. This gets caught in stage 2, which checks the actual character to ensure the right + // operators are in the right places. + const auto op_table = simd8::repeat_16( + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, ':', '{', // : = 3A, [ = 5B, { = 7B + ',', '}', 0, 0 // , = 2C, ] = 5D, } = 7D + ); + + // We compute whitespace and op separately. If later code only uses one or the + // other, given the fact that all functions are aggressively inlined, we can + // hope that useless computations will be omitted. This is namely case when + // minifying (we only need whitespace). + + const uint64_t whitespace = in.eq({ + _mm512_shuffle_epi8(whitespace_table, in.chunks[0]) + }); + // Turn [ and ] into { and } + const simd8x64 curlified{ + in.chunks[0] | 0x20 + }; + const uint64_t op = curlified.eq({ + _mm512_shuffle_epi8(op_table, in.chunks[0]) + }); + + return { whitespace, op }; +} + +simdjson_inline bool is_ascii(const simd8x64& input) { + return input.reduce_or().is_ascii(); +} + +simdjson_unused simdjson_inline simd8 must_be_continuation(const simd8 prev1, const simd8 prev2, const simd8 prev3) { + simd8 is_second_byte = prev1.saturating_sub(0xc0u-1); // Only 11______ will be > 0 + simd8 is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0 + simd8 is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0 + // Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine. + return simd8(is_second_byte | is_third_byte | is_fourth_byte) > int8_t(0); +} + +simdjson_inline simd8 must_be_2_3_continuation(const simd8 prev2, const simd8 prev3) { + simd8 is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0 + simd8 is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0 + // Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine. + return simd8(is_third_byte | is_fourth_byte) > int8_t(0); +} + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +/** + * We provide a custom version of bit_indexer::write using + * naked intrinsics. + * TODO: make this code more elegant. + */ +// Under GCC 12, the intrinsic _mm512_extracti32x4_epi32 may generate 'maybe uninitialized'. +// as a workaround, we disable warnings within the following function. +SIMDJSON_PUSH_DISABLE_ALL_WARNINGS +namespace simdjson { namespace icelake { namespace { namespace stage1 { +simdjson_inline void bit_indexer::write(uint32_t idx, uint64_t bits) { + // In some instances, the next branch is expensive because it is mispredicted. + // Unfortunately, in other cases, + // it helps tremendously. + if (bits == 0) { return; } + + const __m512i indexes = _mm512_maskz_compress_epi8(bits, _mm512_set_epi32( + 0x3f3e3d3c, 0x3b3a3938, 0x37363534, 0x33323130, + 0x2f2e2d2c, 0x2b2a2928, 0x27262524, 0x23222120, + 0x1f1e1d1c, 0x1b1a1918, 0x17161514, 0x13121110, + 0x0f0e0d0c, 0x0b0a0908, 0x07060504, 0x03020100 + )); + const __m512i start_index = _mm512_set1_epi32(idx); + + const auto count = count_ones(bits); + __m512i t0 = _mm512_cvtepu8_epi32(_mm512_castsi512_si128(indexes)); + _mm512_storeu_si512(this->tail, _mm512_add_epi32(t0, start_index)); + + if(count > 16) { + const __m512i t1 = _mm512_cvtepu8_epi32(_mm512_extracti32x4_epi32(indexes, 1)); + _mm512_storeu_si512(this->tail + 16, _mm512_add_epi32(t1, start_index)); + if(count > 32) { + const __m512i t2 = _mm512_cvtepu8_epi32(_mm512_extracti32x4_epi32(indexes, 2)); + _mm512_storeu_si512(this->tail + 32, _mm512_add_epi32(t2, start_index)); + if(count > 48) { + const __m512i t3 = _mm512_cvtepu8_epi32(_mm512_extracti32x4_epi32(indexes, 3)); + _mm512_storeu_si512(this->tail + 48, _mm512_add_epi32(t3, start_index)); + } + } + } + this->tail += count; +} +}}}} +SIMDJSON_POP_DISABLE_WARNINGS + +// +// Stage 2 +// + +// +// Implementation-specific overrides +// +namespace simdjson { +namespace icelake { + +simdjson_warn_unused error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept { + return icelake::stage1::json_minifier::minify<128>(buf, len, dst, dst_len); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, stage1_mode streaming) noexcept { + this->buf = _buf; + this->len = _len; + return icelake::stage1::json_structural_indexer::index<128>(_buf, _len, *this, streaming); +} + +simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t len) const noexcept { + return icelake::stage1::generic_validate_utf8(buf,len); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { + return stage2::tape_builder::parse_document(*this, _doc); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { + return stage2::tape_builder::parse_document(*this, _doc); +} + +simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { + return icelake::stringparsing::parse_string(src, dst, replacement_char); +} + +simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept { + return icelake::stringparsing::parse_wobbly_string(src, dst); +} + +simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { + auto error = stage1(_buf, _len, stage1_mode::regular); + if (error) { return error; } + return stage2(_doc); +} + +} // namespace icelake +} // namespace simdjson + +/* including simdjson/icelake/end.h: #include */ +/* begin file simdjson/icelake/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_ICELAKE +SIMDJSON_UNTARGET_REGION +#endif + +/* undefining SIMDJSON_IMPLEMENTATION from "icelake" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/icelake/end.h */ + +#endif // SIMDJSON_SRC_ICELAKE_CPP +/* end file icelake.cpp */ +#endif +#if SIMDJSON_IMPLEMENTATION_PPC64 +/* including ppc64.cpp: #include */ +/* begin file ppc64.cpp */ +#ifndef SIMDJSON_SRC_PPC64_CPP +#define SIMDJSON_SRC_PPC64_CPP + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +/* including simdjson/ppc64.h: #include */ +/* begin file simdjson/ppc64.h */ +#ifndef SIMDJSON_PPC64_H +#define SIMDJSON_PPC64_H + +/* including simdjson/ppc64/begin.h: #include "simdjson/ppc64/begin.h" */ +/* begin file simdjson/ppc64/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "ppc64" */ +#define SIMDJSON_IMPLEMENTATION ppc64 +/* including simdjson/ppc64/base.h: #include "simdjson/ppc64/base.h" */ +/* begin file simdjson/ppc64/base.h */ +#ifndef SIMDJSON_PPC64_BASE_H +#define SIMDJSON_PPC64_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Implementation for ALTIVEC (PPC64). + */ +namespace ppc64 { + +class implementation; + +namespace { +namespace simd { +template struct simd8; +template struct simd8x64; +} // namespace simd +} // unnamed namespace + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_BASE_H +/* end file simdjson/ppc64/base.h */ +/* including simdjson/ppc64/intrinsics.h: #include "simdjson/ppc64/intrinsics.h" */ +/* begin file simdjson/ppc64/intrinsics.h */ +#ifndef SIMDJSON_PPC64_INTRINSICS_H +#define SIMDJSON_PPC64_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This should be the correct header whether +// you use visual studio or other compilers. +#include + +// These are defined by altivec.h in GCC toolchain, it is safe to undef them. +#ifdef bool +#undef bool +#endif + +#ifdef vector +#undef vector +#endif + +static_assert(sizeof(__vector unsigned char) <= simdjson::SIMDJSON_PADDING, "insufficient padding for ppc64"); + +#endif // SIMDJSON_PPC64_INTRINSICS_H +/* end file simdjson/ppc64/intrinsics.h */ +/* including simdjson/ppc64/bitmanipulation.h: #include "simdjson/ppc64/bitmanipulation.h" */ +/* begin file simdjson/ppc64/bitmanipulation.h */ +#ifndef SIMDJSON_PPC64_BITMANIPULATION_H +#define SIMDJSON_PPC64_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num - 1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline int count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num); // Visual Studio wants two underscores +} +#else +simdjson_inline int count_ones(uint64_t input_num) { + return __builtin_popcountll(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + *result = value1 + value2; + return *result < value1; +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_BITMANIPULATION_H +/* end file simdjson/ppc64/bitmanipulation.h */ +/* including simdjson/ppc64/bitmask.h: #include "simdjson/ppc64/bitmask.h" */ +/* begin file simdjson/ppc64/bitmask.h */ +#ifndef SIMDJSON_PPC64_BITMASK_H +#define SIMDJSON_PPC64_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is +// encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(uint64_t bitmask) { + // You can use the version below, however gcc sometimes miscompiles + // vec_pmsum_be, it happens somewhere around between 8 and 9th version. + // The performance boost was not noticeable, falling back to a usual + // implementation. + // __vector unsigned long long all_ones = {~0ull, ~0ull}; + // __vector unsigned long long mask = {bitmask, 0}; + // // Clang and GCC return different values for pmsum for ull so cast it to one. + // // Generally it is not specified by ALTIVEC ISA what is returned by + // // vec_pmsum_be. + // #if defined(__LITTLE_ENDIAN__) + // return (uint64_t)(((__vector unsigned long long)vec_pmsum_be(all_ones, mask))[0]); + // #else + // return (uint64_t)(((__vector unsigned long long)vec_pmsum_be(all_ones, mask))[1]); + // #endif + bitmask ^= bitmask << 1; + bitmask ^= bitmask << 2; + bitmask ^= bitmask << 4; + bitmask ^= bitmask << 8; + bitmask ^= bitmask << 16; + bitmask ^= bitmask << 32; + return bitmask; +} + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif +/* end file simdjson/ppc64/bitmask.h */ +/* including simdjson/ppc64/numberparsing_defs.h: #include "simdjson/ppc64/numberparsing_defs.h" */ +/* begin file simdjson/ppc64/numberparsing_defs.h */ +#ifndef SIMDJSON_PPC64_NUMBERPARSING_DEFS_H +#define SIMDJSON_PPC64_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +#if defined(__linux__) +#include +#elif defined(__FreeBSD__) +#include +#endif + +namespace simdjson { +namespace ppc64 { +namespace numberparsing { + +// we don't have appropriate instructions, so let us use a scalar function +// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + uint64_t val; + std::memcpy(&val, chars, sizeof(uint64_t)); +#ifdef __BIG_ENDIAN__ +#if defined(__linux__) + val = bswap_64(val); +#elif defined(__FreeBSD__) + val = bswap64(val); +#endif +#endif + val = (val & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8; + val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16; + return uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32); +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace ppc64 +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_PPC64_NUMBERPARSING_DEFS_H +/* end file simdjson/ppc64/numberparsing_defs.h */ +/* including simdjson/ppc64/simd.h: #include "simdjson/ppc64/simd.h" */ +/* begin file simdjson/ppc64/simd.h */ +#ifndef SIMDJSON_PPC64_SIMD_H +#define SIMDJSON_PPC64_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace ppc64 { +namespace { +namespace simd { + +using __m128i = __vector unsigned char; + +template struct base { + __m128i value; + + // Zero constructor + simdjson_inline base() : value{__m128i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m128i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m128i &() const { + return this->value; + } + simdjson_inline operator __m128i &() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { + return vec_or(this->value, (__m128i)other); + } + simdjson_inline Child operator&(const Child other) const { + return vec_and(this->value, (__m128i)other); + } + simdjson_inline Child operator^(const Child other) const { + return vec_xor(this->value, (__m128i)other); + } + simdjson_inline Child bit_andnot(const Child other) const { + return vec_andc(this->value, (__m128i)other); + } + simdjson_inline Child &operator|=(const Child other) { + auto this_cast = static_cast(this); + *this_cast = *this_cast | other; + return *this_cast; + } + simdjson_inline Child &operator&=(const Child other) { + auto this_cast = static_cast(this); + *this_cast = *this_cast & other; + return *this_cast; + } + simdjson_inline Child &operator^=(const Child other) { + auto this_cast = static_cast(this); + *this_cast = *this_cast ^ other; + return *this_cast; + } +}; + +template > +struct base8 : base> { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m128i _value) : base>(_value) {} + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { + return (__m128i)vec_cmpeq(lhs.value, (__m128i)rhs); + } + + static const int SIZE = sizeof(base>::value); + + template + simdjson_inline simd8 prev(simd8 prev_chunk) const { + __m128i chunk = this->value; +#ifdef __LITTLE_ENDIAN__ + chunk = (__m128i)vec_reve(this->value); + prev_chunk = (__m128i)vec_reve((__m128i)prev_chunk); +#endif + chunk = (__m128i)vec_sld((__m128i)prev_chunk, (__m128i)chunk, 16 - N); +#ifdef __LITTLE_ENDIAN__ + chunk = (__m128i)vec_reve((__m128i)chunk); +#endif + return chunk; + } +}; + +// SIMD byte mask type (returned by things like eq and gt) +template <> struct simd8 : base8 { + static simdjson_inline simd8 splat(bool _value) { + return (__m128i)vec_splats((unsigned char)(-(!!_value))); + } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m128i _value) + : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) + : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { + __vector unsigned long long result; + const __m128i perm_mask = {0x78, 0x70, 0x68, 0x60, 0x58, 0x50, 0x48, 0x40, + 0x38, 0x30, 0x28, 0x20, 0x18, 0x10, 0x08, 0x00}; + + result = ((__vector unsigned long long)vec_vbpermq((__m128i)this->value, + (__m128i)perm_mask)); +#ifdef __LITTLE_ENDIAN__ + return static_cast(result[1]); +#else + return static_cast(result[0]); +#endif + } + simdjson_inline bool any() const { + return !vec_all_eq(this->value, (__m128i)vec_splats(0)); + } + simdjson_inline simd8 operator~() const { + return this->value ^ (__m128i)splat(true); + } +}; + +template struct base8_numeric : base8 { + static simdjson_inline simd8 splat(T value) { + (void)value; + return (__m128i)vec_splats(value); + } + static simdjson_inline simd8 zero() { return splat(0); } + static simdjson_inline simd8 load(const T values[16]) { + return (__m128i)(vec_vsx_ld(0, reinterpret_cast(values))); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16(T v0, T v1, T v2, T v3, T v4, + T v5, T v6, T v7, T v8, T v9, + T v10, T v11, T v12, T v13, + T v14, T v15) { + return simd8(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m128i _value) + : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[16]) const { + vec_vsx_st(this->value, 0, reinterpret_cast<__m128i *>(dst)); + } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { + return (__m128i)((__m128i)this->value + (__m128i)other); + } + simdjson_inline simd8 operator-(const simd8 other) const { + return (__m128i)((__m128i)this->value - (__m128i)other); + } + simdjson_inline simd8 &operator+=(const simd8 other) { + *this = *this + other; + return *static_cast *>(this); + } + simdjson_inline simd8 &operator-=(const simd8 other) { + *this = *this - other; + return *static_cast *>(this); + } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior + // for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return (__m128i)vec_perm((__m128i)lookup_table, (__m128i)lookup_table, this->value); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted + // as a bitset). Passing a 0 value for mask would be equivalent to writing out + // every byte to output. Only the first 16 - count_ones(mask) bytes of the + // result are significant but 16 bytes get written. Design consideration: it + // seems like a function with the signature simd8 compress(uint32_t mask) + // would be sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L *output) const { + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + using internal::thintable_epi8; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. +#ifdef __LITTLE_ENDIAN__ + __m128i shufmask = (__m128i)(__vector unsigned long long){ + thintable_epi8[mask1], thintable_epi8[mask2]}; +#else + __m128i shufmask = (__m128i)(__vector unsigned long long){ + thintable_epi8[mask2], thintable_epi8[mask1]}; + shufmask = (__m128i)vec_reve((__m128i)shufmask); +#endif + // we increment by 0x08 the second half of the mask + shufmask = ((__m128i)shufmask) + + ((__m128i)(__vector int){0, 0, 0x08080808, 0x08080808}); + + // this is the version "nearly pruned" + __m128i pruned = vec_perm(this->value, this->value, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + __m128i compactmask = + vec_vsx_ld(0, reinterpret_cast(pshufb_combine_table + pop1 * 8)); + __m128i answer = vec_perm(pruned, (__m128i)vec_splats(0), compactmask); + vec_vsx_st(answer, 0, reinterpret_cast<__m128i *>(output)); + } + + template + simdjson_inline simd8 + lookup_16(L replace0, L replace1, L replace2, L replace3, L replace4, + L replace5, L replace6, L replace7, L replace8, L replace9, + L replace10, L replace11, L replace12, L replace13, L replace14, + L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, replace4, replace5, replace6, + replace7, replace8, replace9, replace10, replace11, replace12, + replace13, replace14, replace15)); + } +}; + +// Signed bytes +template <> struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) + : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t *values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8(int8_t v0, int8_t v1, int8_t v2, int8_t v3, + int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, + int8_t v12, int8_t v13, int8_t v14, int8_t v15) + : simd8((__m128i)(__vector signed char){v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, + v15}) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 + repeat_16(int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, + int8_t v6, int8_t v7, int8_t v8, int8_t v9, int8_t v10, int8_t v11, + int8_t v12, int8_t v13, int8_t v14, int8_t v15) { + return simd8(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); + } + + // Order-sensitive comparisons + simdjson_inline simd8 + max_val(const simd8 other) const { + return (__m128i)vec_max((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } + simdjson_inline simd8 + min_val(const simd8 other) const { + return (__m128i)vec_min((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } + simdjson_inline simd8 + operator>(const simd8 other) const { + return (__m128i)vec_cmpgt((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } + simdjson_inline simd8 + operator<(const simd8 other) const { + return (__m128i)vec_cmplt((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } +}; + +// Unsigned bytes +template <> struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) + : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t *values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline + simd8(uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, + uint8_t v6, uint8_t v7, uint8_t v8, uint8_t v9, uint8_t v10, + uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15) + : simd8((__m128i){v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15}) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 + repeat_16(uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, + uint8_t v5, uint8_t v6, uint8_t v7, uint8_t v8, uint8_t v9, + uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, + uint8_t v15) { + return simd8(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); + } + + // Saturated math + simdjson_inline simd8 + saturating_add(const simd8 other) const { + return (__m128i)vec_adds(this->value, (__m128i)other); + } + simdjson_inline simd8 + saturating_sub(const simd8 other) const { + return (__m128i)vec_subs(this->value, (__m128i)other); + } + + // Order-specific operations + simdjson_inline simd8 + max_val(const simd8 other) const { + return (__m128i)vec_max(this->value, (__m128i)other); + } + simdjson_inline simd8 + min_val(const simd8 other) const { + return (__m128i)vec_min(this->value, (__m128i)other); + } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 + gt_bits(const simd8 other) const { + return this->saturating_sub(other); + } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 + lt_bits(const simd8 other) const { + return other.saturating_sub(*this); + } + simdjson_inline simd8 + operator<=(const simd8 other) const { + return other.max_val(*this) == other; + } + simdjson_inline simd8 + operator>=(const simd8 other) const { + return other.min_val(*this) == other; + } + simdjson_inline simd8 + operator>(const simd8 other) const { + return this->gt_bits(other).any_bits_set(); + } + simdjson_inline simd8 + operator<(const simd8 other) const { + return this->gt_bits(other).any_bits_set(); + } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { + return (__m128i)vec_cmpeq(this->value, (__m128i)vec_splats(uint8_t(0))); + } + simdjson_inline simd8 bits_not_set(simd8 bits) const { + return (*this & bits).bits_not_set(); + } + simdjson_inline simd8 any_bits_set() const { + return ~this->bits_not_set(); + } + simdjson_inline simd8 any_bits_set(simd8 bits) const { + return ~this->bits_not_set(bits); + } + simdjson_inline bool bits_not_set_anywhere() const { + return vec_all_eq(this->value, (__m128i)vec_splats(0)); + } + simdjson_inline bool any_bits_set_anywhere() const { + return !bits_not_set_anywhere(); + } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { + return vec_all_eq(vec_and(this->value, (__m128i)bits), + (__m128i)vec_splats(0)); + } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { + return !bits_not_set_anywhere(bits); + } + template simdjson_inline simd8 shr() const { + return simd8( + (__m128i)vec_sr(this->value, (__m128i)vec_splat_u8(N))); + } + template simdjson_inline simd8 shl() const { + return simd8( + (__m128i)vec_sl(this->value, (__m128i)vec_splat_u8(N))); + } +}; + +template struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, + "PPC64 kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64 &o) = delete; // no copy allowed + simd8x64 & + operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, + const simd8 chunk2, const simd8 chunk3) + : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) + : chunks{simd8::load(ptr), simd8::load(ptr + 16), + simd8::load(ptr + 32), simd8::load(ptr + 48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr + sizeof(simd8) * 0); + this->chunks[1].store(ptr + sizeof(simd8) * 1); + this->chunks[2].store(ptr + sizeof(simd8) * 2); + this->chunks[3].store(ptr + sizeof(simd8) * 3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | + (this->chunks[2] | this->chunks[3]); + } + + simdjson_inline uint64_t compress(uint64_t mask, T *output) const { + this->chunks[0].compress(uint16_t(mask), output); + this->chunks[1].compress(uint16_t(mask >> 16), + output + 16 - count_ones(mask & 0xFFFF)); + this->chunks[2].compress(uint16_t(mask >> 32), + output + 32 - count_ones(mask & 0xFFFFFFFF)); + this->chunks[3].compress(uint16_t(mask >> 48), + output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); + return 64 - count_ones(mask); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r0 = uint32_t(this->chunks[0].to_bitmask()); + uint64_t r1 = this->chunks[1].to_bitmask(); + uint64_t r2 = this->chunks[2].to_bitmask(); + uint64_t r3 = this->chunks[3].to_bitmask(); + return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64(this->chunks[0] == mask, this->chunks[1] == mask, + this->chunks[2] == mask, this->chunks[3] == mask) + .to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64(this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1], + this->chunks[2] == other.chunks[2], + this->chunks[3] == other.chunks[3]) + .to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64(this->chunks[0] <= mask, this->chunks[1] <= mask, + this->chunks[2] <= mask, this->chunks[3] <= mask) + .to_bitmask(); + } +}; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_SIMD_INPUT_H +/* end file simdjson/ppc64/simd.h */ +/* including simdjson/ppc64/stringparsing_defs.h: #include "simdjson/ppc64/stringparsing_defs.h" */ +/* begin file simdjson/ppc64/stringparsing_defs.h */ +#ifndef SIMDJSON_PPC64_STRINGPARSING_DEFS_H +#define SIMDJSON_PPC64_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/simd.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote + copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { + return ((bs_bits - 1) & quote_bits) != 0; + } + simdjson_inline bool has_backslash() { return bs_bits != 0; } + simdjson_inline int quote_index() { + return trailing_zeroes(quote_bits); + } + simdjson_inline int backslash_index() { + return trailing_zeroes(bs_bits); + } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote +backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 31 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), + "backslash and quote finder must process fewer than " + "SIMDJSON_PADDING bytes"); + simd8 v0(src); + simd8 v1(src + sizeof(v0)); + v0.store(dst); + v1.store(dst + sizeof(v0)); + + // Getting a 64-bit bitmask is much cheaper than multiple 16-bit bitmasks on + // PPC; therefore, we smash them together into a 64-byte mask and get the + // bitmask from there. + uint64_t bs_and_quote = + simd8x64(v0 == '\\', v1 == '\\', v0 == '"', v1 == '"').to_bitmask(); + return { + uint32_t(bs_and_quote), // bs_bits + uint32_t(bs_and_quote >> 32) // quote_bits + }; +} + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_STRINGPARSING_DEFS_H +/* end file simdjson/ppc64/stringparsing_defs.h */ + +#define SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT 1 +/* end file simdjson/ppc64/begin.h */ +/* including simdjson/generic/amalgamated.h for ppc64: #include "simdjson/generic/amalgamated.h" */ +/* begin file simdjson/generic/amalgamated.h for ppc64 */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_DEPENDENCIES_H) +#error simdjson/generic/dependencies.h must be included before simdjson/generic/amalgamated.h! +#endif + +/* including simdjson/generic/base.h for ppc64: #include "simdjson/generic/base.h" */ +/* begin file simdjson/generic/base.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): // If we haven't got an implementation yet, we're in the editor, editing a generic file! Just */ +/* amalgamation skipped (editor-only): // use the most advanced one we can so the most possible stuff can be tested. */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation_detection.h" */ +/* amalgamation skipped (editor-only): #if SIMDJSON_IMPLEMENTATION_ICELAKE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_HASWELL */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_WESTMERE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_ARM64 */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_PPC64 */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_FALLBACK */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/begin.h" */ +/* amalgamation skipped (editor-only): #else */ +/* amalgamation skipped (editor-only): #error "All possible implementations (including fallback) have been disabled! simdjson will not run." */ +/* amalgamation skipped (editor-only): #endif */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { + +struct open_container; +class dom_parser_implementation; + +/** + * The type of a JSON number + */ +enum class number_type { + floating_point_number=1, /// a binary64 number + signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + unsigned_integer /// a positive integer larger or equal to 1<<63 +}; + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_BASE_H +/* end file simdjson/generic/base.h for ppc64 */ +/* including simdjson/generic/jsoncharutils.h for ppc64: #include "simdjson/generic/jsoncharutils.h" */ +/* begin file simdjson/generic/jsoncharutils.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_JSONCHARUTILS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_JSONCHARUTILS_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/jsoncharutils_tables.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { +namespace jsoncharutils { + +// return non-zero if not a structural or whitespace char +// zero otherwise +simdjson_inline uint32_t is_not_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace_negated[c]; +} + +simdjson_inline uint32_t is_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace[c]; +} + +// returns a value with the high 16 bits set if not valid +// otherwise returns the conversion of the 4 hex digits at src into the bottom +// 16 bits of the 32-bit return register +// +// see +// https://lemire.me/blog/2019/04/17/parsing-short-hexadecimal-strings-efficiently/ +static inline uint32_t hex_to_u32_nocheck( + const uint8_t *src) { // strictly speaking, static inline is a C-ism + uint32_t v1 = internal::digit_to_val32[630 + src[0]]; + uint32_t v2 = internal::digit_to_val32[420 + src[1]]; + uint32_t v3 = internal::digit_to_val32[210 + src[2]]; + uint32_t v4 = internal::digit_to_val32[0 + src[3]]; + return v1 | v2 | v3 | v4; +} + +// given a code point cp, writes to c +// the utf-8 code, outputting the length in +// bytes, if the length is zero, the code point +// is invalid +// +// This can possibly be made faster using pdep +// and clz and table lookups, but JSON documents +// have few escaped code points, and the following +// function looks cheap. +// +// Note: we assume that surrogates are treated separately +// +simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) { + if (cp <= 0x7F) { + c[0] = uint8_t(cp); + return 1; // ascii + } + if (cp <= 0x7FF) { + c[0] = uint8_t((cp >> 6) + 192); + c[1] = uint8_t((cp & 63) + 128); + return 2; // universal plane + // Surrogates are treated elsewhere... + //} //else if (0xd800 <= cp && cp <= 0xdfff) { + // return 0; // surrogates // could put assert here + } else if (cp <= 0xFFFF) { + c[0] = uint8_t((cp >> 12) + 224); + c[1] = uint8_t(((cp >> 6) & 63) + 128); + c[2] = uint8_t((cp & 63) + 128); + return 3; + } else if (cp <= 0x10FFFF) { // if you know you have a valid code point, this + // is not needed + c[0] = uint8_t((cp >> 18) + 240); + c[1] = uint8_t(((cp >> 12) & 63) + 128); + c[2] = uint8_t(((cp >> 6) & 63) + 128); + c[3] = uint8_t((cp & 63) + 128); + return 4; + } + // will return 0 when the code point was too large. + return 0; // bad r +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +} // namespace jsoncharutils +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_JSONCHARUTILS_H +/* end file simdjson/generic/jsoncharutils.h for ppc64 */ +/* including simdjson/generic/atomparsing.h for ppc64: #include "simdjson/generic/atomparsing.h" */ +/* begin file simdjson/generic/atomparsing.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ATOMPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ATOMPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace ppc64 { +namespace { +/// @private +namespace atomparsing { + +// The string_to_uint32 is exclusively used to map literal strings to 32-bit values. +// We use memcpy instead of a pointer cast to avoid undefined behaviors since we cannot +// be certain that the character pointer will be properly aligned. +// You might think that using memcpy makes this function expensive, but you'd be wrong. +// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false"); +// to the compile-time constant 1936482662. +simdjson_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; } + + +// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive. +// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about. +simdjson_warn_unused +simdjson_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) { + uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++) + static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes"); + std::memcpy(&srcval, src, sizeof(uint32_t)); + return srcval ^ string_to_uint32(atom); +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src) { + return (str4ncmp(src, "true") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_true_atom(src); } + else if (len == 4) { return !str4ncmp(src, "true"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src) { + return (str4ncmp(src+1, "alse") | jsoncharutils::is_not_structural_or_whitespace(src[5])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src, size_t len) { + if (len > 5) { return is_valid_false_atom(src); } + else if (len == 5) { return !str4ncmp(src+1, "alse"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src) { + return (str4ncmp(src, "null") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_null_atom(src); } + else if (len == 4) { return !str4ncmp(src, "null"); } + else { return false; } +} + +} // namespace atomparsing +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ATOMPARSING_H +/* end file simdjson/generic/atomparsing.h for ppc64 */ +/* including simdjson/generic/dom_parser_implementation.h for ppc64: #include "simdjson/generic/dom_parser_implementation.h" */ +/* begin file simdjson/generic/dom_parser_implementation.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { + +// expectation: sizeof(open_container) = 64/8. +struct open_container { + uint32_t tape_index; // where, on the tape, does the scope ([,{) begins + uint32_t count; // how many elements in the scope +}; // struct open_container + +static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits"); + +class dom_parser_implementation final : public internal::dom_parser_implementation { +public: + /** Tape location of each open { or [ */ + std::unique_ptr open_containers{}; + /** Whether each open container is a [ or { */ + std::unique_ptr is_array{}; + /** Buffer passed to stage 1 */ + const uint8_t *buf{}; + /** Length passed to stage 1 */ + size_t len{0}; + /** Document passed to stage 2 */ + dom::document *doc{}; + + inline dom_parser_implementation() noexcept; + inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; + inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; + dom_parser_implementation(const dom_parser_implementation &) = delete; + dom_parser_implementation &operator=(const dom_parser_implementation &) = delete; + + simdjson_warn_unused error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage1(const uint8_t *buf, size_t len, stage1_mode partial) noexcept final; + simdjson_warn_unused error_code stage2(dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage2_next(dom::document &doc) noexcept final; + simdjson_warn_unused uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept final; + simdjson_warn_unused uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept final; + inline simdjson_warn_unused error_code set_capacity(size_t capacity) noexcept final; + inline simdjson_warn_unused error_code set_max_depth(size_t max_depth) noexcept final; +private: + simdjson_inline simdjson_warn_unused error_code set_capacity_stage1(size_t capacity); + +}; + +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { +namespace ppc64 { + +inline dom_parser_implementation::dom_parser_implementation() noexcept = default; +inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; +inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; + +// Leaving these here so they can be inlined if so desired +inline simdjson_warn_unused error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept { + if(capacity > SIMDJSON_MAXSIZE_BYTES) { return CAPACITY; } + // Stage 1 index output + size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7; + structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] ); + if (!structural_indexes) { _capacity = 0; return MEMALLOC; } + structural_indexes[0] = 0; + n_structural_indexes = 0; + + _capacity = capacity; + return SUCCESS; +} + +inline simdjson_warn_unused error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept { + // Stage 2 stacks + open_containers.reset(new (std::nothrow) open_container[max_depth]); + is_array.reset(new (std::nothrow) bool[max_depth]); + if (!is_array || !open_containers) { _max_depth = 0; return MEMALLOC; } + + _max_depth = max_depth; + return SUCCESS; +} + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file simdjson/generic/dom_parser_implementation.h for ppc64 */ +/* including simdjson/generic/implementation_simdjson_result_base.h for ppc64: #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { + +// This is a near copy of include/error.h's implementation_simdjson_result_base, except it doesn't use std::pair +// so we can avoid inlining errors +// TODO reconcile these! +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + * + * This is a base class for implementations that want to add functions to the result type for + * chaining. + * + * Override like: + * + * struct simdjson_result : public internal::implementation_simdjson_result_base { + * simdjson_result() noexcept : internal::implementation_simdjson_result_base() {} + * simdjson_result(error_code error) noexcept : internal::implementation_simdjson_result_base(error) {} + * simdjson_result(T &&value) noexcept : internal::implementation_simdjson_result_base(std::forward(value)) {} + * simdjson_result(T &&value, error_code error) noexcept : internal::implementation_simdjson_result_base(value, error) {} + * // Your extra methods here + * } + * + * Then any method returning simdjson_result will be chainable with your methods. + */ +template +struct implementation_simdjson_result_base { + + /** + * Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline implementation_simdjson_result_base() noexcept = default; + + /** + * Create a new error result. + */ + simdjson_inline implementation_simdjson_result_base(error_code error) noexcept; + + /** + * Create a new successful result. + */ + simdjson_inline implementation_simdjson_result_base(T &&value) noexcept; + + /** + * Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline implementation_simdjson_result_base(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); + + +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T& value_unsafe() & noexcept; + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; +protected: + /** users should never directly access first and second. **/ + T first{}; /** Users should never directly access 'first'. **/ + error_code second{UNINITIALIZED}; /** Users should never directly access 'second'. **/ +}; // struct implementation_simdjson_result_base + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H +/* end file simdjson/generic/implementation_simdjson_result_base.h for ppc64 */ +/* including simdjson/generic/numberparsing.h for ppc64: #include "simdjson/generic/numberparsing.h" */ +/* begin file simdjson/generic/numberparsing.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_NUMBERPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_NUMBERPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include +#include + +namespace simdjson { +namespace ppc64 { +namespace numberparsing { + +#ifdef JSON_TEST_NUMBERS +#define INVALID_NUMBER(SRC) (found_invalid_number((SRC)), NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (found_integer((VALUE), (SRC)), (WRITER).append_s64((VALUE))) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (found_unsigned_integer((VALUE), (SRC)), (WRITER).append_u64((VALUE))) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (found_float((VALUE), (SRC)), (WRITER).append_double((VALUE))) +#else +#define INVALID_NUMBER(SRC) (NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (WRITER).append_s64((VALUE)) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (WRITER).append_u64((VALUE)) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (WRITER).append_double((VALUE)) +#endif + +namespace { + +// Convert a mantissa, an exponent and a sign bit into an ieee64 double. +// The real_exponent needs to be in [0, 2046] (technically real_exponent = 2047 would be acceptable). +// The mantissa should be in [0,1<<53). The bit at index (1ULL << 52) while be zeroed. +simdjson_inline double to_double(uint64_t mantissa, uint64_t real_exponent, bool negative) { + double d; + mantissa &= ~(1ULL << 52); + mantissa |= real_exponent << 52; + mantissa |= ((static_cast(negative)) << 63); + std::memcpy(&d, &mantissa, sizeof(d)); + return d; +} + +// Attempts to compute i * 10^(power) exactly; and if "negative" is +// true, negate the result. +// This function will only work in some cases, when it does not work, success is +// set to false. This should work *most of the time* (like 99% of the time). +// We assume that power is in the [smallest_power, +// largest_power] interval: the caller is responsible for this check. +simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative, double &d) { + // we start with a fast path + // It was described in + // Clinger WD. How to read floating point numbers accurately. + // ACM SIGPLAN Notices. 1990 +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + // We cannot be certain that x/y is rounded to nearest. + if (0 <= power && power <= 22 && i <= 9007199254740991) +#else + if (-22 <= power && power <= 22 && i <= 9007199254740991) +#endif + { + // convert the integer into a double. This is lossless since + // 0 <= i <= 2^53 - 1. + d = double(i); + // + // The general idea is as follows. + // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then + // 1) Both s and p can be represented exactly as 64-bit floating-point + // values + // (binary64). + // 2) Because s and p can be represented exactly as floating-point values, + // then s * p + // and s / p will produce correctly rounded values. + // + if (power < 0) { + d = d / simdjson::internal::power_of_ten[-power]; + } else { + d = d * simdjson::internal::power_of_ten[power]; + } + if (negative) { + d = -d; + } + return true; + } + // When 22 < power && power < 22 + 16, we could + // hope for another, secondary fast path. It was + // described by David M. Gay in "Correctly rounded + // binary-decimal and decimal-binary conversions." (1990) + // If you need to compute i * 10^(22 + x) for x < 16, + // first compute i * 10^x, if you know that result is exact + // (e.g., when i * 10^x < 2^53), + // then you can still proceed and do (i * 10^x) * 10^22. + // Is this worth your time? + // You need 22 < power *and* power < 22 + 16 *and* (i * 10^(x-22) < 2^53) + // for this second fast path to work. + // If you you have 22 < power *and* power < 22 + 16, and then you + // optimistically compute "i * 10^(x-22)", there is still a chance that you + // have wasted your time if i * 10^(x-22) >= 2^53. It makes the use cases of + // this optimization maybe less common than we would like. Source: + // http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + // also used in RapidJSON: https://rapidjson.org/strtod_8h_source.html + + // The fast path has now failed, so we are failing back on the slower path. + + // In the slow path, we need to adjust i so that it is > 1<<63 which is always + // possible, except if i == 0, so we handle i == 0 separately. + if(i == 0) { + d = negative ? -0.0 : 0.0; + return true; + } + + + // The exponent is 1024 + 63 + power + // + floor(log(5**power)/log(2)). + // The 1024 comes from the ieee64 standard. + // The 63 comes from the fact that we use a 64-bit word. + // + // Computing floor(log(5**power)/log(2)) could be + // slow. Instead we use a fast function. + // + // For power in (-400,350), we have that + // (((152170 + 65536) * power ) >> 16); + // is equal to + // floor(log(5**power)/log(2)) + power when power >= 0 + // and it is equal to + // ceil(log(5**-power)/log(2)) + power when power < 0 + // + // The 65536 is (1<<16) and corresponds to + // (65536 * power) >> 16 ---> power + // + // ((152170 * power ) >> 16) is equal to + // floor(log(5**power)/log(2)) + // + // Note that this is not magic: 152170/(1<<16) is + // approximatively equal to log(5)/log(2). + // The 1<<16 value is a power of two; we could use a + // larger power of 2 if we wanted to. + // + int64_t exponent = (((152170 + 65536) * power) >> 16) + 1024 + 63; + + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(i); + i <<= lz; + + + // We are going to need to do some 64-bit arithmetic to get a precise product. + // We use a table lookup approach. + // It is safe because + // power >= smallest_power + // and power <= largest_power + // We recover the mantissa of the power, it has a leading 1. It is always + // rounded down. + // + // We want the most significant 64 bits of the product. We know + // this will be non-zero because the most significant bit of i is + // 1. + const uint32_t index = 2 * uint32_t(power - simdjson::internal::smallest_power); + // Optimization: It may be that materializing the index as a variable might confuse some compilers and prevent effective complex-addressing loads. (Done for code clarity.) + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); + // Both i and power_of_five_128[index] have their most significant bit set to 1 which + // implies that the either the most or the second most significant bit of the product + // is 1. We pack values in this manner for efficiency reasons: it maximizes the use + // we make of the product. It also makes it easy to reason about the product: there + // is 0 or 1 leading zero in the product. + + // Unless the least significant 9 bits of the high (64-bit) part of the full + // product are all 1s, then we know that the most significant 55 bits are + // exact and no further work is needed. Having 55 bits is necessary because + // we need 53 bits for the mantissa but we have to have one rounding bit and + // we can waste a bit if the most significant bit of the product is zero. + if((firstproduct.high & 0x1FF) == 0x1FF) { + // We want to compute i * 5^q, but only care about the top 55 bits at most. + // Consider the scenario where q>=0. Then 5^q may not fit in 64-bits. Doing + // the full computation is wasteful. So we do what is called a "truncated + // multiplication". + // We take the most significant 64-bits, and we put them in + // power_of_five_128[index]. Usually, that's good enough to approximate i * 5^q + // to the desired approximation using one multiplication. Sometimes it does not suffice. + // Then we store the next most significant 64 bits in power_of_five_128[index + 1], and + // then we get a better approximation to i * 5^q. + // + // That's for when q>=0. The logic for q<0 is somewhat similar but it is somewhat + // more complicated. + // + // There is an extra layer of complexity in that we need more than 55 bits of + // accuracy in the round-to-even scenario. + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if(secondproduct.high > firstproduct.low) { firstproduct.high++; } + // As it has been proven by Noble Mushtak and Daniel Lemire in "Fast Number Parsing Without + // Fallback" (https://arxiv.org/abs/2212.06644), at this point we are sure that the product + // is sufficiently accurate, and more computation is not needed. + } + uint64_t lower = firstproduct.low; + uint64_t upper = firstproduct.high; + // The final mantissa should be 53 bits with a leading 1. + // We shift it so that it occupies 54 bits with a leading 1. + /////// + uint64_t upperbit = upper >> 63; + uint64_t mantissa = upper >> (upperbit + 9); + lz += int(1 ^ upperbit); + + // Here we have mantissa < (1<<54). + int64_t real_exponent = exponent - lz; + if (simdjson_unlikely(real_exponent <= 0)) { // we have a subnormal? + // Here have that real_exponent <= 0 so -real_exponent >= 0 + if(-real_exponent + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure. + d = negative ? -0.0 : 0.0; + return true; + } + // next line is safe because -real_exponent + 1 < 0 + mantissa >>= -real_exponent + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0. + mantissa += (mantissa & 1); // round up + mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + real_exponent = (mantissa < (uint64_t(1) << 52)) ? 0 : 1; + d = to_double(mantissa, real_exponent, negative); + return true; + } + // We have to round to even. The "to even" part + // is only a problem when we are right in between two floats + // which we guard against. + // If we have lots of trailing zeros, we may fall right between two + // floating-point values. + // + // The round-to-even cases take the form of a number 2m+1 which is in (2^53,2^54] + // times a power of two. That is, it is right between a number with binary significand + // m and another number with binary significand m+1; and it must be the case + // that it cannot be represented by a float itself. + // + // We must have that w * 10 ^q == (2m+1) * 2^p for some power of two 2^p. + // Recall that 10^q = 5^q * 2^q. + // When q >= 0, we must have that (2m+1) is divible by 5^q, so 5^q <= 2^54. We have that + // 5^23 <= 2^54 and it is the last power of five to qualify, so q <= 23. + // When q<0, we have w >= (2m+1) x 5^{-q}. We must have that w<2^{64} so + // (2m+1) x 5^{-q} < 2^{64}. We have that 2m+1>2^{53}. Hence, we must have + // 2^{53} x 5^{-q} < 2^{64}. + // Hence we have 5^{-q} < 2^{11}$ or q>= -4. + // + // We require lower <= 1 and not lower == 0 because we could not prove that + // that lower == 0 is implied; but we could prove that lower <= 1 is a necessary and sufficient test. + if (simdjson_unlikely((lower <= 1) && (power >= -4) && (power <= 23) && ((mantissa & 3) == 1))) { + if((mantissa << (upperbit + 64 - 53 - 2)) == upper) { + mantissa &= ~1; // flip it so that we do not round up + } + } + + mantissa += mantissa & 1; + mantissa >>= 1; + + // Here we have mantissa < (1<<53), unless there was an overflow + if (mantissa >= (1ULL << 53)) { + ////////// + // This will happen when parsing values such as 7.2057594037927933e+16 + //////// + mantissa = (1ULL << 52); + real_exponent++; + } + mantissa &= ~(1ULL << 52); + // we have to check that real_exponent is in range, otherwise we bail out + if (simdjson_unlikely(real_exponent > 2046)) { + // We have an infinite value!!! We could actually throw an error here if we could. + return false; + } + d = to_double(mantissa, real_exponent, negative); + return true; +} + +// We call a fallback floating-point parser that might be slow. Note +// it will accept JSON numbers, but the JSON spec. is more restrictive so +// before you call parse_float_fallback, you need to have validated the input +// string with the JSON grammar. +// It will return an error (false) if the parsed number is infinite. +// The string parsing itself always succeeds. We know that there is at least +// one digit. +static bool parse_float_fallback(const uint8_t *ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +static bool parse_float_fallback(const uint8_t *ptr, const uint8_t *end_ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr), reinterpret_cast(end_ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +// check quickly whether the next 8 chars are made of digits +// at a glance, it looks better than Mula's +// http://0x80.pl/articles/swar-digits-validate.html +simdjson_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) { + uint64_t val; + // this can read up to 7 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(7 <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be bigger than 7"); + std::memcpy(&val, chars, 8); + // a branchy method might be faster: + // return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030) + // && (( (val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0 ) == + // 0x3030303030303030); + return (((val & 0xF0F0F0F0F0F0F0F0) | + (((val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4)) == + 0x3333333333333333); +} + +template +SIMDJSON_NO_SANITIZE_UNDEFINED // We deliberately allow overflow here and check later +simdjson_inline bool parse_digit(const uint8_t c, I &i) { + const uint8_t digit = static_cast(c - '0'); + if (digit > 9) { + return false; + } + // PERF NOTE: multiplication by 10 is cheaper than arbitrary integer multiplication + i = 10 * i + digit; // might overflow, we will handle the overflow later + return true; +} + +simdjson_inline error_code parse_decimal_after_separator(simdjson_unused const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) { + // we continue with the fiction that we have an integer. If the + // floating point number is representable as x * 10^z for some integer + // z that fits in 53 bits, then we will be able to convert back the + // the integer into a float in a lossless manner. + const uint8_t *const first_after_period = p; + +#ifdef SIMDJSON_SWAR_NUMBER_PARSING +#if SIMDJSON_SWAR_NUMBER_PARSING + // this helps if we have lots of decimals! + // this turns out to be frequent enough. + if (is_made_of_eight_digits_fast(p)) { + i = i * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + } +#endif // SIMDJSON_SWAR_NUMBER_PARSING +#endif // #ifdef SIMDJSON_SWAR_NUMBER_PARSING + // Unrolling the first digit makes a small difference on some implementations (e.g. westmere) + if (parse_digit(*p, i)) { ++p; } + while (parse_digit(*p, i)) { p++; } + exponent = first_after_period - p; + // Decimal without digits (123.) is illegal + if (exponent == 0) { + return INVALID_NUMBER(src); + } + return SUCCESS; +} + +simdjson_inline error_code parse_exponent(simdjson_unused const uint8_t *const src, const uint8_t *&p, int64_t &exponent) { + // Exp Sign: -123.456e[-]78 + bool neg_exp = ('-' == *p); + if (neg_exp || '+' == *p) { p++; } // Skip + as well + + // Exponent: -123.456e-[78] + auto start_exp = p; + int64_t exp_number = 0; + while (parse_digit(*p, exp_number)) { ++p; } + // It is possible for parse_digit to overflow. + // In particular, it could overflow to INT64_MIN, and we cannot do - INT64_MIN. + // Thus we *must* check for possible overflow before we negate exp_number. + + // Performance notes: it may seem like combining the two "simdjson_unlikely checks" below into + // a single simdjson_unlikely path would be faster. The reasoning is sound, but the compiler may + // not oblige and may, in fact, generate two distinct paths in any case. It might be + // possible to do uint64_t(p - start_exp - 1) >= 18 but it could end up trading off + // instructions for a simdjson_likely branch, an unconclusive gain. + + // If there were no digits, it's an error. + if (simdjson_unlikely(p == start_exp)) { + return INVALID_NUMBER(src); + } + // We have a valid positive exponent in exp_number at this point, except that + // it may have overflowed. + + // If there were more than 18 digits, we may have overflowed the integer. We have to do + // something!!!! + if (simdjson_unlikely(p > start_exp+18)) { + // Skip leading zeroes: 1e000000000000000000001 is technically valid and doesn't overflow + while (*start_exp == '0') { start_exp++; } + // 19 digits could overflow int64_t and is kind of absurd anyway. We don't + // support exponents smaller than -999,999,999,999,999,999 and bigger + // than 999,999,999,999,999,999. + // We can truncate. + // Note that 999999999999999999 is assuredly too large. The maximal ieee64 value before + // infinity is ~1.8e308. The smallest subnormal is ~5e-324. So, actually, we could + // truncate at 324. + // Note that there is no reason to fail per se at this point in time. + // E.g., 0e999999999999999999999 is a fine number. + if (p > start_exp+18) { exp_number = 999999999999999999; } + } + // At this point, we know that exp_number is a sane, positive, signed integer. + // It is <= 999,999,999,999,999,999. As long as 'exponent' is in + // [-8223372036854775808, 8223372036854775808], we won't overflow. Because 'exponent' + // is bounded in magnitude by the size of the JSON input, we are fine in this universe. + // To sum it up: the next line should never overflow. + exponent += (neg_exp ? -exp_number : exp_number); + return SUCCESS; +} + +simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t digit_count) { + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + const uint8_t *start = start_digits; + while ((*start == '0') || (*start == '.')) { ++start; } + // we over-decrement by one when there is a '.' + return digit_count - size_t(start - start_digits); +} + +} // unnamed namespace + +/** @private */ +static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) { + if (parse_float_fallback(src, answer)) { + return SUCCESS; + } + return INVALID_NUMBER(src); +} + +/** @private */ +template +simdjson_inline error_code write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer) { + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon in practice. + // + // 9999999999999999999 < 2**64 so we can accommodate 19 digits. + // If we have a decimal separator, then digit_count - 1 is the number of digits, but we + // may not have a decimal separator! + if (simdjson_unlikely(digit_count > 19 && significant_digits(start_digits, digit_count) > 19)) { + // Ok, chances are good that we had an overflow! + // this is almost never going to get called!!! + // we start anew, going slowly!!! + // This will happen in the following examples: + // 10000000000000000000000000000000000000000000e+308 + // 3.1415926535897932384626433832795028841971693993751 + // + // NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer + // reference to it, it would force it to be stored in memory, preventing the compiler from + // picking it apart and putting into registers. i.e. if we pass it as reference, + // it gets slow. + double d; + error_code error = slow_float_parsing(src, &d); + writer.append_double(d); + return error; + } + // NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other + // way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331 + // To future reader: we'd love if someone found a better way, or at least could explain this result! + if (simdjson_unlikely(exponent < simdjson::internal::smallest_power) || (exponent > simdjson::internal::largest_power)) { + // + // Important: smallest_power is such that it leads to a zero value. + // Observe that 18446744073709551615e-343 == 0, i.e. (2**64 - 1) e -343 is zero + // so something x 10^-343 goes to zero, but not so with something x 10^-342. + static_assert(simdjson::internal::smallest_power <= -342, "smallest_power is not small enough"); + // + if((exponent < simdjson::internal::smallest_power) || (i == 0)) { + // E.g. Parse "-0.0e-999" into the same value as "-0.0". See https://en.wikipedia.org/wiki/Signed_zero + WRITE_DOUBLE(negative ? -0.0 : 0.0, src, writer); + return SUCCESS; + } else { // (exponent > largest_power) and (i != 0) + // We have, for sure, an infinite value and simdjson refuses to parse infinite values. + return INVALID_NUMBER(src); + } + } + double d; + if (!compute_float_64(exponent, i, negative, d)) { + // we are almost never going to get here. + if (!parse_float_fallback(src, &d)) { return INVALID_NUMBER(src); } + } + WRITE_DOUBLE(d, src, writer); + return SUCCESS; +} + +// for performance analysis, it is sometimes useful to skip parsing +#ifdef SIMDJSON_SKIPNUMBERPARSING + +template +simdjson_inline error_code parse_number(const uint8_t *const, W &writer) { + writer.append_s64(0); // always write zero + return SUCCESS; // always succeeds +} + +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { return number_type::signed_integer; } +#else + +// parse the number at src +// define JSON_TEST_NUMBERS for unit testing +// +// It is assumed that the number is followed by a structural ({,},],[) character +// or a white space character. If that is not the case (e.g., when the JSON +// document is made of a single number), then it is necessary to copy the +// content and append a space before calling this function. +// +// Our objective is accurate parsing (ULP of 0) at high speed. +template +simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) { + + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + if (digit_count == 0 || ('0' == *start_digits && digit_count > 1)) { return INVALID_NUMBER(src); } + + // + // Handle floats if there is a . or e (or both) + // + int64_t exponent = 0; + bool is_float = false; + if ('.' == *p) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) ); + digit_count = int(p - start_digits); // used later to guard against overflows + } + if (('e' == *p) || ('E' == *p)) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_exponent(src, p, exponent) ); + } + if (is_float) { + const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p); + SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) ); + if (dirty_end) { return INVALID_NUMBER(src); } + return SUCCESS; + } + + // The longest negative 64-bit number is 19 digits. + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + size_t longest_digit_count = negative ? 19 : 20; + if (digit_count > longest_digit_count) { return INVALID_NUMBER(src); } + if (digit_count == longest_digit_count) { + if (negative) { + // Anything negative above INT64_MAX+1 is invalid + if (i > uint64_t(INT64_MAX)+1) { return INVALID_NUMBER(src); } + WRITE_INTEGER(~i+1, src, writer); + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + } else if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INVALID_NUMBER(src); } + } + + // Write unsigned if it doesn't fit in a signed integer. + if (i > uint64_t(INT64_MAX)) { + WRITE_UNSIGNED(i, src, writer); + } else { + WRITE_INTEGER(negative ? (~i+1) : i, src, writer); + } + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; +} + +// Inlineable functions +namespace { + +// This table can be used to characterize the final character of an integer +// string. For JSON structural character and allowable white space characters, +// we return SUCCESS. For 'e', '.' and 'E', we return INCORRECT_TYPE. Otherwise +// we return NUMBER_ERROR. +// Optimization note: we could easily reduce the size of the table by half (to 128) +// at the cost of an extra branch. +// Optimization note: we want the values to use at most 8 bits (not, e.g., 32 bits): +static_assert(error_code(uint8_t(NUMBER_ERROR))== NUMBER_ERROR, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(SUCCESS))== SUCCESS, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(INCORRECT_TYPE))== INCORRECT_TYPE, "bad NUMBER_ERROR cast"); + +const uint8_t integer_string_finisher[256] = { + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, INCORRECT_TYPE, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, SUCCESS, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR}; + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + + +// Parse any number from 0 to 18,446,744,073,709,551,615 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src, const uint8_t * const src_end) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if ((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { + const uint8_t *p = src + 1; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (*p != '"') { return NUMBER_ERROR; } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + // Note: we use src[1] and not src[0] because src[0] is the quote character in this + // instance. + if (src[1] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src, const uint8_t * const src_end) noexcept { + // + // Check for minus sign + // + if(src == src_end) { return NUMBER_ERROR; } + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = src; + uint64_t i = 0; + while (parse_digit(*src, i)) { src++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(src - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*src)) { + // return (*src == '.' || *src == 'e' || *src == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(*src != '"') { return NUMBER_ERROR; } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { + return (*src == '-'); +} + +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { return true; } + return false; +} + +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { + // We have an integer. + // If the number is negative and valid, it must be a signed integer. + if(negative) { return number_type::signed_integer; } + // We want values larger or equal to 9223372036854775808 to be unsigned + // integers, and the other values to be signed integers. + int digit_count = int(p - src); + if(digit_count >= 19) { + const uint8_t * smaller_big_integer = reinterpret_cast("9223372036854775808"); + if((digit_count >= 20) || (memcmp(src, smaller_big_integer, 19) >= 0)) { + return number_type::unsigned_integer; + } + } + return number_type::signed_integer; + } + // Hopefully, we have 'e' or 'E' or '.'. + return number_type::floating_point_number; +} + +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src, const uint8_t * const src_end) noexcept { + if(src == src_end) { return NUMBER_ERROR; } + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + if(p == src_end) { return NUMBER_ERROR; } + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while ((p != src_end) && parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely((p != src_end) && (*p == '.'))) { + p++; + const uint8_t *start_decimal_digits = p; + if ((p == src_end) || !parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = start_digits-src > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if ((p != src_end) && (*p == 'e' || *p == 'E')) { + p++; + if(p == src_end) { return NUMBER_ERROR; } + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while ((p != src_end) && parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (*p != '"') { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +} // unnamed namespace +#endif // SIMDJSON_SKIPNUMBERPARSING + +} // namespace numberparsing + +inline std::ostream& operator<<(std::ostream& out, number_type type) noexcept { + switch (type) { + case number_type::signed_integer: out << "integer in [-9223372036854775808,9223372036854775808)"; break; + case number_type::unsigned_integer: out << "unsigned integer in [9223372036854775808,18446744073709551616)"; break; + case number_type::floating_point_number: out << "floating-point number (binary64)"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_NUMBERPARSING_H +/* end file simdjson/generic/numberparsing.h for ppc64 */ + +/* including simdjson/generic/implementation_simdjson_result_base-inl.h for ppc64: #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { + +// +// internal::implementation_simdjson_result_base inline implementation +// + +template +simdjson_inline void implementation_simdjson_result_base::tie(T &value, error_code &error) && noexcept { + error = this->second; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +simdjson_warn_unused simdjson_inline error_code implementation_simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; +} + +template +simdjson_inline error_code implementation_simdjson_result_base::error() const noexcept { + return this->second; +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& implementation_simdjson_result_base::value() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline T&& implementation_simdjson_result_base::take_value() && noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& implementation_simdjson_result_base::value_unsafe() const& noexcept { + return this->first; +} + +template +simdjson_inline T& implementation_simdjson_result_base::value_unsafe() & noexcept { + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value_unsafe() && noexcept { + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value, error_code error) noexcept + : first{std::forward(value)}, second{error} {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(error_code error) noexcept + : implementation_simdjson_result_base(T{}, error) {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value) noexcept + : implementation_simdjson_result_base(std::forward(value), SUCCESS) {} + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H +/* end file simdjson/generic/implementation_simdjson_result_base-inl.h for ppc64 */ +/* end file simdjson/generic/amalgamated.h for ppc64 */ +/* including simdjson/ppc64/end.h: #include "simdjson/ppc64/end.h" */ +/* begin file simdjson/ppc64/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#undef SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT +/* undefining SIMDJSON_IMPLEMENTATION from "ppc64" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/ppc64/end.h */ + +#endif // SIMDJSON_PPC64_H +/* end file simdjson/ppc64.h */ +/* including simdjson/ppc64/implementation.h: #include */ +/* begin file simdjson/ppc64/implementation.h */ +#ifndef SIMDJSON_PPC64_IMPLEMENTATION_H +#define SIMDJSON_PPC64_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +/** + * Implementation for ALTIVEC (PPC64). + */ +namespace ppc64 { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() + : simdjson::implementation("ppc64", "PPC64 ALTIVEC", + internal::instruction_set::ALTIVEC) {} + + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, size_t max_length, + std::unique_ptr &dst) + const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, + uint8_t *dst, + size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, + size_t len) const noexcept final; +}; + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_IMPLEMENTATION_H +/* end file simdjson/ppc64/implementation.h */ + +/* including simdjson/ppc64/begin.h: #include */ +/* begin file simdjson/ppc64/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "ppc64" */ +#define SIMDJSON_IMPLEMENTATION ppc64 +/* including simdjson/ppc64/base.h: #include "simdjson/ppc64/base.h" */ +/* begin file simdjson/ppc64/base.h */ +#ifndef SIMDJSON_PPC64_BASE_H +#define SIMDJSON_PPC64_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Implementation for ALTIVEC (PPC64). + */ +namespace ppc64 { + +class implementation; + +namespace { +namespace simd { +template struct simd8; +template struct simd8x64; +} // namespace simd +} // unnamed namespace + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_BASE_H +/* end file simdjson/ppc64/base.h */ +/* including simdjson/ppc64/intrinsics.h: #include "simdjson/ppc64/intrinsics.h" */ +/* begin file simdjson/ppc64/intrinsics.h */ +#ifndef SIMDJSON_PPC64_INTRINSICS_H +#define SIMDJSON_PPC64_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This should be the correct header whether +// you use visual studio or other compilers. +#include + +// These are defined by altivec.h in GCC toolchain, it is safe to undef them. +#ifdef bool +#undef bool +#endif + +#ifdef vector +#undef vector +#endif + +static_assert(sizeof(__vector unsigned char) <= simdjson::SIMDJSON_PADDING, "insufficient padding for ppc64"); + +#endif // SIMDJSON_PPC64_INTRINSICS_H +/* end file simdjson/ppc64/intrinsics.h */ +/* including simdjson/ppc64/bitmanipulation.h: #include "simdjson/ppc64/bitmanipulation.h" */ +/* begin file simdjson/ppc64/bitmanipulation.h */ +#ifndef SIMDJSON_PPC64_BITMANIPULATION_H +#define SIMDJSON_PPC64_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num - 1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline int count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num); // Visual Studio wants two underscores +} +#else +simdjson_inline int count_ones(uint64_t input_num) { + return __builtin_popcountll(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + *result = value1 + value2; + return *result < value1; +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_BITMANIPULATION_H +/* end file simdjson/ppc64/bitmanipulation.h */ +/* including simdjson/ppc64/bitmask.h: #include "simdjson/ppc64/bitmask.h" */ +/* begin file simdjson/ppc64/bitmask.h */ +#ifndef SIMDJSON_PPC64_BITMASK_H +#define SIMDJSON_PPC64_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is +// encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(uint64_t bitmask) { + // You can use the version below, however gcc sometimes miscompiles + // vec_pmsum_be, it happens somewhere around between 8 and 9th version. + // The performance boost was not noticeable, falling back to a usual + // implementation. + // __vector unsigned long long all_ones = {~0ull, ~0ull}; + // __vector unsigned long long mask = {bitmask, 0}; + // // Clang and GCC return different values for pmsum for ull so cast it to one. + // // Generally it is not specified by ALTIVEC ISA what is returned by + // // vec_pmsum_be. + // #if defined(__LITTLE_ENDIAN__) + // return (uint64_t)(((__vector unsigned long long)vec_pmsum_be(all_ones, mask))[0]); + // #else + // return (uint64_t)(((__vector unsigned long long)vec_pmsum_be(all_ones, mask))[1]); + // #endif + bitmask ^= bitmask << 1; + bitmask ^= bitmask << 2; + bitmask ^= bitmask << 4; + bitmask ^= bitmask << 8; + bitmask ^= bitmask << 16; + bitmask ^= bitmask << 32; + return bitmask; +} + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif +/* end file simdjson/ppc64/bitmask.h */ +/* including simdjson/ppc64/numberparsing_defs.h: #include "simdjson/ppc64/numberparsing_defs.h" */ +/* begin file simdjson/ppc64/numberparsing_defs.h */ +#ifndef SIMDJSON_PPC64_NUMBERPARSING_DEFS_H +#define SIMDJSON_PPC64_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +#if defined(__linux__) +#include +#elif defined(__FreeBSD__) +#include +#endif + +namespace simdjson { +namespace ppc64 { +namespace numberparsing { + +// we don't have appropriate instructions, so let us use a scalar function +// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + uint64_t val; + std::memcpy(&val, chars, sizeof(uint64_t)); +#ifdef __BIG_ENDIAN__ +#if defined(__linux__) + val = bswap_64(val); +#elif defined(__FreeBSD__) + val = bswap64(val); +#endif +#endif + val = (val & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8; + val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16; + return uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32); +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace ppc64 +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_PPC64_NUMBERPARSING_DEFS_H +/* end file simdjson/ppc64/numberparsing_defs.h */ +/* including simdjson/ppc64/simd.h: #include "simdjson/ppc64/simd.h" */ +/* begin file simdjson/ppc64/simd.h */ +#ifndef SIMDJSON_PPC64_SIMD_H +#define SIMDJSON_PPC64_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace ppc64 { +namespace { +namespace simd { + +using __m128i = __vector unsigned char; + +template struct base { + __m128i value; + + // Zero constructor + simdjson_inline base() : value{__m128i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m128i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m128i &() const { + return this->value; + } + simdjson_inline operator __m128i &() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { + return vec_or(this->value, (__m128i)other); + } + simdjson_inline Child operator&(const Child other) const { + return vec_and(this->value, (__m128i)other); + } + simdjson_inline Child operator^(const Child other) const { + return vec_xor(this->value, (__m128i)other); + } + simdjson_inline Child bit_andnot(const Child other) const { + return vec_andc(this->value, (__m128i)other); + } + simdjson_inline Child &operator|=(const Child other) { + auto this_cast = static_cast(this); + *this_cast = *this_cast | other; + return *this_cast; + } + simdjson_inline Child &operator&=(const Child other) { + auto this_cast = static_cast(this); + *this_cast = *this_cast & other; + return *this_cast; + } + simdjson_inline Child &operator^=(const Child other) { + auto this_cast = static_cast(this); + *this_cast = *this_cast ^ other; + return *this_cast; + } +}; + +template > +struct base8 : base> { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m128i _value) : base>(_value) {} + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { + return (__m128i)vec_cmpeq(lhs.value, (__m128i)rhs); + } + + static const int SIZE = sizeof(base>::value); + + template + simdjson_inline simd8 prev(simd8 prev_chunk) const { + __m128i chunk = this->value; +#ifdef __LITTLE_ENDIAN__ + chunk = (__m128i)vec_reve(this->value); + prev_chunk = (__m128i)vec_reve((__m128i)prev_chunk); +#endif + chunk = (__m128i)vec_sld((__m128i)prev_chunk, (__m128i)chunk, 16 - N); +#ifdef __LITTLE_ENDIAN__ + chunk = (__m128i)vec_reve((__m128i)chunk); +#endif + return chunk; + } +}; + +// SIMD byte mask type (returned by things like eq and gt) +template <> struct simd8 : base8 { + static simdjson_inline simd8 splat(bool _value) { + return (__m128i)vec_splats((unsigned char)(-(!!_value))); + } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m128i _value) + : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) + : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { + __vector unsigned long long result; + const __m128i perm_mask = {0x78, 0x70, 0x68, 0x60, 0x58, 0x50, 0x48, 0x40, + 0x38, 0x30, 0x28, 0x20, 0x18, 0x10, 0x08, 0x00}; + + result = ((__vector unsigned long long)vec_vbpermq((__m128i)this->value, + (__m128i)perm_mask)); +#ifdef __LITTLE_ENDIAN__ + return static_cast(result[1]); +#else + return static_cast(result[0]); +#endif + } + simdjson_inline bool any() const { + return !vec_all_eq(this->value, (__m128i)vec_splats(0)); + } + simdjson_inline simd8 operator~() const { + return this->value ^ (__m128i)splat(true); + } +}; + +template struct base8_numeric : base8 { + static simdjson_inline simd8 splat(T value) { + (void)value; + return (__m128i)vec_splats(value); + } + static simdjson_inline simd8 zero() { return splat(0); } + static simdjson_inline simd8 load(const T values[16]) { + return (__m128i)(vec_vsx_ld(0, reinterpret_cast(values))); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16(T v0, T v1, T v2, T v3, T v4, + T v5, T v6, T v7, T v8, T v9, + T v10, T v11, T v12, T v13, + T v14, T v15) { + return simd8(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m128i _value) + : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[16]) const { + vec_vsx_st(this->value, 0, reinterpret_cast<__m128i *>(dst)); + } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { + return (__m128i)((__m128i)this->value + (__m128i)other); + } + simdjson_inline simd8 operator-(const simd8 other) const { + return (__m128i)((__m128i)this->value - (__m128i)other); + } + simdjson_inline simd8 &operator+=(const simd8 other) { + *this = *this + other; + return *static_cast *>(this); + } + simdjson_inline simd8 &operator-=(const simd8 other) { + *this = *this - other; + return *static_cast *>(this); + } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior + // for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return (__m128i)vec_perm((__m128i)lookup_table, (__m128i)lookup_table, this->value); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted + // as a bitset). Passing a 0 value for mask would be equivalent to writing out + // every byte to output. Only the first 16 - count_ones(mask) bytes of the + // result are significant but 16 bytes get written. Design consideration: it + // seems like a function with the signature simd8 compress(uint32_t mask) + // would be sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L *output) const { + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + using internal::thintable_epi8; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. +#ifdef __LITTLE_ENDIAN__ + __m128i shufmask = (__m128i)(__vector unsigned long long){ + thintable_epi8[mask1], thintable_epi8[mask2]}; +#else + __m128i shufmask = (__m128i)(__vector unsigned long long){ + thintable_epi8[mask2], thintable_epi8[mask1]}; + shufmask = (__m128i)vec_reve((__m128i)shufmask); +#endif + // we increment by 0x08 the second half of the mask + shufmask = ((__m128i)shufmask) + + ((__m128i)(__vector int){0, 0, 0x08080808, 0x08080808}); + + // this is the version "nearly pruned" + __m128i pruned = vec_perm(this->value, this->value, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + __m128i compactmask = + vec_vsx_ld(0, reinterpret_cast(pshufb_combine_table + pop1 * 8)); + __m128i answer = vec_perm(pruned, (__m128i)vec_splats(0), compactmask); + vec_vsx_st(answer, 0, reinterpret_cast<__m128i *>(output)); + } + + template + simdjson_inline simd8 + lookup_16(L replace0, L replace1, L replace2, L replace3, L replace4, + L replace5, L replace6, L replace7, L replace8, L replace9, + L replace10, L replace11, L replace12, L replace13, L replace14, + L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, replace4, replace5, replace6, + replace7, replace8, replace9, replace10, replace11, replace12, + replace13, replace14, replace15)); + } +}; + +// Signed bytes +template <> struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) + : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t *values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8(int8_t v0, int8_t v1, int8_t v2, int8_t v3, + int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, + int8_t v12, int8_t v13, int8_t v14, int8_t v15) + : simd8((__m128i)(__vector signed char){v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, + v15}) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 + repeat_16(int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, + int8_t v6, int8_t v7, int8_t v8, int8_t v9, int8_t v10, int8_t v11, + int8_t v12, int8_t v13, int8_t v14, int8_t v15) { + return simd8(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); + } + + // Order-sensitive comparisons + simdjson_inline simd8 + max_val(const simd8 other) const { + return (__m128i)vec_max((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } + simdjson_inline simd8 + min_val(const simd8 other) const { + return (__m128i)vec_min((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } + simdjson_inline simd8 + operator>(const simd8 other) const { + return (__m128i)vec_cmpgt((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } + simdjson_inline simd8 + operator<(const simd8 other) const { + return (__m128i)vec_cmplt((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } +}; + +// Unsigned bytes +template <> struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) + : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t *values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline + simd8(uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, + uint8_t v6, uint8_t v7, uint8_t v8, uint8_t v9, uint8_t v10, + uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15) + : simd8((__m128i){v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15}) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 + repeat_16(uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, + uint8_t v5, uint8_t v6, uint8_t v7, uint8_t v8, uint8_t v9, + uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, + uint8_t v15) { + return simd8(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); + } + + // Saturated math + simdjson_inline simd8 + saturating_add(const simd8 other) const { + return (__m128i)vec_adds(this->value, (__m128i)other); + } + simdjson_inline simd8 + saturating_sub(const simd8 other) const { + return (__m128i)vec_subs(this->value, (__m128i)other); + } + + // Order-specific operations + simdjson_inline simd8 + max_val(const simd8 other) const { + return (__m128i)vec_max(this->value, (__m128i)other); + } + simdjson_inline simd8 + min_val(const simd8 other) const { + return (__m128i)vec_min(this->value, (__m128i)other); + } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 + gt_bits(const simd8 other) const { + return this->saturating_sub(other); + } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 + lt_bits(const simd8 other) const { + return other.saturating_sub(*this); + } + simdjson_inline simd8 + operator<=(const simd8 other) const { + return other.max_val(*this) == other; + } + simdjson_inline simd8 + operator>=(const simd8 other) const { + return other.min_val(*this) == other; + } + simdjson_inline simd8 + operator>(const simd8 other) const { + return this->gt_bits(other).any_bits_set(); + } + simdjson_inline simd8 + operator<(const simd8 other) const { + return this->gt_bits(other).any_bits_set(); + } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { + return (__m128i)vec_cmpeq(this->value, (__m128i)vec_splats(uint8_t(0))); + } + simdjson_inline simd8 bits_not_set(simd8 bits) const { + return (*this & bits).bits_not_set(); + } + simdjson_inline simd8 any_bits_set() const { + return ~this->bits_not_set(); + } + simdjson_inline simd8 any_bits_set(simd8 bits) const { + return ~this->bits_not_set(bits); + } + simdjson_inline bool bits_not_set_anywhere() const { + return vec_all_eq(this->value, (__m128i)vec_splats(0)); + } + simdjson_inline bool any_bits_set_anywhere() const { + return !bits_not_set_anywhere(); + } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { + return vec_all_eq(vec_and(this->value, (__m128i)bits), + (__m128i)vec_splats(0)); + } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { + return !bits_not_set_anywhere(bits); + } + template simdjson_inline simd8 shr() const { + return simd8( + (__m128i)vec_sr(this->value, (__m128i)vec_splat_u8(N))); + } + template simdjson_inline simd8 shl() const { + return simd8( + (__m128i)vec_sl(this->value, (__m128i)vec_splat_u8(N))); + } +}; + +template struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, + "PPC64 kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64 &o) = delete; // no copy allowed + simd8x64 & + operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, + const simd8 chunk2, const simd8 chunk3) + : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) + : chunks{simd8::load(ptr), simd8::load(ptr + 16), + simd8::load(ptr + 32), simd8::load(ptr + 48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr + sizeof(simd8) * 0); + this->chunks[1].store(ptr + sizeof(simd8) * 1); + this->chunks[2].store(ptr + sizeof(simd8) * 2); + this->chunks[3].store(ptr + sizeof(simd8) * 3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | + (this->chunks[2] | this->chunks[3]); + } + + simdjson_inline uint64_t compress(uint64_t mask, T *output) const { + this->chunks[0].compress(uint16_t(mask), output); + this->chunks[1].compress(uint16_t(mask >> 16), + output + 16 - count_ones(mask & 0xFFFF)); + this->chunks[2].compress(uint16_t(mask >> 32), + output + 32 - count_ones(mask & 0xFFFFFFFF)); + this->chunks[3].compress(uint16_t(mask >> 48), + output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); + return 64 - count_ones(mask); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r0 = uint32_t(this->chunks[0].to_bitmask()); + uint64_t r1 = this->chunks[1].to_bitmask(); + uint64_t r2 = this->chunks[2].to_bitmask(); + uint64_t r3 = this->chunks[3].to_bitmask(); + return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64(this->chunks[0] == mask, this->chunks[1] == mask, + this->chunks[2] == mask, this->chunks[3] == mask) + .to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64(this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1], + this->chunks[2] == other.chunks[2], + this->chunks[3] == other.chunks[3]) + .to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64(this->chunks[0] <= mask, this->chunks[1] <= mask, + this->chunks[2] <= mask, this->chunks[3] <= mask) + .to_bitmask(); + } +}; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_SIMD_INPUT_H +/* end file simdjson/ppc64/simd.h */ +/* including simdjson/ppc64/stringparsing_defs.h: #include "simdjson/ppc64/stringparsing_defs.h" */ +/* begin file simdjson/ppc64/stringparsing_defs.h */ +#ifndef SIMDJSON_PPC64_STRINGPARSING_DEFS_H +#define SIMDJSON_PPC64_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/simd.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote + copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { + return ((bs_bits - 1) & quote_bits) != 0; + } + simdjson_inline bool has_backslash() { return bs_bits != 0; } + simdjson_inline int quote_index() { + return trailing_zeroes(quote_bits); + } + simdjson_inline int backslash_index() { + return trailing_zeroes(bs_bits); + } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote +backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 31 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), + "backslash and quote finder must process fewer than " + "SIMDJSON_PADDING bytes"); + simd8 v0(src); + simd8 v1(src + sizeof(v0)); + v0.store(dst); + v1.store(dst + sizeof(v0)); + + // Getting a 64-bit bitmask is much cheaper than multiple 16-bit bitmasks on + // PPC; therefore, we smash them together into a 64-byte mask and get the + // bitmask from there. + uint64_t bs_and_quote = + simd8x64(v0 == '\\', v1 == '\\', v0 == '"', v1 == '"').to_bitmask(); + return { + uint32_t(bs_and_quote), // bs_bits + uint32_t(bs_and_quote >> 32) // quote_bits + }; +} + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_STRINGPARSING_DEFS_H +/* end file simdjson/ppc64/stringparsing_defs.h */ + +#define SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT 1 +/* end file simdjson/ppc64/begin.h */ +/* including generic/amalgamated.h for ppc64: #include */ +/* begin file generic/amalgamated.h for ppc64 */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_SRC_GENERIC_DEPENDENCIES_H) +#error generic/dependencies.h must be included before generic/amalgamated.h! +#endif + +/* including generic/base.h for ppc64: #include */ +/* begin file generic/base.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { + +struct json_character_block; + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_BASE_H +/* end file generic/base.h for ppc64 */ +/* including generic/dom_parser_implementation.h for ppc64: #include */ +/* begin file generic/dom_parser_implementation.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// Interface a dom parser implementation must fulfill +namespace simdjson { +namespace ppc64 { +namespace { + +simdjson_inline simd8 must_be_2_3_continuation(const simd8 prev2, const simd8 prev3); +simdjson_inline bool is_ascii(const simd8x64& input); + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file generic/dom_parser_implementation.h for ppc64 */ +/* including generic/json_character_block.h for ppc64: #include */ +/* begin file generic/json_character_block.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { + +struct json_character_block { + static simdjson_inline json_character_block classify(const simd::simd8x64& in); + + simdjson_inline uint64_t whitespace() const noexcept { return _whitespace; } + simdjson_inline uint64_t op() const noexcept { return _op; } + simdjson_inline uint64_t scalar() const noexcept { return ~(op() | whitespace()); } + + uint64_t _whitespace; + uint64_t _op; +}; + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H +/* end file generic/json_character_block.h for ppc64 */ +/* end file generic/amalgamated.h for ppc64 */ +/* including generic/stage1/amalgamated.h for ppc64: #include */ +/* begin file generic/stage1/amalgamated.h for ppc64 */ +// Stuff other things depend on +/* including generic/stage1/base.h for ppc64: #include */ +/* begin file generic/stage1/base.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { +namespace stage1 { + +class bit_indexer; +template +struct buf_block_reader; +struct json_block; +class json_minifier; +class json_scanner; +struct json_string_block; +class json_string_scanner; +class json_structural_indexer; + +} // namespace stage1 + +namespace utf8_validation { +struct utf8_checker; +} // namespace utf8_validation + +using utf8_validation::utf8_checker; + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_BASE_H +/* end file generic/stage1/base.h for ppc64 */ +/* including generic/stage1/buf_block_reader.h for ppc64: #include */ +/* begin file generic/stage1/buf_block_reader.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace ppc64 { +namespace { +namespace stage1 { + +// Walks through a buffer in block-sized increments, loading the last part with spaces +template +struct buf_block_reader { +public: + simdjson_inline buf_block_reader(const uint8_t *_buf, size_t _len); + simdjson_inline size_t block_index(); + simdjson_inline bool has_full_block() const; + simdjson_inline const uint8_t *full_block() const; + /** + * Get the last block, padded with spaces. + * + * There will always be a last block, with at least 1 byte, unless len == 0 (in which case this + * function fills the buffer with spaces and returns 0. In particular, if len == STEP_SIZE there + * will be 0 full_blocks and 1 remainder block with STEP_SIZE bytes and no spaces for padding. + * + * @return the number of effective characters in the last block. + */ + simdjson_inline size_t get_remainder(uint8_t *dst) const; + simdjson_inline void advance(); +private: + const uint8_t *buf; + const size_t len; + const size_t lenminusstep; + size_t idx; +}; + +// Routines to print masks and text for debugging bitmask operations +simdjson_unused static char * format_input_text_64(const uint8_t *text) { + static char buf[sizeof(simd8x64) + 1]; + for (size_t i=0; i); i++) { + buf[i] = int8_t(text[i]) < ' ' ? '_' : int8_t(text[i]); + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +// Routines to print masks and text for debugging bitmask operations +simdjson_unused static char * format_input_text(const simd8x64& in) { + static char buf[sizeof(simd8x64) + 1]; + in.store(reinterpret_cast(buf)); + for (size_t i=0; i); i++) { + if (buf[i] < ' ') { buf[i] = '_'; } + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +simdjson_unused static char * format_input_text(const simd8x64& in, uint64_t mask) { + static char buf[sizeof(simd8x64) + 1]; + in.store(reinterpret_cast(buf)); + for (size_t i=0; i); i++) { + if (buf[i] <= ' ') { buf[i] = '_'; } + if (!(mask & (size_t(1) << i))) { buf[i] = ' '; } + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +simdjson_unused static char * format_mask(uint64_t mask) { + static char buf[sizeof(simd8x64) + 1]; + for (size_t i=0; i<64; i++) { + buf[i] = (mask & (size_t(1) << i)) ? 'X' : ' '; + } + buf[64] = '\0'; + return buf; +} + +template +simdjson_inline buf_block_reader::buf_block_reader(const uint8_t *_buf, size_t _len) : buf{_buf}, len{_len}, lenminusstep{len < STEP_SIZE ? 0 : len - STEP_SIZE}, idx{0} {} + +template +simdjson_inline size_t buf_block_reader::block_index() { return idx; } + +template +simdjson_inline bool buf_block_reader::has_full_block() const { + return idx < lenminusstep; +} + +template +simdjson_inline const uint8_t *buf_block_reader::full_block() const { + return &buf[idx]; +} + +template +simdjson_inline size_t buf_block_reader::get_remainder(uint8_t *dst) const { + if(len == idx) { return 0; } // memcpy(dst, null, 0) will trigger an error with some sanitizers + std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it's more efficient to write out 8 or 16 bytes at once. + std::memcpy(dst, buf + idx, len - idx); + return len - idx; +} + +template +simdjson_inline void buf_block_reader::advance() { + idx += STEP_SIZE; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H +/* end file generic/stage1/buf_block_reader.h for ppc64 */ +/* including generic/stage1/json_escape_scanner.h for ppc64: #include */ +/* begin file generic/stage1/json_escape_scanner.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_ESCAPE_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_ESCAPE_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { +namespace stage1 { + +/** + * Scans for escape characters in JSON, taking care with multiple backslashes (\\n vs. \n). + */ +struct json_escape_scanner { + /** The actual escape characters (the backslashes themselves). */ + uint64_t next_is_escaped = 0ULL; + + struct escaped_and_escape { + /** + * Mask of escaped characters. + * + * ``` + * \n \\n \\\n \\\\n \ + * 0100100010100101000 + * n \ \ n \ \ + * ``` + */ + uint64_t escaped; + /** + * Mask of escape characters. + * + * ``` + * \n \\n \\\n \\\\n \ + * 1001000101001010001 + * \ \ \ \ \ \ \ + * ``` + */ + uint64_t escape; + }; + + /** + * Get a mask of both escape and escaped characters (the characters following a backslash). + * + * @param potential_escape A mask of the character that can escape others (but could be + * escaped itself). e.g. block.eq('\\') + */ + simdjson_really_inline escaped_and_escape next(uint64_t backslash) noexcept { + +#if !SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT + if (!backslash) { return {next_escaped_without_backslashes(), 0}; } +#endif + + // | | Mask (shows characters instead of 1's) | Depth | Instructions | + // |--------------------------------|----------------------------------------|-------|---------------------| + // | string | `\\n_\\\n___\\\n___\\\\___\\\\__\\\` | | | + // | | ` even odd even odd odd` | | | + // | potential_escape | ` \ \\\ \\\ \\\\ \\\\ \\\` | 1 | 1 (backslash & ~first_is_escaped) + // | escape_and_terminal_code | ` \n \ \n \ \n \ \ \ \ \ \` | 5 | 5 (next_escape_and_terminal_code()) + // | escaped | `\ \ n \ n \ \ \ \ \ ` X | 6 | 7 (escape_and_terminal_code ^ (potential_escape | first_is_escaped)) + // | escape | ` \ \ \ \ \ \ \ \ \ \` | 6 | 8 (escape_and_terminal_code & backslash) + // | first_is_escaped | `\ ` | 7 (*) | 9 (escape >> 63) () + // (*) this is not needed until the next iteration + uint64_t escape_and_terminal_code = next_escape_and_terminal_code(backslash & ~this->next_is_escaped); + uint64_t escaped = escape_and_terminal_code ^ (backslash | this->next_is_escaped); + uint64_t escape = escape_and_terminal_code & backslash; + this->next_is_escaped = escape >> 63; + return {escaped, escape}; + } + +private: + static constexpr const uint64_t ODD_BITS = 0xAAAAAAAAAAAAAAAAULL; + + simdjson_really_inline uint64_t next_escaped_without_backslashes() noexcept { + uint64_t escaped = this->next_is_escaped; + this->next_is_escaped = 0; + return escaped; + } + + /** + * Returns a mask of the next escape characters (masking out escaped backslashes), along with + * any non-backslash escape codes. + * + * \n \\n \\\n \\\\n returns: + * \n \ \ \n \ \ + * 11 100 1011 10100 + * + * You are expected to mask out the first bit yourself if the previous block had a trailing + * escape. + * + * & the result with potential_escape to get just the escape characters. + * ^ the result with (potential_escape | first_is_escaped) to get escaped characters. + */ + static simdjson_really_inline uint64_t next_escape_and_terminal_code(uint64_t potential_escape) noexcept { + // If we were to just shift and mask out any odd bits, we'd actually get a *half* right answer: + // any even-aligned backslash runs would be correct! Odd-aligned backslash runs would be + // inverted (\\\ would be 010 instead of 101). + // + // ``` + // string: | ____\\\\_\\\\_____ | + // maybe_escaped | ODD | \ \ \ \ | + // even-aligned ^^^ ^^^^ odd-aligned + // ``` + // + // Taking that into account, our basic strategy is: + // + // 1. Use subtraction to produce a mask with 1's for even-aligned runs and 0's for + // odd-aligned runs. + // 2. XOR all odd bits, which masks out the odd bits in even-aligned runs, and brings IN the + // odd bits in odd-aligned runs. + // 3. & with backslash to clean up any stray bits. + // runs are set to 0, and then XORing with "odd": + // + // | | Mask (shows characters instead of 1's) | Instructions | + // |--------------------------------|----------------------------------------|---------------------| + // | string | `\\n_\\\n___\\\n___\\\\___\\\\__\\\` | + // | | ` even odd even odd odd` | + // | maybe_escaped | ` n \\n \\n \\\_ \\\_ \\` X | 1 (potential_escape << 1) + // | maybe_escaped_and_odd | ` \n_ \\n _ \\\n_ _ \\\__ _\\\_ \\\` | 1 (maybe_escaped | odd) + // | even_series_codes_and_odd | ` n_\\\ _ n_ _\\\\ _ _ ` | 1 (maybe_escaped_and_odd - potential_escape) + // | escape_and_terminal_code | ` \n \ \n \ \n \ \ \ \ \ \` | 1 (^ odd) + // + + // Escaped characters are characters following an escape. + uint64_t maybe_escaped = potential_escape << 1; + + // To distinguish odd from even escape sequences, therefore, we turn on any *starting* + // escapes that are on an odd byte. (We actually bring in all odd bits, for speed.) + // - Odd runs of backslashes are 0000, and the code at the end ("n" in \n or \\n) is 1. + // - Odd runs of backslashes are 1111, and the code at the end ("n" in \n or \\n) is 0. + // - All other odd bytes are 1, and even bytes are 0. + uint64_t maybe_escaped_and_odd_bits = maybe_escaped | ODD_BITS; + uint64_t even_series_codes_and_odd_bits = maybe_escaped_and_odd_bits - potential_escape; + + // Now we flip all odd bytes back with xor. This: + // - Makes odd runs of backslashes go from 0000 to 1010 + // - Makes even runs of backslashes go from 1111 to 1010 + // - Sets actually-escaped codes to 1 (the n in \n and \\n: \n = 11, \\n = 100) + // - Resets all other bytes to 0 + return even_series_codes_and_odd_bits ^ ODD_BITS; + } +}; + +} // namespace stage1 +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H +/* end file generic/stage1/json_escape_scanner.h for ppc64 */ +/* including generic/stage1/json_string_scanner.h for ppc64: #include */ +/* begin file generic/stage1/json_string_scanner.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { +namespace stage1 { + +struct json_string_block { + // We spell out the constructors in the hope of resolving inlining issues with Visual Studio 2017 + simdjson_really_inline json_string_block(uint64_t escaped, uint64_t quote, uint64_t in_string) : + _escaped(escaped), _quote(quote), _in_string(in_string) {} + + // Escaped characters (characters following an escape() character) + simdjson_really_inline uint64_t escaped() const { return _escaped; } + // Real (non-backslashed) quotes + simdjson_really_inline uint64_t quote() const { return _quote; } + // Only characters inside the string (not including the quotes) + simdjson_really_inline uint64_t string_content() const { return _in_string & ~_quote; } + // Return a mask of whether the given characters are inside a string (only works on non-quotes) + simdjson_really_inline uint64_t non_quote_inside_string(uint64_t mask) const { return mask & _in_string; } + // Return a mask of whether the given characters are inside a string (only works on non-quotes) + simdjson_really_inline uint64_t non_quote_outside_string(uint64_t mask) const { return mask & ~_in_string; } + // Tail of string (everything except the start quote) + simdjson_really_inline uint64_t string_tail() const { return _in_string ^ _quote; } + + // escaped characters (backslashed--does not include the hex characters after \u) + uint64_t _escaped; + // real quotes (non-escaped ones) + uint64_t _quote; + // string characters (includes start quote but not end quote) + uint64_t _in_string; +}; + +// Scans blocks for string characters, storing the state necessary to do so +class json_string_scanner { +public: + simdjson_really_inline json_string_block next(const simd::simd8x64& in); + // Returns either UNCLOSED_STRING or SUCCESS + simdjson_really_inline error_code finish(); + +private: + // Scans for escape characters + json_escape_scanner escape_scanner{}; + // Whether the last iteration was still inside a string (all 1's = true, all 0's = false). + uint64_t prev_in_string = 0ULL; +}; + +// +// Return a mask of all string characters plus end quotes. +// +// prev_escaped is overflow saying whether the next character is escaped. +// prev_in_string is overflow saying whether we're still in a string. +// +// Backslash sequences outside of quotes will be detected in stage 2. +// +simdjson_really_inline json_string_block json_string_scanner::next(const simd::simd8x64& in) { + const uint64_t backslash = in.eq('\\'); + const uint64_t escaped = escape_scanner.next(backslash).escaped; + const uint64_t quote = in.eq('"') & ~escaped; + + // + // prefix_xor flips on bits inside the string (and flips off the end quote). + // + // Then we xor with prev_in_string: if we were in a string already, its effect is flipped + // (characters inside strings are outside, and characters outside strings are inside). + // + const uint64_t in_string = prefix_xor(quote) ^ prev_in_string; + + // + // Check if we're still in a string at the end of the box so the next block will know + // + prev_in_string = uint64_t(static_cast(in_string) >> 63); + + // Use ^ to turn the beginning quote off, and the end quote on. + + // We are returning a function-local object so either we get a move constructor + // or we get copy elision. + return json_string_block(escaped, quote, in_string); +} + +simdjson_really_inline error_code json_string_scanner::finish() { + if (prev_in_string) { + return UNCLOSED_STRING; + } + return SUCCESS; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H +/* end file generic/stage1/json_string_scanner.h for ppc64 */ +/* including generic/stage1/utf8_lookup4_algorithm.h for ppc64: #include */ +/* begin file generic/stage1/utf8_lookup4_algorithm.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { +namespace utf8_validation { + +using namespace simd; + + simdjson_inline simd8 check_special_cases(const simd8 input, const simd8 prev1) { +// Bit 0 = Too Short (lead byte/ASCII followed by lead byte/ASCII) +// Bit 1 = Too Long (ASCII followed by continuation) +// Bit 2 = Overlong 3-byte +// Bit 4 = Surrogate +// Bit 5 = Overlong 2-byte +// Bit 7 = Two Continuations + constexpr const uint8_t TOO_SHORT = 1<<0; // 11______ 0_______ + // 11______ 11______ + constexpr const uint8_t TOO_LONG = 1<<1; // 0_______ 10______ + constexpr const uint8_t OVERLONG_3 = 1<<2; // 11100000 100_____ + constexpr const uint8_t SURROGATE = 1<<4; // 11101101 101_____ + constexpr const uint8_t OVERLONG_2 = 1<<5; // 1100000_ 10______ + constexpr const uint8_t TWO_CONTS = 1<<7; // 10______ 10______ + constexpr const uint8_t TOO_LARGE = 1<<3; // 11110100 1001____ + // 11110100 101_____ + // 11110101 1001____ + // 11110101 101_____ + // 1111011_ 1001____ + // 1111011_ 101_____ + // 11111___ 1001____ + // 11111___ 101_____ + constexpr const uint8_t TOO_LARGE_1000 = 1<<6; + // 11110101 1000____ + // 1111011_ 1000____ + // 11111___ 1000____ + constexpr const uint8_t OVERLONG_4 = 1<<6; // 11110000 1000____ + + const simd8 byte_1_high = prev1.shr<4>().lookup_16( + // 0_______ ________ + TOO_LONG, TOO_LONG, TOO_LONG, TOO_LONG, + TOO_LONG, TOO_LONG, TOO_LONG, TOO_LONG, + // 10______ ________ + TWO_CONTS, TWO_CONTS, TWO_CONTS, TWO_CONTS, + // 1100____ ________ + TOO_SHORT | OVERLONG_2, + // 1101____ ________ + TOO_SHORT, + // 1110____ ________ + TOO_SHORT | OVERLONG_3 | SURROGATE, + // 1111____ ________ + TOO_SHORT | TOO_LARGE | TOO_LARGE_1000 | OVERLONG_4 + ); + constexpr const uint8_t CARRY = TOO_SHORT | TOO_LONG | TWO_CONTS; // These all have ____ in byte 1 . + const simd8 byte_1_low = (prev1 & 0x0F).lookup_16( + // ____0000 ________ + CARRY | OVERLONG_3 | OVERLONG_2 | OVERLONG_4, + // ____0001 ________ + CARRY | OVERLONG_2, + // ____001_ ________ + CARRY, + CARRY, + + // ____0100 ________ + CARRY | TOO_LARGE, + // ____0101 ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + // ____011_ ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + + // ____1___ ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + // ____1101 ________ + CARRY | TOO_LARGE | TOO_LARGE_1000 | SURROGATE, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000 + ); + const simd8 byte_2_high = input.shr<4>().lookup_16( + // ________ 0_______ + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT, + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT, + + // ________ 1000____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | OVERLONG_3 | TOO_LARGE_1000 | OVERLONG_4, + // ________ 1001____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | OVERLONG_3 | TOO_LARGE, + // ________ 101_____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | SURROGATE | TOO_LARGE, + TOO_LONG | OVERLONG_2 | TWO_CONTS | SURROGATE | TOO_LARGE, + + // ________ 11______ + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT + ); + return (byte_1_high & byte_1_low & byte_2_high); + } + simdjson_inline simd8 check_multibyte_lengths(const simd8 input, + const simd8 prev_input, const simd8 sc) { + simd8 prev2 = input.prev<2>(prev_input); + simd8 prev3 = input.prev<3>(prev_input); + simd8 must23 = simd8(must_be_2_3_continuation(prev2, prev3)); + simd8 must23_80 = must23 & uint8_t(0x80); + return must23_80 ^ sc; + } + + // + // Return nonzero if there are incomplete multibyte characters at the end of the block: + // e.g. if there is a 4-byte character, but it's 3 bytes from the end. + // + simdjson_inline simd8 is_incomplete(const simd8 input) { + // If the previous input's last 3 bytes match this, they're too short (they ended at EOF): + // ... 1111____ 111_____ 11______ +#if SIMDJSON_IMPLEMENTATION_ICELAKE + static const uint8_t max_array[64] = { + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 0xf0u-1, 0xe0u-1, 0xc0u-1 + }; +#else + static const uint8_t max_array[32] = { + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 0xf0u-1, 0xe0u-1, 0xc0u-1 + }; +#endif + const simd8 max_value(&max_array[sizeof(max_array)-sizeof(simd8)]); + return input.gt_bits(max_value); + } + + struct utf8_checker { + // If this is nonzero, there has been a UTF-8 error. + simd8 error; + // The last input we received + simd8 prev_input_block; + // Whether the last input we received was incomplete (used for ASCII fast path) + simd8 prev_incomplete; + + // + // Check whether the current bytes are valid UTF-8. + // + simdjson_inline void check_utf8_bytes(const simd8 input, const simd8 prev_input) { + // Flip prev1...prev3 so we can easily determine if they are 2+, 3+ or 4+ lead bytes + // (2, 3, 4-byte leads become large positive numbers instead of small negative numbers) + simd8 prev1 = input.prev<1>(prev_input); + simd8 sc = check_special_cases(input, prev1); + this->error |= check_multibyte_lengths(input, prev_input, sc); + } + + // The only problem that can happen at EOF is that a multibyte character is too short + // or a byte value too large in the last bytes: check_special_cases only checks for bytes + // too large in the first of two bytes. + simdjson_inline void check_eof() { + // If the previous block had incomplete UTF-8 characters at the end, an ASCII block can't + // possibly finish them. + this->error |= this->prev_incomplete; + } + + simdjson_inline void check_next_input(const simd8x64& input) { + if(simdjson_likely(is_ascii(input))) { + this->error |= this->prev_incomplete; + } else { + // you might think that a for-loop would work, but under Visual Studio, it is not good enough. + static_assert((simd8x64::NUM_CHUNKS == 1) + ||(simd8x64::NUM_CHUNKS == 2) + || (simd8x64::NUM_CHUNKS == 4), + "We support one, two or four chunks per 64-byte block."); + SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 1) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + } else SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 2) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + this->check_utf8_bytes(input.chunks[1], input.chunks[0]); + } else SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 4) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + this->check_utf8_bytes(input.chunks[1], input.chunks[0]); + this->check_utf8_bytes(input.chunks[2], input.chunks[1]); + this->check_utf8_bytes(input.chunks[3], input.chunks[2]); + } + this->prev_incomplete = is_incomplete(input.chunks[simd8x64::NUM_CHUNKS-1]); + this->prev_input_block = input.chunks[simd8x64::NUM_CHUNKS-1]; + } + } + // do not forget to call check_eof! + simdjson_inline error_code errors() { + return this->error.any_bits_set_anywhere() ? error_code::UTF8_ERROR : error_code::SUCCESS; + } + + }; // struct utf8_checker +} // namespace utf8_validation + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H +/* end file generic/stage1/utf8_lookup4_algorithm.h for ppc64 */ +/* including generic/stage1/json_scanner.h for ppc64: #include */ +/* begin file generic/stage1/json_scanner.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { +namespace stage1 { + +/** + * A block of scanned json, with information on operators and scalars. + * + * We seek to identify pseudo-structural characters. Anything that is inside + * a string must be omitted (hence & ~_string.string_tail()). + * Otherwise, pseudo-structural characters come in two forms. + * 1. We have the structural characters ([,],{,},:, comma). The + * term 'structural character' is from the JSON RFC. + * 2. We have the 'scalar pseudo-structural characters'. + * Scalars are quotes, and any character except structural characters and white space. + * + * To identify the scalar pseudo-structural characters, we must look at what comes + * before them: it must be a space, a quote or a structural characters. + * Starting with simdjson v0.3, we identify them by + * negation: we identify everything that is followed by a non-quote scalar, + * and we negate that. Whatever remains must be a 'scalar pseudo-structural character'. + */ +struct json_block { +public: + // We spell out the constructors in the hope of resolving inlining issues with Visual Studio 2017 + simdjson_inline json_block(json_string_block&& string, json_character_block characters, uint64_t follows_potential_nonquote_scalar) : + _string(std::move(string)), _characters(characters), _follows_potential_nonquote_scalar(follows_potential_nonquote_scalar) {} + simdjson_inline json_block(json_string_block string, json_character_block characters, uint64_t follows_potential_nonquote_scalar) : + _string(string), _characters(characters), _follows_potential_nonquote_scalar(follows_potential_nonquote_scalar) {} + + /** + * The start of structurals. + * In simdjson prior to v0.3, these were called the pseudo-structural characters. + **/ + simdjson_inline uint64_t structural_start() const noexcept { return potential_structural_start() & ~_string.string_tail(); } + /** All JSON whitespace (i.e. not in a string) */ + simdjson_inline uint64_t whitespace() const noexcept { return non_quote_outside_string(_characters.whitespace()); } + + // Helpers + + /** Whether the given characters are inside a string (only works on non-quotes) */ + simdjson_inline uint64_t non_quote_inside_string(uint64_t mask) const noexcept { return _string.non_quote_inside_string(mask); } + /** Whether the given characters are outside a string (only works on non-quotes) */ + simdjson_inline uint64_t non_quote_outside_string(uint64_t mask) const noexcept { return _string.non_quote_outside_string(mask); } + + // string and escape characters + json_string_block _string; + // whitespace, structural characters ('operators'), scalars + json_character_block _characters; + // whether the previous character was a scalar + uint64_t _follows_potential_nonquote_scalar; +private: + // Potential structurals (i.e. disregarding strings) + + /** + * structural elements ([,],{,},:, comma) plus scalar starts like 123, true and "abc". + * They may reside inside a string. + **/ + simdjson_inline uint64_t potential_structural_start() const noexcept { return _characters.op() | potential_scalar_start(); } + /** + * The start of non-operator runs, like 123, true and "abc". + * It main reside inside a string. + **/ + simdjson_inline uint64_t potential_scalar_start() const noexcept { + // The term "scalar" refers to anything except structural characters and white space + // (so letters, numbers, quotes). + // Whenever it is preceded by something that is not a structural element ({,},[,],:, ") nor a white-space + // then we know that it is irrelevant structurally. + return _characters.scalar() & ~follows_potential_scalar(); + } + /** + * Whether the given character is immediately after a non-operator like 123, true. + * The characters following a quote are not included. + */ + simdjson_inline uint64_t follows_potential_scalar() const noexcept { + // _follows_potential_nonquote_scalar: is defined as marking any character that follows a character + // that is not a structural element ({,},[,],:, comma) nor a quote (") and that is not a + // white space. + // It is understood that within quoted region, anything at all could be marked (irrelevant). + return _follows_potential_nonquote_scalar; + } +}; + +/** + * Scans JSON for important bits: structural characters or 'operators', strings, and scalars. + * + * The scanner starts by calculating two distinct things: + * - string characters (taking \" into account) + * - structural characters or 'operators' ([]{},:, comma) + * and scalars (runs of non-operators like 123, true and "abc") + * + * To minimize data dependency (a key component of the scanner's speed), it finds these in parallel: + * in particular, the operator/scalar bit will find plenty of things that are actually part of + * strings. When we're done, json_block will fuse the two together by masking out tokens that are + * part of a string. + */ +class json_scanner { +public: + json_scanner() = default; + simdjson_inline json_block next(const simd::simd8x64& in); + // Returns either UNCLOSED_STRING or SUCCESS + simdjson_inline error_code finish(); + +private: + // Whether the last character of the previous iteration is part of a scalar token + // (anything except whitespace or a structural character/'operator'). + uint64_t prev_scalar = 0ULL; + json_string_scanner string_scanner{}; +}; + + +// +// Check if the current character immediately follows a matching character. +// +// For example, this checks for quotes with backslashes in front of them: +// +// const uint64_t backslashed_quote = in.eq('"') & immediately_follows(in.eq('\'), prev_backslash); +// +simdjson_inline uint64_t follows(const uint64_t match, uint64_t &overflow) { + const uint64_t result = match << 1 | overflow; + overflow = match >> 63; + return result; +} + +simdjson_inline json_block json_scanner::next(const simd::simd8x64& in) { + json_string_block strings = string_scanner.next(in); + // identifies the white-space and the structural characters + json_character_block characters = json_character_block::classify(in); + // The term "scalar" refers to anything except structural characters and white space + // (so letters, numbers, quotes). + // We want follows_scalar to mark anything that follows a non-quote scalar (so letters and numbers). + // + // A terminal quote should either be followed by a structural character (comma, brace, bracket, colon) + // or nothing. However, we still want ' "a string"true ' to mark the 't' of 'true' as a potential + // pseudo-structural character just like we would if we had ' "a string" true '; otherwise we + // may need to add an extra check when parsing strings. + // + // Performance: there are many ways to skin this cat. + const uint64_t nonquote_scalar = characters.scalar() & ~strings.quote(); + uint64_t follows_nonquote_scalar = follows(nonquote_scalar, prev_scalar); + // We are returning a function-local object so either we get a move constructor + // or we get copy elision. + return json_block( + strings,// strings is a function-local object so either it moves or the copy is elided. + characters, + follows_nonquote_scalar + ); +} + +simdjson_inline error_code json_scanner::finish() { + return string_scanner.finish(); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H +/* end file generic/stage1/json_scanner.h for ppc64 */ + +// All other declarations +/* including generic/stage1/find_next_document_index.h for ppc64: #include */ +/* begin file generic/stage1/find_next_document_index.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { +namespace stage1 { + +/** + * This algorithm is used to quickly identify the last structural position that + * makes up a complete document. + * + * It does this by going backwards and finding the last *document boundary* (a + * place where one value follows another without a comma between them). If the + * last document (the characters after the boundary) has an equal number of + * start and end brackets, it is considered complete. + * + * Simply put, we iterate over the structural characters, starting from + * the end. We consider that we found the end of a JSON document when the + * first element of the pair is NOT one of these characters: '{' '[' ':' ',' + * and when the second element is NOT one of these characters: '}' ']' ':' ','. + * + * This simple comparison works most of the time, but it does not cover cases + * where the batch's structural indexes contain a perfect amount of documents. + * In such a case, we do not have access to the structural index which follows + * the last document, therefore, we do not have access to the second element in + * the pair, and that means we cannot identify the last document. To fix this + * issue, we keep a count of the open and closed curly/square braces we found + * while searching for the pair. When we find a pair AND the count of open and + * closed curly/square braces is the same, we know that we just passed a + * complete document, therefore the last json buffer location is the end of the + * batch. + */ +simdjson_inline uint32_t find_next_document_index(dom_parser_implementation &parser) { + // Variant: do not count separately, just figure out depth + if(parser.n_structural_indexes == 0) { return 0; } + auto arr_cnt = 0; + auto obj_cnt = 0; + for (auto i = parser.n_structural_indexes - 1; i > 0; i--) { + auto idxb = parser.structural_indexes[i]; + switch (parser.buf[idxb]) { + case ':': + case ',': + continue; + case '}': + obj_cnt--; + continue; + case ']': + arr_cnt--; + continue; + case '{': + obj_cnt++; + break; + case '[': + arr_cnt++; + break; + } + auto idxa = parser.structural_indexes[i - 1]; + switch (parser.buf[idxa]) { + case '{': + case '[': + case ':': + case ',': + continue; + } + // Last document is complete, so the next document will appear after! + if (!arr_cnt && !obj_cnt) { + return parser.n_structural_indexes; + } + // Last document is incomplete; mark the document at i + 1 as the next one + return i; + } + // If we made it to the end, we want to finish counting to see if we have a full document. + switch (parser.buf[parser.structural_indexes[0]]) { + case '}': + obj_cnt--; + break; + case ']': + arr_cnt--; + break; + case '{': + obj_cnt++; + break; + case '[': + arr_cnt++; + break; + } + if (!arr_cnt && !obj_cnt) { + // We have a complete document. + return parser.n_structural_indexes; + } + return 0; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H +/* end file generic/stage1/find_next_document_index.h for ppc64 */ +/* including generic/stage1/json_minifier.h for ppc64: #include */ +/* begin file generic/stage1/json_minifier.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses in stage1 +// It is intended to be included multiple times and compiled multiple times +// We assume the file in which it is included already includes +// "simdjson/stage1.h" (this simplifies amalgation) + +namespace simdjson { +namespace ppc64 { +namespace { +namespace stage1 { + +class json_minifier { +public: + template + static error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept; + +private: + simdjson_inline json_minifier(uint8_t *_dst) + : dst{_dst} + {} + template + simdjson_inline void step(const uint8_t *block_buf, buf_block_reader &reader) noexcept; + simdjson_inline void next(const simd::simd8x64& in, const json_block& block); + simdjson_inline error_code finish(uint8_t *dst_start, size_t &dst_len); + json_scanner scanner{}; + uint8_t *dst; +}; + +simdjson_inline void json_minifier::next(const simd::simd8x64& in, const json_block& block) { + uint64_t mask = block.whitespace(); + dst += in.compress(mask, dst); +} + +simdjson_inline error_code json_minifier::finish(uint8_t *dst_start, size_t &dst_len) { + error_code error = scanner.finish(); + if (error) { dst_len = 0; return error; } + dst_len = dst - dst_start; + return SUCCESS; +} + +template<> +simdjson_inline void json_minifier::step<128>(const uint8_t *block_buf, buf_block_reader<128> &reader) noexcept { + simd::simd8x64 in_1(block_buf); + simd::simd8x64 in_2(block_buf+64); + json_block block_1 = scanner.next(in_1); + json_block block_2 = scanner.next(in_2); + this->next(in_1, block_1); + this->next(in_2, block_2); + reader.advance(); +} + +template<> +simdjson_inline void json_minifier::step<64>(const uint8_t *block_buf, buf_block_reader<64> &reader) noexcept { + simd::simd8x64 in_1(block_buf); + json_block block_1 = scanner.next(in_1); + this->next(block_buf, block_1); + reader.advance(); +} + +template +error_code json_minifier::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept { + buf_block_reader reader(buf, len); + json_minifier minifier(dst); + + // Index the first n-1 blocks + while (reader.has_full_block()) { + minifier.step(reader.full_block(), reader); + } + + // Index the last (remainder) block, padded with spaces + uint8_t block[STEP_SIZE]; + size_t remaining_bytes = reader.get_remainder(block); + if (remaining_bytes > 0) { + // We do not want to write directly to the output stream. Rather, we write + // to a local buffer (for safety). + uint8_t out_block[STEP_SIZE]; + uint8_t * const guarded_dst{minifier.dst}; + minifier.dst = out_block; + minifier.step(block, reader); + size_t to_write = minifier.dst - out_block; + // In some cases, we could be enticed to consider the padded spaces + // as part of the string. This is fine as long as we do not write more + // than we consumed. + if(to_write > remaining_bytes) { to_write = remaining_bytes; } + memcpy(guarded_dst, out_block, to_write); + minifier.dst = guarded_dst + to_write; + } + return minifier.finish(dst, dst_len); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H +/* end file generic/stage1/json_minifier.h for ppc64 */ +/* including generic/stage1/json_structural_indexer.h for ppc64: #include */ +/* begin file generic/stage1/json_structural_indexer.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses in stage1 +// It is intended to be included multiple times and compiled multiple times +// We assume the file in which it is included already includes +// "simdjson/stage1.h" (this simplifies amalgation) + +namespace simdjson { +namespace ppc64 { +namespace { +namespace stage1 { + +class bit_indexer { +public: + uint32_t *tail; + + simdjson_inline bit_indexer(uint32_t *index_buf) : tail(index_buf) {} + +#if SIMDJSON_PREFER_REVERSE_BITS + /** + * ARM lacks a fast trailing zero instruction, but it has a fast + * bit reversal instruction and a fast leading zero instruction. + * Thus it may be profitable to reverse the bits (once) and then + * to rely on a sequence of instructions that call the leading + * zero instruction. + * + * Performance notes: + * The chosen routine is not optimal in terms of data dependency + * since zero_leading_bit might require two instructions. However, + * it tends to minimize the total number of instructions which is + * beneficial. + */ + simdjson_inline void write_index(uint32_t idx, uint64_t& rev_bits, int i) { + int lz = leading_zeroes(rev_bits); + this->tail[i] = static_cast(idx) + lz; + rev_bits = zero_leading_bit(rev_bits, lz); + } +#else + /** + * Under recent x64 systems, we often have both a fast trailing zero + * instruction and a fast 'clear-lower-bit' instruction so the following + * algorithm can be competitive. + */ + + simdjson_inline void write_index(uint32_t idx, uint64_t& bits, int i) { + this->tail[i] = idx + trailing_zeroes(bits); + bits = clear_lowest_bit(bits); + } +#endif // SIMDJSON_PREFER_REVERSE_BITS + + template + simdjson_inline int write_indexes(uint32_t idx, uint64_t& bits) { + write_index(idx, bits, START); + SIMDJSON_IF_CONSTEXPR (N > 1) { + write_indexes<(N-1>0?START+1:START), (N-1>=0?N-1:1)>(idx, bits); + } + return START+N; + } + + template + simdjson_inline int write_indexes_stepped(uint32_t idx, uint64_t& bits, int cnt) { + write_indexes(idx, bits); + SIMDJSON_IF_CONSTEXPR ((START+STEP) < END) { + if (simdjson_unlikely((START+STEP) < cnt)) { + write_indexes_stepped<(START+STEP(idx, bits, cnt); + } + } + return ((END-START) % STEP) == 0 ? END : (END-START) - ((END-START) % STEP) + STEP; + } + + // flatten out values in 'bits' assuming that they are are to have values of idx + // plus their position in the bitvector, and store these indexes at + // base_ptr[base] incrementing base as we go + // will potentially store extra values beyond end of valid bits, so base_ptr + // needs to be large enough to handle this + // + // If the kernel sets SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER, then it + // will provide its own version of the code. +#ifdef SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + simdjson_inline void write(uint32_t idx, uint64_t bits); +#else + simdjson_inline void write(uint32_t idx, uint64_t bits) { + // In some instances, the next branch is expensive because it is mispredicted. + // Unfortunately, in other cases, + // it helps tremendously. + if (bits == 0) + return; + + int cnt = static_cast(count_ones(bits)); + +#if SIMDJSON_PREFER_REVERSE_BITS + bits = reverse_bits(bits); +#endif +#ifdef SIMDJSON_STRUCTURAL_INDEXER_STEP + static constexpr const int STEP = SIMDJSON_STRUCTURAL_INDEXER_STEP; +#else + static constexpr const int STEP = 4; +#endif + static constexpr const int STEP_UNTIL = 24; + + write_indexes_stepped<0, STEP_UNTIL, STEP>(idx, bits, cnt); + SIMDJSON_IF_CONSTEXPR (STEP_UNTIL < 64) { + if (simdjson_unlikely(STEP_UNTIL < cnt)) { + for (int i=STEP_UNTIL; itail += cnt; + } +#endif // SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + +}; + +class json_structural_indexer { +public: + /** + * Find the important bits of JSON in a 128-byte chunk, and add them to structural_indexes. + * + * @param partial Setting the partial parameter to true allows the find_structural_bits to + * tolerate unclosed strings. 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 + static error_code index(const uint8_t *buf, size_t len, dom_parser_implementation &parser, stage1_mode partial) noexcept; + +private: + simdjson_inline json_structural_indexer(uint32_t *structural_indexes); + template + simdjson_inline void step(const uint8_t *block, buf_block_reader &reader) noexcept; + simdjson_inline void next(const simd::simd8x64& in, const json_block& block, size_t idx); + simdjson_inline error_code finish(dom_parser_implementation &parser, size_t idx, size_t len, stage1_mode partial); + + json_scanner scanner{}; + utf8_checker checker{}; + bit_indexer indexer; + uint64_t prev_structurals = 0; + uint64_t unescaped_chars_error = 0; +}; + +simdjson_inline json_structural_indexer::json_structural_indexer(uint32_t *structural_indexes) : indexer{structural_indexes} {} + +// Skip the last character if it is partial +simdjson_inline size_t trim_partial_utf8(const uint8_t *buf, size_t len) { + if (simdjson_unlikely(len < 3)) { + switch (len) { + case 2: + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + if (buf[len-2] >= 0xe0) { return len-2; } // 3- and 4-byte characters with only 2 bytes left + return len; + case 1: + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + return len; + case 0: + return len; + } + } + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + if (buf[len-2] >= 0xe0) { return len-2; } // 3- and 4-byte characters with only 1 byte left + if (buf[len-3] >= 0xf0) { return len-3; } // 4-byte characters with only 3 bytes left + return len; +} + +// +// PERF NOTES: +// We pipe 2 inputs through these stages: +// 1. Load JSON into registers. This takes a long time and is highly parallelizable, so we load +// 2 inputs' worth at once so that by the time step 2 is looking for them input, it's available. +// 2. Scan the JSON for critical data: strings, scalars and operators. This is the critical path. +// The output of step 1 depends entirely on this information. These functions don't quite use +// up enough CPU: the second half of the functions is highly serial, only using 1 execution core +// at a time. The second input's scans has some dependency on the first ones finishing it, but +// they can make a lot of progress before they need that information. +// 3. Step 1 doesn't use enough capacity, so we run some extra stuff while we're waiting for that +// to finish: utf-8 checks and generating the output from the last iteration. +// +// The reason we run 2 inputs at a time, is steps 2 and 3 are *still* not enough to soak up all +// available capacity with just one input. Running 2 at a time seems to give the CPU a good enough +// workout. +// +template +error_code json_structural_indexer::index(const uint8_t *buf, size_t len, dom_parser_implementation &parser, stage1_mode partial) noexcept { + if (simdjson_unlikely(len > parser.capacity())) { return CAPACITY; } + // We guard the rest of the code so that we can assume that len > 0 throughout. + if (len == 0) { return EMPTY; } + if (is_streaming(partial)) { + len = trim_partial_utf8(buf, len); + // If you end up with an empty window after trimming + // the partial UTF-8 bytes, then chances are good that you + // have an UTF-8 formatting error. + if(len == 0) { return UTF8_ERROR; } + } + buf_block_reader reader(buf, len); + json_structural_indexer indexer(parser.structural_indexes.get()); + + // Read all but the last block + while (reader.has_full_block()) { + indexer.step(reader.full_block(), reader); + } + // Take care of the last block (will always be there unless file is empty which is + // not supposed to happen.) + uint8_t block[STEP_SIZE]; + if (simdjson_unlikely(reader.get_remainder(block) == 0)) { return UNEXPECTED_ERROR; } + indexer.step(block, reader); + return indexer.finish(parser, reader.block_index(), len, partial); +} + +template<> +simdjson_inline void json_structural_indexer::step<128>(const uint8_t *block, buf_block_reader<128> &reader) noexcept { + simd::simd8x64 in_1(block); + simd::simd8x64 in_2(block+64); + json_block block_1 = scanner.next(in_1); + json_block block_2 = scanner.next(in_2); + this->next(in_1, block_1, reader.block_index()); + this->next(in_2, block_2, reader.block_index()+64); + reader.advance(); +} + +template<> +simdjson_inline void json_structural_indexer::step<64>(const uint8_t *block, buf_block_reader<64> &reader) noexcept { + simd::simd8x64 in_1(block); + json_block block_1 = scanner.next(in_1); + this->next(in_1, block_1, reader.block_index()); + reader.advance(); +} + +simdjson_inline void json_structural_indexer::next(const simd::simd8x64& in, const json_block& block, size_t idx) { + uint64_t unescaped = in.lteq(0x1F); +#if SIMDJSON_UTF8VALIDATION + checker.check_next_input(in); +#endif + indexer.write(uint32_t(idx-64), prev_structurals); // Output *last* iteration's structurals to the parser + prev_structurals = block.structural_start(); + unescaped_chars_error |= block.non_quote_inside_string(unescaped); +} + +simdjson_inline error_code json_structural_indexer::finish(dom_parser_implementation &parser, size_t idx, size_t len, stage1_mode partial) { + // Write out the final iteration's structurals + indexer.write(uint32_t(idx-64), prev_structurals); + error_code error = scanner.finish(); + // We deliberately break down the next expression so that it is + // human readable. + const bool should_we_exit = is_streaming(partial) ? + ((error != SUCCESS) && (error != UNCLOSED_STRING)) // when partial we tolerate UNCLOSED_STRING + : (error != SUCCESS); // if partial is false, we must have SUCCESS + const bool have_unclosed_string = (error == UNCLOSED_STRING); + if (simdjson_unlikely(should_we_exit)) { return error; } + + if (unescaped_chars_error) { + return UNESCAPED_CHARS; + } + parser.n_structural_indexes = uint32_t(indexer.tail - parser.structural_indexes.get()); + /*** + * The On Demand API requires special padding. + * + * This is related to https://github.com/simdjson/simdjson/issues/906 + * Basically, we want to make sure that if the parsing continues beyond the last (valid) + * structural character, it quickly stops. + * Only three structural characters can be repeated without triggering an error in JSON: [,] and }. + * We repeat the padding character (at 'len'). We don't know what it is, but if the parsing + * continues, then it must be [,] or }. + * Suppose it is ] or }. We backtrack to the first character, what could it be that would + * not trigger an error? It could be ] or } but no, because you can't start a document that way. + * It can't be a comma, a colon or any simple value. So the only way we could continue is + * if the repeated character is [. But if so, the document must start with [. But if the document + * starts with [, it should end with ]. If we enforce that rule, then we would get + * ][[ which is invalid. + * + * This is illustrated with the test array_iterate_unclosed_error() on the following input: + * R"({ "a": [,,)" + **/ + parser.structural_indexes[parser.n_structural_indexes] = uint32_t(len); // used later in partial == stage1_mode::streaming_final + parser.structural_indexes[parser.n_structural_indexes + 1] = uint32_t(len); + parser.structural_indexes[parser.n_structural_indexes + 2] = 0; + parser.next_structural_index = 0; + // a valid JSON file cannot have zero structural indexes - we should have found something + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { + return EMPTY; + } + if (simdjson_unlikely(parser.structural_indexes[parser.n_structural_indexes - 1] > len)) { + return UNEXPECTED_ERROR; + } + if (partial == stage1_mode::streaming_partial) { + // If we have an unclosed string, then the last structural + // will be the quote and we want to make sure to omit it. + if(have_unclosed_string) { + parser.n_structural_indexes--; + // a valid JSON file cannot have zero structural indexes - we should have found something + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { return CAPACITY; } + } + // We truncate the input to the end of the last complete document (or zero). + auto new_structural_indexes = find_next_document_index(parser); + if (new_structural_indexes == 0 && parser.n_structural_indexes > 0) { + if(parser.structural_indexes[0] == 0) { + // If the buffer is partial and we started at index 0 but the document is + // incomplete, it's too big to parse. + return CAPACITY; + } else { + // It is possible that the document could be parsed, we just had a lot + // of white space. + parser.n_structural_indexes = 0; + return EMPTY; + } + } + + parser.n_structural_indexes = new_structural_indexes; + } else if (partial == stage1_mode::streaming_final) { + if(have_unclosed_string) { parser.n_structural_indexes--; } + // We truncate the input to the end of the last complete document (or zero). + // Because partial == stage1_mode::streaming_final, it means that we may + // silently ignore trailing garbage. Though it sounds bad, we do it + // deliberately because many people who have streams of JSON documents + // will truncate them for processing. E.g., imagine that you are uncompressing + // the data from a size file or receiving it in chunks from the network. You + // may not know where exactly the last document will be. Meanwhile the + // document_stream instances allow people to know the JSON documents they are + // parsing (see the iterator.source() method). + parser.n_structural_indexes = find_next_document_index(parser); + // We store the initial n_structural_indexes so that the client can see + // whether we used truncation. If initial_n_structural_indexes == parser.n_structural_indexes, + // then this will query parser.structural_indexes[parser.n_structural_indexes] which is len, + // otherwise, it will copy some prior index. + parser.structural_indexes[parser.n_structural_indexes + 1] = parser.structural_indexes[parser.n_structural_indexes]; + // This next line is critical, do not change it unless you understand what you are + // doing. + parser.structural_indexes[parser.n_structural_indexes] = uint32_t(len); + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { + // We tolerate an unclosed string at the very end of the stream. Indeed, users + // often load their data in bulk without being careful and they want us to ignore + // the trailing garbage. + return EMPTY; + } + } + checker.check_eof(); + return checker.errors(); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +// Clear CUSTOM_BIT_INDEXER so other implementations can set it if they need to. +#undef SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H +/* end file generic/stage1/json_structural_indexer.h for ppc64 */ +/* including generic/stage1/utf8_validator.h for ppc64: #include */ +/* begin file generic/stage1/utf8_validator.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { +namespace stage1 { + +/** + * Validates that the string is actual UTF-8. + */ +template +bool generic_validate_utf8(const uint8_t * input, size_t length) { + checker c{}; + buf_block_reader<64> reader(input, length); + while (reader.has_full_block()) { + simd::simd8x64 in(reader.full_block()); + c.check_next_input(in); + reader.advance(); + } + uint8_t block[64]{}; + reader.get_remainder(block); + simd::simd8x64 in(block); + c.check_next_input(in); + reader.advance(); + c.check_eof(); + return c.errors() == error_code::SUCCESS; +} + +bool generic_validate_utf8(const char * input, size_t length) { + return generic_validate_utf8(reinterpret_cast(input),length); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H +/* end file generic/stage1/utf8_validator.h for ppc64 */ +/* end file generic/stage1/amalgamated.h for ppc64 */ +/* including generic/stage2/amalgamated.h for ppc64: #include */ +/* begin file generic/stage2/amalgamated.h for ppc64 */ +// Stuff other things depend on +/* including generic/stage2/base.h for ppc64: #include */ +/* begin file generic/stage2/base.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { +namespace stage2 { + +class json_iterator; +class structural_iterator; +struct tape_builder; +struct tape_writer; + +} // namespace stage2 +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_BASE_H +/* end file generic/stage2/base.h for ppc64 */ +/* including generic/stage2/tape_writer.h for ppc64: #include */ +/* begin file generic/stage2/tape_writer.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace ppc64 { +namespace { +namespace stage2 { + +struct tape_writer { + /** The next place to write to tape */ + uint64_t *next_tape_loc; + + /** Write a signed 64-bit value to tape. */ + simdjson_inline void append_s64(int64_t value) noexcept; + + /** Write an unsigned 64-bit value to tape. */ + simdjson_inline void append_u64(uint64_t value) noexcept; + + /** Write a double value to tape. */ + simdjson_inline void append_double(double value) noexcept; + + /** + * Append a tape entry (an 8-bit type,and 56 bits worth of value). + */ + simdjson_inline void append(uint64_t val, internal::tape_type t) noexcept; + + /** + * Skip the current tape entry without writing. + * + * Used to skip the start of the container, since we'll come back later to fill it in when the + * container ends. + */ + simdjson_inline void skip() noexcept; + + /** + * Skip the number of tape entries necessary to write a large u64 or i64. + */ + simdjson_inline void skip_large_integer() noexcept; + + /** + * Skip the number of tape entries necessary to write a double. + */ + simdjson_inline void skip_double() noexcept; + + /** + * Write a value to a known location on tape. + * + * Used to go back and write out the start of a container after the container ends. + */ + simdjson_inline static void write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept; + +private: + /** + * Append both the tape entry, and a supplementary value following it. Used for types that need + * all 64 bits, such as double and uint64_t. + */ + template + simdjson_inline void append2(uint64_t val, T val2, internal::tape_type t) noexcept; +}; // struct tape_writer + +simdjson_inline void tape_writer::append_s64(int64_t value) noexcept { + append2(0, value, internal::tape_type::INT64); +} + +simdjson_inline void tape_writer::append_u64(uint64_t value) noexcept { + append(0, internal::tape_type::UINT64); + *next_tape_loc = value; + next_tape_loc++; +} + +/** Write a double value to tape. */ +simdjson_inline void tape_writer::append_double(double value) noexcept { + append2(0, value, internal::tape_type::DOUBLE); +} + +simdjson_inline void tape_writer::skip() noexcept { + next_tape_loc++; +} + +simdjson_inline void tape_writer::skip_large_integer() noexcept { + next_tape_loc += 2; +} + +simdjson_inline void tape_writer::skip_double() noexcept { + next_tape_loc += 2; +} + +simdjson_inline void tape_writer::append(uint64_t val, internal::tape_type t) noexcept { + *next_tape_loc = val | ((uint64_t(char(t))) << 56); + next_tape_loc++; +} + +template +simdjson_inline void tape_writer::append2(uint64_t val, T val2, internal::tape_type t) noexcept { + append(val, t); + static_assert(sizeof(val2) == sizeof(*next_tape_loc), "Type is not 64 bits!"); + memcpy(next_tape_loc, &val2, sizeof(val2)); + next_tape_loc++; +} + +simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept { + tape_loc = val | ((uint64_t(char(t))) << 56); +} + +} // namespace stage2 +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H +/* end file generic/stage2/tape_writer.h for ppc64 */ +/* including generic/stage2/logger.h for ppc64: #include */ +/* begin file generic/stage2/logger.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_LOGGER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_LOGGER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + + +// This is for an internal-only stage 2 specific logger. +// Set LOG_ENABLED = true to log what stage 2 is doing! +namespace simdjson { +namespace ppc64 { +namespace { +namespace logger { + + static constexpr const char * DASHES = "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"; + +#if SIMDJSON_VERBOSE_LOGGING + static constexpr const bool LOG_ENABLED = true; +#else + static constexpr const bool LOG_ENABLED = false; +#endif + static constexpr const int LOG_EVENT_LEN = 20; + static constexpr const int LOG_BUFFER_LEN = 30; + static constexpr const int LOG_SMALL_BUFFER_LEN = 10; + static constexpr const int LOG_INDEX_LEN = 5; + + static int log_depth; // Not threadsafe. Log only. + + // Helper to turn unprintable or newline characters into spaces + static simdjson_inline char printable_char(char c) { + if (c >= 0x20) { + return c; + } else { + return ' '; + } + } + + // Print the header and set up log_start + static simdjson_inline void log_start() { + if (LOG_ENABLED) { + log_depth = 0; + printf("\n"); + printf("| %-*s | %-*s | %-*s | %-*s | Detail |\n", LOG_EVENT_LEN, "Event", LOG_BUFFER_LEN, "Buffer", LOG_SMALL_BUFFER_LEN, "Next", 5, "Next#"); + printf("|%.*s|%.*s|%.*s|%.*s|--------|\n", LOG_EVENT_LEN+2, DASHES, LOG_BUFFER_LEN+2, DASHES, LOG_SMALL_BUFFER_LEN+2, DASHES, 5+2, DASHES); + } + } + + simdjson_unused static simdjson_inline void log_string(const char *message) { + if (LOG_ENABLED) { + printf("%s\n", message); + } + } + + // Logs a single line from the stage 2 DOM parser + template + static simdjson_inline void log_line(S &structurals, const char *title_prefix, const char *title, const char *detail) { + if (LOG_ENABLED) { + printf("| %*s%s%-*s ", log_depth*2, "", title_prefix, LOG_EVENT_LEN - log_depth*2 - int(strlen(title_prefix)), title); + auto current_index = structurals.at_beginning() ? nullptr : structurals.next_structural-1; + auto next_index = structurals.next_structural; + auto current = current_index ? &structurals.buf[*current_index] : reinterpret_cast(" "); + auto next = &structurals.buf[*next_index]; + { + // Print the next N characters in the buffer. + printf("| "); + // Otherwise, print the characters starting from the buffer position. + // Print spaces for unprintable or newline characters. + for (int i=0;i */ +/* begin file generic/stage2/json_iterator.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { +namespace stage2 { + +class json_iterator { +public: + const uint8_t* const buf; + uint32_t *next_structural; + dom_parser_implementation &dom_parser; + uint32_t depth{0}; + + /** + * Walk the JSON document. + * + * The visitor receives callbacks when values are encountered. All callbacks pass the iterator as + * the first parameter; some callbacks have other parameters as well: + * + * - visit_document_start() - at the beginning. + * - visit_document_end() - at the end (if things were successful). + * + * - visit_array_start() - at the start `[` of a non-empty array. + * - visit_array_end() - at the end `]` of a non-empty array. + * - visit_empty_array() - when an empty array is encountered. + * + * - visit_object_end() - at the start `]` of a non-empty object. + * - visit_object_start() - at the end `]` of a non-empty object. + * - visit_empty_object() - when an empty object is encountered. + * - visit_key(const uint8_t *key) - when a key in an object field is encountered. key is + * guaranteed to point at the first quote of the string (`"key"`). + * - visit_primitive(const uint8_t *value) - when a value is a string, number, boolean or null. + * - visit_root_primitive(iter, uint8_t *value) - when the top-level value is a string, number, boolean or null. + * + * - increment_count(iter) - each time a value is found in an array or object. + */ + template + simdjson_warn_unused simdjson_inline error_code walk_document(V &visitor) noexcept; + + /** + * Create an iterator capable of walking a JSON document. + * + * The document must have already passed through stage 1. + */ + simdjson_inline json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index); + + /** + * Look at the next token. + * + * Tokens can be strings, numbers, booleans, null, or operators (`[{]},:`)). + * + * They may include invalid JSON as well (such as `1.2.3` or `ture`). + */ + simdjson_inline const uint8_t *peek() const noexcept; + /** + * Advance to the next token. + * + * Tokens can be strings, numbers, booleans, null, or operators (`[{]},:`)). + * + * They may include invalid JSON as well (such as `1.2.3` or `ture`). + */ + simdjson_inline const uint8_t *advance() noexcept; + /** + * Get the remaining length of the document, from the start of the current token. + */ + simdjson_inline size_t remaining_len() const noexcept; + /** + * Check if we are at the end of the document. + * + * If this is true, there are no more tokens. + */ + simdjson_inline bool at_eof() const noexcept; + /** + * Check if we are at the beginning of the document. + */ + simdjson_inline bool at_beginning() const noexcept; + simdjson_inline uint8_t last_structural() const noexcept; + + /** + * Log that a value has been found. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_value(const char *type) const noexcept; + /** + * Log the start of a multipart value. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_start_value(const char *type) const noexcept; + /** + * Log the end of a multipart value. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_end_value(const char *type) const noexcept; + /** + * Log an error. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_error(const char *error) const noexcept; + + template + simdjson_warn_unused simdjson_inline error_code visit_root_primitive(V &visitor, const uint8_t *value) noexcept; + template + simdjson_warn_unused simdjson_inline error_code visit_primitive(V &visitor, const uint8_t *value) noexcept; +}; + +template +simdjson_warn_unused simdjson_inline error_code json_iterator::walk_document(V &visitor) noexcept { + logger::log_start(); + + // + // Start the document + // + if (at_eof()) { return EMPTY; } + log_start_value("document"); + SIMDJSON_TRY( visitor.visit_document_start(*this) ); + + // + // Read first value + // + { + auto value = advance(); + + // Make sure the outer object or array is closed before continuing; otherwise, there are ways we + // could get into memory corruption. See https://github.com/simdjson/simdjson/issues/906 + if (!STREAMING) { + switch (*value) { + case '{': if (last_structural() != '}') { log_value("starting brace unmatched"); return TAPE_ERROR; }; break; + case '[': if (last_structural() != ']') { log_value("starting bracket unmatched"); return TAPE_ERROR; }; break; + } + } + + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_root_primitive(*this, value) ); break; + } + } + goto document_end; + +// +// Object parser states +// +object_begin: + log_start_value("object"); + depth++; + if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; } + dom_parser.is_array[depth] = false; + SIMDJSON_TRY( visitor.visit_object_start(*this) ); + + { + auto key = advance(); + if (*key != '"') { log_error("Object does not start with a key"); return TAPE_ERROR; } + SIMDJSON_TRY( visitor.increment_count(*this) ); + SIMDJSON_TRY( visitor.visit_key(*this, key) ); + } + +object_field: + if (simdjson_unlikely( *advance() != ':' )) { log_error("Missing colon after key in object"); return TAPE_ERROR; } + { + auto value = advance(); + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break; + } + } + +object_continue: + switch (*advance()) { + case ',': + SIMDJSON_TRY( visitor.increment_count(*this) ); + { + auto key = advance(); + if (simdjson_unlikely( *key != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; } + SIMDJSON_TRY( visitor.visit_key(*this, key) ); + } + goto object_field; + case '}': log_end_value("object"); SIMDJSON_TRY( visitor.visit_object_end(*this) ); goto scope_end; + default: log_error("No comma between object fields"); return TAPE_ERROR; + } + +scope_end: + depth--; + if (depth == 0) { goto document_end; } + if (dom_parser.is_array[depth]) { goto array_continue; } + goto object_continue; + +// +// Array parser states +// +array_begin: + log_start_value("array"); + depth++; + if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; } + dom_parser.is_array[depth] = true; + SIMDJSON_TRY( visitor.visit_array_start(*this) ); + SIMDJSON_TRY( visitor.increment_count(*this) ); + +array_value: + { + auto value = advance(); + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break; + } + } + +array_continue: + switch (*advance()) { + case ',': SIMDJSON_TRY( visitor.increment_count(*this) ); goto array_value; + case ']': log_end_value("array"); SIMDJSON_TRY( visitor.visit_array_end(*this) ); goto scope_end; + default: log_error("Missing comma between array values"); return TAPE_ERROR; + } + +document_end: + log_end_value("document"); + SIMDJSON_TRY( visitor.visit_document_end(*this) ); + + dom_parser.next_structural_index = uint32_t(next_structural - &dom_parser.structural_indexes[0]); + + // If we didn't make it to the end, it's an error + if ( !STREAMING && dom_parser.next_structural_index != dom_parser.n_structural_indexes ) { + log_error("More than one JSON value at the root of the document, or extra characters at the end of the JSON!"); + return TAPE_ERROR; + } + + return SUCCESS; + +} // walk_document() + +simdjson_inline json_iterator::json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index) + : buf{_dom_parser.buf}, + next_structural{&_dom_parser.structural_indexes[start_structural_index]}, + dom_parser{_dom_parser} { +} + +simdjson_inline const uint8_t *json_iterator::peek() const noexcept { + return &buf[*(next_structural)]; +} +simdjson_inline const uint8_t *json_iterator::advance() noexcept { + return &buf[*(next_structural++)]; +} +simdjson_inline size_t json_iterator::remaining_len() const noexcept { + return dom_parser.len - *(next_structural-1); +} + +simdjson_inline bool json_iterator::at_eof() const noexcept { + return next_structural == &dom_parser.structural_indexes[dom_parser.n_structural_indexes]; +} +simdjson_inline bool json_iterator::at_beginning() const noexcept { + return next_structural == dom_parser.structural_indexes.get(); +} +simdjson_inline uint8_t json_iterator::last_structural() const noexcept { + return buf[dom_parser.structural_indexes[dom_parser.n_structural_indexes - 1]]; +} + +simdjson_inline void json_iterator::log_value(const char *type) const noexcept { + logger::log_line(*this, "", type, ""); +} + +simdjson_inline void json_iterator::log_start_value(const char *type) const noexcept { + logger::log_line(*this, "+", type, ""); + if (logger::LOG_ENABLED) { logger::log_depth++; } +} + +simdjson_inline void json_iterator::log_end_value(const char *type) const noexcept { + if (logger::LOG_ENABLED) { logger::log_depth--; } + logger::log_line(*this, "-", type, ""); +} + +simdjson_inline void json_iterator::log_error(const char *error) const noexcept { + logger::log_line(*this, "", "ERROR", error); +} + +template +simdjson_warn_unused simdjson_inline error_code json_iterator::visit_root_primitive(V &visitor, const uint8_t *value) noexcept { + switch (*value) { + case '"': return visitor.visit_root_string(*this, value); + case 't': return visitor.visit_root_true_atom(*this, value); + case 'f': return visitor.visit_root_false_atom(*this, value); + case 'n': return visitor.visit_root_null_atom(*this, value); + case '-': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return visitor.visit_root_number(*this, value); + default: + log_error("Document starts with a non-value character"); + return TAPE_ERROR; + } +} +template +simdjson_warn_unused simdjson_inline error_code json_iterator::visit_primitive(V &visitor, const uint8_t *value) noexcept { + // Use the fact that most scalars are going to be either strings or numbers. + if(*value == '"') { + return visitor.visit_string(*this, value); + } else if (((*value - '0') < 10) || (*value == '-')) { + return visitor.visit_number(*this, value); + } + // true, false, null are uncommon. + switch (*value) { + case 't': return visitor.visit_true_atom(*this, value); + case 'f': return visitor.visit_false_atom(*this, value); + case 'n': return visitor.visit_null_atom(*this, value); + default: + log_error("Non-value found when value was expected!"); + return TAPE_ERROR; + } +} + +} // namespace stage2 +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H +/* end file generic/stage2/json_iterator.h for ppc64 */ +/* including generic/stage2/stringparsing.h for ppc64: #include */ +/* begin file generic/stage2/stringparsing.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses +// It is intended to be included multiple times and compiled multiple times + +namespace simdjson { +namespace ppc64 { +namespace { +/// @private +namespace stringparsing { + +// begin copypasta +// These chars yield themselves: " \ / +// b -> backspace, f -> formfeed, n -> newline, r -> cr, t -> horizontal tab +// u not handled in this table as it's complex +static const uint8_t escape_map[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0x22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2f, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x4. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5c, 0, 0, 0, // 0x5. + 0, 0, 0x08, 0, 0, 0, 0x0c, 0, 0, 0, 0, 0, 0, 0, 0x0a, 0, // 0x6. + 0, 0, 0x0d, 0, 0x09, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x7. + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +// handle a unicode codepoint +// write appropriate values into dest +// src will advance 6 bytes or 12 bytes +// dest will advance a variable amount (return via pointer) +// return true if the unicode codepoint was valid +// We work in little-endian then swap at write time +simdjson_warn_unused +simdjson_inline bool handle_unicode_codepoint(const uint8_t **src_ptr, + uint8_t **dst_ptr, bool allow_replacement) { + // Use the default Unicode Character 'REPLACEMENT CHARACTER' (U+FFFD) + constexpr uint32_t substitution_code_point = 0xfffd; + // jsoncharutils::hex_to_u32_nocheck fills high 16 bits of the return value with 1s if the + // conversion isn't valid; we defer the check for this to inside the + // multilingual plane check + uint32_t code_point = jsoncharutils::hex_to_u32_nocheck(*src_ptr + 2); + *src_ptr += 6; + + // If we found a high surrogate, we must + // check for low surrogate for characters + // outside the Basic + // Multilingual Plane. + if (code_point >= 0xd800 && code_point < 0xdc00) { + const uint8_t *src_data = *src_ptr; + /* Compiler optimizations convert this to a single 16-bit load and compare on most platforms */ + if (((src_data[0] << 8) | src_data[1]) != ((static_cast ('\\') << 8) | static_cast ('u'))) { + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } else { + uint32_t code_point_2 = jsoncharutils::hex_to_u32_nocheck(src_data + 2); + + // We have already checked that the high surrogate is valid and + // (code_point - 0xd800) < 1024. + // + // Check that code_point_2 is in the range 0xdc00..0xdfff + // and that code_point_2 was parsed from valid hex. + uint32_t low_bit = code_point_2 - 0xdc00; + if (low_bit >> 10) { + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } else { + code_point = (((code_point - 0xd800) << 10) | low_bit) + 0x10000; + *src_ptr += 6; + } + + } + } else if (code_point >= 0xdc00 && code_point <= 0xdfff) { + // If we encounter a low surrogate (not preceded by a high surrogate) + // then we have an error. + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } + size_t offset = jsoncharutils::codepoint_to_utf8(code_point, *dst_ptr); + *dst_ptr += offset; + return offset > 0; +} + + +// handle a unicode codepoint using the wobbly convention +// https://simonsapin.github.io/wtf-8/ +// write appropriate values into dest +// src will advance 6 bytes or 12 bytes +// dest will advance a variable amount (return via pointer) +// return true if the unicode codepoint was valid +// We work in little-endian then swap at write time +simdjson_warn_unused +simdjson_inline bool handle_unicode_codepoint_wobbly(const uint8_t **src_ptr, + uint8_t **dst_ptr) { + // It is not ideal that this function is nearly identical to handle_unicode_codepoint. + // + // jsoncharutils::hex_to_u32_nocheck fills high 16 bits of the return value with 1s if the + // conversion isn't valid; we defer the check for this to inside the + // multilingual plane check + uint32_t code_point = jsoncharutils::hex_to_u32_nocheck(*src_ptr + 2); + *src_ptr += 6; + // If we found a high surrogate, we must + // check for low surrogate for characters + // outside the Basic + // Multilingual Plane. + if (code_point >= 0xd800 && code_point < 0xdc00) { + const uint8_t *src_data = *src_ptr; + /* Compiler optimizations convert this to a single 16-bit load and compare on most platforms */ + if (((src_data[0] << 8) | src_data[1]) == ((static_cast ('\\') << 8) | static_cast ('u'))) { + uint32_t code_point_2 = jsoncharutils::hex_to_u32_nocheck(src_data + 2); + uint32_t low_bit = code_point_2 - 0xdc00; + if ((low_bit >> 10) == 0) { + code_point = + (((code_point - 0xd800) << 10) | low_bit) + 0x10000; + *src_ptr += 6; + } + } + } + + size_t offset = jsoncharutils::codepoint_to_utf8(code_point, *dst_ptr); + *dst_ptr += offset; + return offset > 0; +} + + +/** + * Unescape a valid UTF-8 string from src to dst, stopping at a final unescaped quote. There + * must be an unescaped quote terminating the string. It returns the final output + * position as pointer. In case of error (e.g., the string has bad escaped codes), + * then null_nullptrptr is returned. It is assumed that the output buffer is large + * enough. E.g., if src points at 'joe"', then dst needs to have four free bytes + + * SIMDJSON_PADDING bytes. + */ +simdjson_warn_unused simdjson_inline uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) { + while (1) { + // Copy the next n bytes, and find the backslash and quote in them. + auto bs_quote = backslash_and_quote::copy_and_find(src, dst); + // If the next thing is the end quote, copy and return + if (bs_quote.has_quote_first()) { + // we encountered quotes first. Move dst to point to quotes and exit + return dst + bs_quote.quote_index(); + } + if (bs_quote.has_backslash()) { + /* find out where the backspace is */ + auto bs_dist = bs_quote.backslash_index(); + uint8_t escape_char = src[bs_dist + 1]; + /* we encountered backslash first. Handle backslash */ + if (escape_char == 'u') { + /* move src/dst up to the start; they will be further adjusted + within the unicode codepoint handling code. */ + src += bs_dist; + dst += bs_dist; + if (!handle_unicode_codepoint(&src, &dst, allow_replacement)) { + return nullptr; + } + } else { + /* simple 1:1 conversion. Will eat bs_dist+2 characters in input and + * write bs_dist+1 characters to output + * note this may reach beyond the part of the buffer we've actually + * seen. I think this is ok */ + uint8_t escape_result = escape_map[escape_char]; + if (escape_result == 0u) { + return nullptr; /* bogus escape value is an error */ + } + dst[bs_dist] = escape_result; + src += bs_dist + 2; + dst += bs_dist + 1; + } + } else { + /* they are the same. Since they can't co-occur, it means we + * encountered neither. */ + src += backslash_and_quote::BYTES_PROCESSED; + dst += backslash_and_quote::BYTES_PROCESSED; + } + } +} + +simdjson_warn_unused simdjson_inline uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) { + // It is not ideal that this function is nearly identical to parse_string. + while (1) { + // Copy the next n bytes, and find the backslash and quote in them. + auto bs_quote = backslash_and_quote::copy_and_find(src, dst); + // If the next thing is the end quote, copy and return + if (bs_quote.has_quote_first()) { + // we encountered quotes first. Move dst to point to quotes and exit + return dst + bs_quote.quote_index(); + } + if (bs_quote.has_backslash()) { + /* find out where the backspace is */ + auto bs_dist = bs_quote.backslash_index(); + uint8_t escape_char = src[bs_dist + 1]; + /* we encountered backslash first. Handle backslash */ + if (escape_char == 'u') { + /* move src/dst up to the start; they will be further adjusted + within the unicode codepoint handling code. */ + src += bs_dist; + dst += bs_dist; + if (!handle_unicode_codepoint_wobbly(&src, &dst)) { + return nullptr; + } + } else { + /* simple 1:1 conversion. Will eat bs_dist+2 characters in input and + * write bs_dist+1 characters to output + * note this may reach beyond the part of the buffer we've actually + * seen. I think this is ok */ + uint8_t escape_result = escape_map[escape_char]; + if (escape_result == 0u) { + return nullptr; /* bogus escape value is an error */ + } + dst[bs_dist] = escape_result; + src += bs_dist + 2; + dst += bs_dist + 1; + } + } else { + /* they are the same. Since they can't co-occur, it means we + * encountered neither. */ + src += backslash_and_quote::BYTES_PROCESSED; + dst += backslash_and_quote::BYTES_PROCESSED; + } + } +} + +} // namespace stringparsing +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H +/* end file generic/stage2/stringparsing.h for ppc64 */ +/* including generic/stage2/structural_iterator.h for ppc64: #include */ +/* begin file generic/stage2/structural_iterator.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { +namespace stage2 { + +class structural_iterator { +public: + const uint8_t* const buf; + uint32_t *next_structural; + dom_parser_implementation &dom_parser; + + // Start a structural + simdjson_inline structural_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index) + : buf{_dom_parser.buf}, + next_structural{&_dom_parser.structural_indexes[start_structural_index]}, + dom_parser{_dom_parser} { + } + // Get the buffer position of the current structural character + simdjson_inline const uint8_t* current() { + return &buf[*(next_structural-1)]; + } + // Get the current structural character + simdjson_inline char current_char() { + return buf[*(next_structural-1)]; + } + // Get the next structural character without advancing + simdjson_inline char peek_next_char() { + return buf[*next_structural]; + } + simdjson_inline const uint8_t* peek() { + return &buf[*next_structural]; + } + simdjson_inline const uint8_t* advance() { + return &buf[*(next_structural++)]; + } + simdjson_inline char advance_char() { + return buf[*(next_structural++)]; + } + simdjson_inline size_t remaining_len() { + return dom_parser.len - *(next_structural-1); + } + + simdjson_inline bool at_end() { + return next_structural == &dom_parser.structural_indexes[dom_parser.n_structural_indexes]; + } + simdjson_inline bool at_beginning() { + return next_structural == dom_parser.structural_indexes.get(); + } +}; + +} // namespace stage2 +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H +/* end file generic/stage2/structural_iterator.h for ppc64 */ +/* including generic/stage2/tape_builder.h for ppc64: #include */ +/* begin file generic/stage2/tape_builder.h for ppc64 */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + + +namespace simdjson { +namespace ppc64 { +namespace { +namespace stage2 { + +struct tape_builder { + template + simdjson_warn_unused static simdjson_inline error_code parse_document( + dom_parser_implementation &dom_parser, + dom::document &doc) noexcept; + + /** Called when a non-empty document starts. */ + simdjson_warn_unused simdjson_inline error_code visit_document_start(json_iterator &iter) noexcept; + /** Called when a non-empty document ends without error. */ + simdjson_warn_unused simdjson_inline error_code visit_document_end(json_iterator &iter) noexcept; + + /** Called when a non-empty array starts. */ + simdjson_warn_unused simdjson_inline error_code visit_array_start(json_iterator &iter) noexcept; + /** Called when a non-empty array ends. */ + simdjson_warn_unused simdjson_inline error_code visit_array_end(json_iterator &iter) noexcept; + /** Called when an empty array is found. */ + simdjson_warn_unused simdjson_inline error_code visit_empty_array(json_iterator &iter) noexcept; + + /** Called when a non-empty object starts. */ + simdjson_warn_unused simdjson_inline error_code visit_object_start(json_iterator &iter) noexcept; + /** + * Called when a key in a field is encountered. + * + * primitive, visit_object_start, visit_empty_object, visit_array_start, or visit_empty_array + * will be called after this with the field value. + */ + simdjson_warn_unused simdjson_inline error_code visit_key(json_iterator &iter, const uint8_t *key) noexcept; + /** Called when a non-empty object ends. */ + simdjson_warn_unused simdjson_inline error_code visit_object_end(json_iterator &iter) noexcept; + /** Called when an empty object is found. */ + simdjson_warn_unused simdjson_inline error_code visit_empty_object(json_iterator &iter) noexcept; + + /** + * Called when a string, number, boolean or null is found. + */ + simdjson_warn_unused simdjson_inline error_code visit_primitive(json_iterator &iter, const uint8_t *value) noexcept; + /** + * Called when a string, number, boolean or null is found at the top level of a document (i.e. + * when there is no array or object and the entire document is a single string, number, boolean or + * null. + * + * This is separate from primitive() because simdjson's normal primitive parsing routines assume + * there is at least one more token after the value, which is only true in an array or object. + */ + simdjson_warn_unused simdjson_inline error_code visit_root_primitive(json_iterator &iter, const uint8_t *value) noexcept; + + simdjson_warn_unused simdjson_inline error_code visit_string(json_iterator &iter, const uint8_t *value, bool key = false) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_number(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_true_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_false_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_null_atom(json_iterator &iter, const uint8_t *value) noexcept; + + simdjson_warn_unused simdjson_inline error_code visit_root_string(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_number(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_true_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_false_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_null_atom(json_iterator &iter, const uint8_t *value) noexcept; + + /** Called each time a new field or element in an array or object is found. */ + simdjson_warn_unused simdjson_inline error_code increment_count(json_iterator &iter) noexcept; + + /** Next location to write to tape */ + tape_writer tape; +private: + /** Next write location in the string buf for stage 2 parsing */ + uint8_t *current_string_buf_loc; + + simdjson_inline tape_builder(dom::document &doc) noexcept; + + simdjson_inline uint32_t next_tape_index(json_iterator &iter) const noexcept; + simdjson_inline void start_container(json_iterator &iter) noexcept; + simdjson_warn_unused simdjson_inline error_code end_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept; + simdjson_warn_unused simdjson_inline error_code empty_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept; + simdjson_inline uint8_t *on_start_string(json_iterator &iter) noexcept; + simdjson_inline void on_end_string(uint8_t *dst) noexcept; +}; // struct tape_builder + +template +simdjson_warn_unused simdjson_inline error_code tape_builder::parse_document( + dom_parser_implementation &dom_parser, + dom::document &doc) noexcept { + dom_parser.doc = &doc; + json_iterator iter(dom_parser, STREAMING ? dom_parser.next_structural_index : 0); + tape_builder builder(doc); + return iter.walk_document(builder); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_primitive(json_iterator &iter, const uint8_t *value) noexcept { + return iter.visit_root_primitive(*this, value); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_primitive(json_iterator &iter, const uint8_t *value) noexcept { + return iter.visit_primitive(*this, value); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_empty_object(json_iterator &iter) noexcept { + return empty_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_empty_array(json_iterator &iter) noexcept { + return empty_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_document_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_object_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_array_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_object_end(json_iterator &iter) noexcept { + return end_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_array_end(json_iterator &iter) noexcept { + return end_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_document_end(json_iterator &iter) noexcept { + constexpr uint32_t start_tape_index = 0; + tape.append(start_tape_index, internal::tape_type::ROOT); + tape_writer::write(iter.dom_parser.doc->tape[start_tape_index], next_tape_index(iter), internal::tape_type::ROOT); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_key(json_iterator &iter, const uint8_t *key) noexcept { + return visit_string(iter, key, true); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::increment_count(json_iterator &iter) noexcept { + iter.dom_parser.open_containers[iter.depth].count++; // we have a key value pair in the object at parser.dom_parser.depth - 1 + return SUCCESS; +} + +simdjson_inline tape_builder::tape_builder(dom::document &doc) noexcept : tape{doc.tape.get()}, current_string_buf_loc{doc.string_buf.get()} {} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_string(json_iterator &iter, const uint8_t *value, bool key) noexcept { + iter.log_value(key ? "key" : "string"); + uint8_t *dst = on_start_string(iter); + dst = stringparsing::parse_string(value+1, dst, false); // We do not allow replacement when the escape characters are invalid. + if (dst == nullptr) { + iter.log_error("Invalid escape in string"); + return STRING_ERROR; + } + on_end_string(dst); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(json_iterator &iter, const uint8_t *value) noexcept { + return visit_string(iter, value); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("number"); + return numberparsing::parse_number(value, tape); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept { + // + // We need to make a copy to make sure that the string is space terminated. + // This is not about padding the input, which should already padded up + // to len + SIMDJSON_PADDING. However, we have no control at this stage + // on how the padding was done. What if the input string was padded with nulls? + // It is quite common for an input string to have an extra null character (C string). + // We do not want to allow 9\0 (where \0 is the null character) inside a JSON + // document, but the string "9\0" by itself is fine. So we make a copy and + // pad the input with spaces when we know that there is just one input element. + // This copy is relatively expensive, but it will almost never be called in + // practice unless you are in the strange scenario where you have many JSON + // documents made of single atoms. + // + std::unique_ptrcopy(new (std::nothrow) uint8_t[iter.remaining_len() + SIMDJSON_PADDING]); + if (copy.get() == nullptr) { return MEMALLOC; } + std::memcpy(copy.get(), value, iter.remaining_len()); + std::memset(copy.get() + iter.remaining_len(), ' ', SIMDJSON_PADDING); + error_code error = visit_number(iter, copy.get()); + return error; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_true_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("true"); + if (!atomparsing::is_valid_true_atom(value)) { return T_ATOM_ERROR; } + tape.append(0, internal::tape_type::TRUE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_true_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("true"); + if (!atomparsing::is_valid_true_atom(value, iter.remaining_len())) { return T_ATOM_ERROR; } + tape.append(0, internal::tape_type::TRUE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_false_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("false"); + if (!atomparsing::is_valid_false_atom(value)) { return F_ATOM_ERROR; } + tape.append(0, internal::tape_type::FALSE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_false_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("false"); + if (!atomparsing::is_valid_false_atom(value, iter.remaining_len())) { return F_ATOM_ERROR; } + tape.append(0, internal::tape_type::FALSE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_null_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("null"); + if (!atomparsing::is_valid_null_atom(value)) { return N_ATOM_ERROR; } + tape.append(0, internal::tape_type::NULL_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_null_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("null"); + if (!atomparsing::is_valid_null_atom(value, iter.remaining_len())) { return N_ATOM_ERROR; } + tape.append(0, internal::tape_type::NULL_VALUE); + return SUCCESS; +} + +// private: + +simdjson_inline uint32_t tape_builder::next_tape_index(json_iterator &iter) const noexcept { + return uint32_t(tape.next_tape_loc - iter.dom_parser.doc->tape.get()); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::empty_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept { + auto start_index = next_tape_index(iter); + tape.append(start_index+2, start); + tape.append(start_index, end); + return SUCCESS; +} + +simdjson_inline void tape_builder::start_container(json_iterator &iter) noexcept { + iter.dom_parser.open_containers[iter.depth].tape_index = next_tape_index(iter); + iter.dom_parser.open_containers[iter.depth].count = 0; + tape.skip(); // We don't actually *write* the start element until the end. +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::end_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept { + // Write the ending tape element, pointing at the start location + const uint32_t start_tape_index = iter.dom_parser.open_containers[iter.depth].tape_index; + tape.append(start_tape_index, end); + // Write the start tape element, pointing at the end location (and including count) + // count can overflow if it exceeds 24 bits... so we saturate + // the convention being that a cnt of 0xffffff or more is undetermined in value (>= 0xffffff). + const uint32_t count = iter.dom_parser.open_containers[iter.depth].count; + const uint32_t cntsat = count > 0xFFFFFF ? 0xFFFFFF : count; + tape_writer::write(iter.dom_parser.doc->tape[start_tape_index], next_tape_index(iter) | (uint64_t(cntsat) << 32), start); + return SUCCESS; +} + +simdjson_inline uint8_t *tape_builder::on_start_string(json_iterator &iter) noexcept { + // we advance the point, accounting for the fact that we have a NULL termination + tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::STRING); + return current_string_buf_loc + sizeof(uint32_t); +} + +simdjson_inline void tape_builder::on_end_string(uint8_t *dst) noexcept { + uint32_t str_length = uint32_t(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 + // Currently unneeded because we refuse to parse docs larger or equal to 4GB. + memcpy(current_string_buf_loc, &str_length, sizeof(uint32_t)); + // NULL termination is still handy if you expect all your strings to + // be NULL terminated? It comes at a small cost + *dst = 0; + current_string_buf_loc = dst + 1; +} + +} // namespace stage2 +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H +/* end file generic/stage2/tape_builder.h for ppc64 */ +/* end file generic/stage2/amalgamated.h for ppc64 */ + +// +// Stage 1 +// +namespace simdjson { +namespace ppc64 { + +simdjson_warn_unused error_code implementation::create_dom_parser_implementation( + size_t capacity, + size_t max_depth, + std::unique_ptr& dst +) const noexcept { + dst.reset( new (std::nothrow) dom_parser_implementation() ); + if (!dst) { return MEMALLOC; } + if (auto err = dst->set_capacity(capacity)) + return err; + if (auto err = dst->set_max_depth(max_depth)) + return err; + return SUCCESS; +} + +namespace { + +using namespace simd; + +simdjson_inline json_character_block json_character_block::classify(const simd::simd8x64& in) { + const simd8 table1(16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 12, 1, 2, 9, 0, 0); + const simd8 table2(8, 0, 18, 4, 0, 1, 0, 1, 0, 0, 0, 3, 2, 1, 0, 0); + + simd8x64 v( + (in.chunks[0] & 0xf).lookup_16(table1) & (in.chunks[0].shr<4>()).lookup_16(table2), + (in.chunks[1] & 0xf).lookup_16(table1) & (in.chunks[1].shr<4>()).lookup_16(table2), + (in.chunks[2] & 0xf).lookup_16(table1) & (in.chunks[2].shr<4>()).lookup_16(table2), + (in.chunks[3] & 0xf).lookup_16(table1) & (in.chunks[3].shr<4>()).lookup_16(table2) + ); + + uint64_t op = simd8x64( + v.chunks[0].any_bits_set(0x7), + v.chunks[1].any_bits_set(0x7), + v.chunks[2].any_bits_set(0x7), + v.chunks[3].any_bits_set(0x7) + ).to_bitmask(); + + uint64_t whitespace = simd8x64( + v.chunks[0].any_bits_set(0x18), + v.chunks[1].any_bits_set(0x18), + v.chunks[2].any_bits_set(0x18), + v.chunks[3].any_bits_set(0x18) + ).to_bitmask(); + + return { whitespace, op }; +} + +simdjson_inline bool is_ascii(const simd8x64& input) { + // careful: 0x80 is not ascii. + return input.reduce_or().saturating_sub(0x7fu).bits_not_set_anywhere(); +} + +simdjson_unused simdjson_inline simd8 must_be_continuation(const simd8 prev1, const simd8 prev2, const simd8 prev3) { + simd8 is_second_byte = prev1.saturating_sub(0xc0u-1); // Only 11______ will be > 0 + simd8 is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0 + simd8 is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0 + // Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine. + return simd8(is_second_byte | is_third_byte | is_fourth_byte) > int8_t(0); +} + +simdjson_inline simd8 must_be_2_3_continuation(const simd8 prev2, const simd8 prev3) { + simd8 is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0 + simd8 is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0 + // Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine. + return simd8(is_third_byte | is_fourth_byte) > int8_t(0); +} + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +// +// Stage 2 +// + +// +// Implementation-specific overrides +// +namespace simdjson { +namespace ppc64 { + +simdjson_warn_unused error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept { + return ppc64::stage1::json_minifier::minify<64>(buf, len, dst, dst_len); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, stage1_mode streaming) noexcept { + this->buf = _buf; + this->len = _len; + return ppc64::stage1::json_structural_indexer::index<64>(buf, len, *this, streaming); +} + +simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t len) const noexcept { + return ppc64::stage1::generic_validate_utf8(buf,len); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { + return stage2::tape_builder::parse_document(*this, _doc); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { + return stage2::tape_builder::parse_document(*this, _doc); +} + +simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { + return ppc64::stringparsing::parse_string(src, dst, replacement_char); +} + +simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept { + return ppc64::stringparsing::parse_wobbly_string(src, dst); +} + +simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { + auto error = stage1(_buf, _len, stage1_mode::regular); + if (error) { return error; } + return stage2(_doc); +} + +} // namespace ppc64 +} // namespace simdjson + +/* including simdjson/ppc64/end.h: #include */ +/* begin file simdjson/ppc64/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#undef SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT +/* undefining SIMDJSON_IMPLEMENTATION from "ppc64" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/ppc64/end.h */ + +#endif // SIMDJSON_SRC_PPC64_CPP +/* end file ppc64.cpp */ +#endif +#if SIMDJSON_IMPLEMENTATION_WESTMERE +/* including westmere.cpp: #include */ +/* begin file westmere.cpp */ +#ifndef SIMDJSON_SRC_WESTMERE_CPP +#define SIMDJSON_SRC_WESTMERE_CPP + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +/* including simdjson/westmere.h: #include */ +/* begin file simdjson/westmere.h */ +#ifndef SIMDJSON_WESTMERE_H +#define SIMDJSON_WESTMERE_H + +/* including simdjson/westmere/begin.h: #include "simdjson/westmere/begin.h" */ +/* begin file simdjson/westmere/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "westmere" */ +#define SIMDJSON_IMPLEMENTATION westmere +/* including simdjson/westmere/base.h: #include "simdjson/westmere/base.h" */ +/* begin file simdjson/westmere/base.h */ +#ifndef SIMDJSON_WESTMERE_BASE_H +#define SIMDJSON_WESTMERE_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_WESTMERE +namespace simdjson { +/** + * Implementation for Westmere (Intel SSE4.2). + */ +namespace westmere { + +class implementation; + +namespace { +namespace simd { + +template struct simd8; +template struct simd8x64; + +} // namespace simd +} // unnamed namespace + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BASE_H +/* end file simdjson/westmere/base.h */ +/* including simdjson/westmere/intrinsics.h: #include "simdjson/westmere/intrinsics.h" */ +/* begin file simdjson/westmere/intrinsics.h */ +#ifndef SIMDJSON_WESTMERE_INTRINSICS_H +#define SIMDJSON_WESTMERE_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + */ +#include // for _mm_alignr_epi8 +#include // for _mm_clmulepi64_si128 +#endif + +static_assert(sizeof(__m128i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for westmere"); + +#endif // SIMDJSON_WESTMERE_INTRINSICS_H +/* end file simdjson/westmere/intrinsics.h */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_WESTMERE +SIMDJSON_TARGET_REGION("sse4.2,pclmul,popcnt") +#endif + +/* including simdjson/westmere/bitmanipulation.h: #include "simdjson/westmere/bitmanipulation.h" */ +/* begin file simdjson/westmere/bitmanipulation.h */ +#ifndef SIMDJSON_WESTMERE_BITMANIPULATION_H +#define SIMDJSON_WESTMERE_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num-1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// SIMDJSON_REGULAR_VISUAL_STUDIO +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BITMANIPULATION_H +/* end file simdjson/westmere/bitmanipulation.h */ +/* including simdjson/westmere/bitmask.h: #include "simdjson/westmere/bitmask.h" */ +/* begin file simdjson/westmere/bitmask.h */ +#ifndef SIMDJSON_WESTMERE_BITMASK_H +#define SIMDJSON_WESTMERE_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(const uint64_t bitmask) { + // There should be no such thing with a processing supporting avx2 + // but not clmul. + __m128i all_ones = _mm_set1_epi8('\xFF'); + __m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0ULL, bitmask), all_ones, 0); + return _mm_cvtsi128_si64(result); +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BITMASK_H +/* end file simdjson/westmere/bitmask.h */ +/* including simdjson/westmere/numberparsing_defs.h: #include "simdjson/westmere/numberparsing_defs.h" */ +/* begin file simdjson/westmere/numberparsing_defs.h */ +#ifndef SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H +#define SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H + +/* including simdjson/westmere/base.h: #include "simdjson/westmere/base.h" */ +/* begin file simdjson/westmere/base.h */ +#ifndef SIMDJSON_WESTMERE_BASE_H +#define SIMDJSON_WESTMERE_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_WESTMERE +namespace simdjson { +/** + * Implementation for Westmere (Intel SSE4.2). + */ +namespace westmere { + +class implementation; + +namespace { +namespace simd { + +template struct simd8; +template struct simd8x64; + +} // namespace simd +} // unnamed namespace + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BASE_H +/* end file simdjson/westmere/base.h */ +/* including simdjson/westmere/intrinsics.h: #include "simdjson/westmere/intrinsics.h" */ +/* begin file simdjson/westmere/intrinsics.h */ +#ifndef SIMDJSON_WESTMERE_INTRINSICS_H +#define SIMDJSON_WESTMERE_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + */ +#include // for _mm_alignr_epi8 +#include // for _mm_clmulepi64_si128 +#endif + +static_assert(sizeof(__m128i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for westmere"); + +#endif // SIMDJSON_WESTMERE_INTRINSICS_H +/* end file simdjson/westmere/intrinsics.h */ + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace numberparsing { + +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + // this actually computes *16* values so we are being wasteful. + const __m128i ascii0 = _mm_set1_epi8('0'); + const __m128i mul_1_10 = + _mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1); + const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1); + const __m128i mul_1_10000 = + _mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1); + const __m128i input = _mm_sub_epi8( + _mm_loadu_si128(reinterpret_cast(chars)), ascii0); + const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10); + const __m128i t2 = _mm_madd_epi16(t1, mul_1_100); + const __m128i t3 = _mm_packus_epi32(t2, t2); + const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000); + return _mm_cvtsi128_si32( + t4); // only captures the sum of the first 8 digits, drop the rest +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace westmere +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H +/* end file simdjson/westmere/numberparsing_defs.h */ +/* including simdjson/westmere/simd.h: #include "simdjson/westmere/simd.h" */ +/* begin file simdjson/westmere/simd.h */ +#ifndef SIMDJSON_WESTMERE_SIMD_H +#define SIMDJSON_WESTMERE_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace simd { + + template + struct base { + __m128i value; + + // Zero constructor + simdjson_inline base() : value{__m128i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m128i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m128i&() const { return this->value; } + simdjson_inline operator __m128i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm_or_si128(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm_and_si128(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm_xor_si128(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm_andnot_si128(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + template> + struct base8: base> { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m128i _value) : base>(_value) {} + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return _mm_cmpeq_epi8(lhs, rhs); } + + static const int SIZE = sizeof(base>::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return _mm_alignr_epi8(*this, prev_chunk, 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m128i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { return _mm_movemask_epi8(*this); } + simdjson_inline bool any() const { return !_mm_testz_si128(*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm_setzero_si128(); } + static simdjson_inline simd8 load(const T values[16]) { + return _mm_loadu_si128(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m128i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[16]) const { return _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), *this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 16 - count_ones(mask) bytes of the result are significant but 16 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + __m128i shufmask = _mm_set_epi64x(thintable_epi8[mask2], thintable_epi8[mask1]); + // we increment by 0x08 the second half of the mask + shufmask = + _mm_add_epi8(shufmask, _mm_set_epi32(0x08080808, 0x08080808, 0, 0)); + // this is the version "nearly pruned" + __m128i pruned = _mm_shuffle_epi8(*this, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + __m128i compactmask = + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop1 * 8)); + __m128i answer = _mm_shuffle_epi8(pruned, compactmask); + _mm_storeu_si128(reinterpret_cast<__m128i *>(output), answer); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epi8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return _mm_cmpgt_epi8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm_cmpgt_epi8(other, *this); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epu8(*this, other); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline simd8 operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline simd8 operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return *this == uint8_t(0); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + simdjson_inline bool is_ascii() const { return _mm_movemask_epi8(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { return _mm_testz_si128(*this, *this); } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return _mm_testz_si128(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline int get_bit() const { return _mm_movemask_epi8(_mm_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, "Westmere kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, const simd8 chunk2, const simd8 chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+16), simd8::load(ptr+32), simd8::load(ptr+48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + this->chunks[2].store(ptr+sizeof(simd8)*2); + this->chunks[3].store(ptr+sizeof(simd8)*3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | (this->chunks[2] | this->chunks[3]); + } + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + this->chunks[0].compress(uint16_t(mask), output); + this->chunks[1].compress(uint16_t(mask >> 16), output + 16 - count_ones(mask & 0xFFFF)); + this->chunks[2].compress(uint16_t(mask >> 32), output + 32 - count_ones(mask & 0xFFFFFFFF)); + this->chunks[3].compress(uint16_t(mask >> 48), output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); + return 64 - count_ones(mask); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r0 = uint32_t(this->chunks[0].to_bitmask() ); + uint64_t r1 = this->chunks[1].to_bitmask() ; + uint64_t r2 = this->chunks[2].to_bitmask() ; + uint64_t r3 = this->chunks[3].to_bitmask() ; + return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask, + this->chunks[2] == mask, + this->chunks[3] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64( + this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1], + this->chunks[2] == other.chunks[2], + this->chunks[3] == other.chunks[3] + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask, + this->chunks[2] <= mask, + this->chunks[3] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_SIMD_INPUT_H +/* end file simdjson/westmere/simd.h */ +/* including simdjson/westmere/stringparsing_defs.h: #include "simdjson/westmere/stringparsing_defs.h" */ +/* begin file simdjson/westmere/stringparsing_defs.h */ +#ifndef SIMDJSON_WESTMERE_STRINGPARSING_DEFS_H +#define SIMDJSON_WESTMERE_STRINGPARSING_DEFS_H + +/* including simdjson/westmere/bitmanipulation.h: #include "simdjson/westmere/bitmanipulation.h" */ +/* begin file simdjson/westmere/bitmanipulation.h */ +#ifndef SIMDJSON_WESTMERE_BITMANIPULATION_H +#define SIMDJSON_WESTMERE_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num-1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// SIMDJSON_REGULAR_VISUAL_STUDIO +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BITMANIPULATION_H +/* end file simdjson/westmere/bitmanipulation.h */ +/* including simdjson/westmere/simd.h: #include "simdjson/westmere/simd.h" */ +/* begin file simdjson/westmere/simd.h */ +#ifndef SIMDJSON_WESTMERE_SIMD_H +#define SIMDJSON_WESTMERE_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace simd { + + template + struct base { + __m128i value; + + // Zero constructor + simdjson_inline base() : value{__m128i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m128i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m128i&() const { return this->value; } + simdjson_inline operator __m128i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm_or_si128(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm_and_si128(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm_xor_si128(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm_andnot_si128(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + template> + struct base8: base> { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m128i _value) : base>(_value) {} + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return _mm_cmpeq_epi8(lhs, rhs); } + + static const int SIZE = sizeof(base>::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return _mm_alignr_epi8(*this, prev_chunk, 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m128i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { return _mm_movemask_epi8(*this); } + simdjson_inline bool any() const { return !_mm_testz_si128(*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm_setzero_si128(); } + static simdjson_inline simd8 load(const T values[16]) { + return _mm_loadu_si128(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m128i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[16]) const { return _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), *this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 16 - count_ones(mask) bytes of the result are significant but 16 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + __m128i shufmask = _mm_set_epi64x(thintable_epi8[mask2], thintable_epi8[mask1]); + // we increment by 0x08 the second half of the mask + shufmask = + _mm_add_epi8(shufmask, _mm_set_epi32(0x08080808, 0x08080808, 0, 0)); + // this is the version "nearly pruned" + __m128i pruned = _mm_shuffle_epi8(*this, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + __m128i compactmask = + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop1 * 8)); + __m128i answer = _mm_shuffle_epi8(pruned, compactmask); + _mm_storeu_si128(reinterpret_cast<__m128i *>(output), answer); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epi8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return _mm_cmpgt_epi8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm_cmpgt_epi8(other, *this); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epu8(*this, other); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline simd8 operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline simd8 operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return *this == uint8_t(0); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + simdjson_inline bool is_ascii() const { return _mm_movemask_epi8(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { return _mm_testz_si128(*this, *this); } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return _mm_testz_si128(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline int get_bit() const { return _mm_movemask_epi8(_mm_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, "Westmere kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, const simd8 chunk2, const simd8 chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+16), simd8::load(ptr+32), simd8::load(ptr+48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + this->chunks[2].store(ptr+sizeof(simd8)*2); + this->chunks[3].store(ptr+sizeof(simd8)*3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | (this->chunks[2] | this->chunks[3]); + } + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + this->chunks[0].compress(uint16_t(mask), output); + this->chunks[1].compress(uint16_t(mask >> 16), output + 16 - count_ones(mask & 0xFFFF)); + this->chunks[2].compress(uint16_t(mask >> 32), output + 32 - count_ones(mask & 0xFFFFFFFF)); + this->chunks[3].compress(uint16_t(mask >> 48), output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); + return 64 - count_ones(mask); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r0 = uint32_t(this->chunks[0].to_bitmask() ); + uint64_t r1 = this->chunks[1].to_bitmask() ; + uint64_t r2 = this->chunks[2].to_bitmask() ; + uint64_t r3 = this->chunks[3].to_bitmask() ; + return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask, + this->chunks[2] == mask, + this->chunks[3] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64( + this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1], + this->chunks[2] == other.chunks[2], + this->chunks[3] == other.chunks[3] + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask, + this->chunks[2] <= mask, + this->chunks[3] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_SIMD_INPUT_H +/* end file simdjson/westmere/simd.h */ + +namespace simdjson { +namespace westmere { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return bs_bits != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 31 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v0(src); + simd8 v1(src + 16); + v0.store(dst); + v1.store(dst + 16); + uint64_t bs_and_quote = simd8x64(v0 == '\\', v1 == '\\', v0 == '"', v1 == '"').to_bitmask(); + return { + uint32_t(bs_and_quote), // bs_bits + uint32_t(bs_and_quote >> 32) // quote_bits + }; +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_STRINGPARSING_DEFS_H +/* end file simdjson/westmere/stringparsing_defs.h */ +/* end file simdjson/westmere/begin.h */ +/* including simdjson/generic/amalgamated.h for westmere: #include "simdjson/generic/amalgamated.h" */ +/* begin file simdjson/generic/amalgamated.h for westmere */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_DEPENDENCIES_H) +#error simdjson/generic/dependencies.h must be included before simdjson/generic/amalgamated.h! +#endif + +/* including simdjson/generic/base.h for westmere: #include "simdjson/generic/base.h" */ +/* begin file simdjson/generic/base.h for westmere */ +#ifndef SIMDJSON_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): // If we haven't got an implementation yet, we're in the editor, editing a generic file! Just */ +/* amalgamation skipped (editor-only): // use the most advanced one we can so the most possible stuff can be tested. */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation_detection.h" */ +/* amalgamation skipped (editor-only): #if SIMDJSON_IMPLEMENTATION_ICELAKE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_HASWELL */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_WESTMERE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_ARM64 */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_PPC64 */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_FALLBACK */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/begin.h" */ +/* amalgamation skipped (editor-only): #else */ +/* amalgamation skipped (editor-only): #error "All possible implementations (including fallback) have been disabled! simdjson will not run." */ +/* amalgamation skipped (editor-only): #endif */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { + +struct open_container; +class dom_parser_implementation; + +/** + * The type of a JSON number + */ +enum class number_type { + floating_point_number=1, /// a binary64 number + signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + unsigned_integer /// a positive integer larger or equal to 1<<63 +}; + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_BASE_H +/* end file simdjson/generic/base.h for westmere */ +/* including simdjson/generic/jsoncharutils.h for westmere: #include "simdjson/generic/jsoncharutils.h" */ +/* begin file simdjson/generic/jsoncharutils.h for westmere */ +#ifndef SIMDJSON_GENERIC_JSONCHARUTILS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_JSONCHARUTILS_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/jsoncharutils_tables.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace jsoncharutils { + +// return non-zero if not a structural or whitespace char +// zero otherwise +simdjson_inline uint32_t is_not_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace_negated[c]; +} + +simdjson_inline uint32_t is_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace[c]; +} + +// returns a value with the high 16 bits set if not valid +// otherwise returns the conversion of the 4 hex digits at src into the bottom +// 16 bits of the 32-bit return register +// +// see +// https://lemire.me/blog/2019/04/17/parsing-short-hexadecimal-strings-efficiently/ +static inline uint32_t hex_to_u32_nocheck( + const uint8_t *src) { // strictly speaking, static inline is a C-ism + uint32_t v1 = internal::digit_to_val32[630 + src[0]]; + uint32_t v2 = internal::digit_to_val32[420 + src[1]]; + uint32_t v3 = internal::digit_to_val32[210 + src[2]]; + uint32_t v4 = internal::digit_to_val32[0 + src[3]]; + return v1 | v2 | v3 | v4; +} + +// given a code point cp, writes to c +// the utf-8 code, outputting the length in +// bytes, if the length is zero, the code point +// is invalid +// +// This can possibly be made faster using pdep +// and clz and table lookups, but JSON documents +// have few escaped code points, and the following +// function looks cheap. +// +// Note: we assume that surrogates are treated separately +// +simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) { + if (cp <= 0x7F) { + c[0] = uint8_t(cp); + return 1; // ascii + } + if (cp <= 0x7FF) { + c[0] = uint8_t((cp >> 6) + 192); + c[1] = uint8_t((cp & 63) + 128); + return 2; // universal plane + // Surrogates are treated elsewhere... + //} //else if (0xd800 <= cp && cp <= 0xdfff) { + // return 0; // surrogates // could put assert here + } else if (cp <= 0xFFFF) { + c[0] = uint8_t((cp >> 12) + 224); + c[1] = uint8_t(((cp >> 6) & 63) + 128); + c[2] = uint8_t((cp & 63) + 128); + return 3; + } else if (cp <= 0x10FFFF) { // if you know you have a valid code point, this + // is not needed + c[0] = uint8_t((cp >> 18) + 240); + c[1] = uint8_t(((cp >> 12) & 63) + 128); + c[2] = uint8_t(((cp >> 6) & 63) + 128); + c[3] = uint8_t((cp & 63) + 128); + return 4; + } + // will return 0 when the code point was too large. + return 0; // bad r +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +} // namespace jsoncharutils +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_JSONCHARUTILS_H +/* end file simdjson/generic/jsoncharutils.h for westmere */ +/* including simdjson/generic/atomparsing.h for westmere: #include "simdjson/generic/atomparsing.h" */ +/* begin file simdjson/generic/atomparsing.h for westmere */ +#ifndef SIMDJSON_GENERIC_ATOMPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ATOMPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace westmere { +namespace { +/// @private +namespace atomparsing { + +// The string_to_uint32 is exclusively used to map literal strings to 32-bit values. +// We use memcpy instead of a pointer cast to avoid undefined behaviors since we cannot +// be certain that the character pointer will be properly aligned. +// You might think that using memcpy makes this function expensive, but you'd be wrong. +// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false"); +// to the compile-time constant 1936482662. +simdjson_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; } + + +// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive. +// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about. +simdjson_warn_unused +simdjson_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) { + uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++) + static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes"); + std::memcpy(&srcval, src, sizeof(uint32_t)); + return srcval ^ string_to_uint32(atom); +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src) { + return (str4ncmp(src, "true") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_true_atom(src); } + else if (len == 4) { return !str4ncmp(src, "true"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src) { + return (str4ncmp(src+1, "alse") | jsoncharutils::is_not_structural_or_whitespace(src[5])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src, size_t len) { + if (len > 5) { return is_valid_false_atom(src); } + else if (len == 5) { return !str4ncmp(src+1, "alse"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src) { + return (str4ncmp(src, "null") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_null_atom(src); } + else if (len == 4) { return !str4ncmp(src, "null"); } + else { return false; } +} + +} // namespace atomparsing +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ATOMPARSING_H +/* end file simdjson/generic/atomparsing.h for westmere */ +/* including simdjson/generic/dom_parser_implementation.h for westmere: #include "simdjson/generic/dom_parser_implementation.h" */ +/* begin file simdjson/generic/dom_parser_implementation.h for westmere */ +#ifndef SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { + +// expectation: sizeof(open_container) = 64/8. +struct open_container { + uint32_t tape_index; // where, on the tape, does the scope ([,{) begins + uint32_t count; // how many elements in the scope +}; // struct open_container + +static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits"); + +class dom_parser_implementation final : public internal::dom_parser_implementation { +public: + /** Tape location of each open { or [ */ + std::unique_ptr open_containers{}; + /** Whether each open container is a [ or { */ + std::unique_ptr is_array{}; + /** Buffer passed to stage 1 */ + const uint8_t *buf{}; + /** Length passed to stage 1 */ + size_t len{0}; + /** Document passed to stage 2 */ + dom::document *doc{}; + + inline dom_parser_implementation() noexcept; + inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; + inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; + dom_parser_implementation(const dom_parser_implementation &) = delete; + dom_parser_implementation &operator=(const dom_parser_implementation &) = delete; + + simdjson_warn_unused error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage1(const uint8_t *buf, size_t len, stage1_mode partial) noexcept final; + simdjson_warn_unused error_code stage2(dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage2_next(dom::document &doc) noexcept final; + simdjson_warn_unused uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept final; + simdjson_warn_unused uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept final; + inline simdjson_warn_unused error_code set_capacity(size_t capacity) noexcept final; + inline simdjson_warn_unused error_code set_max_depth(size_t max_depth) noexcept final; +private: + simdjson_inline simdjson_warn_unused error_code set_capacity_stage1(size_t capacity); + +}; + +} // namespace westmere +} // namespace simdjson + +namespace simdjson { +namespace westmere { + +inline dom_parser_implementation::dom_parser_implementation() noexcept = default; +inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; +inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; + +// Leaving these here so they can be inlined if so desired +inline simdjson_warn_unused error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept { + if(capacity > SIMDJSON_MAXSIZE_BYTES) { return CAPACITY; } + // Stage 1 index output + size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7; + structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] ); + if (!structural_indexes) { _capacity = 0; return MEMALLOC; } + structural_indexes[0] = 0; + n_structural_indexes = 0; + + _capacity = capacity; + return SUCCESS; +} + +inline simdjson_warn_unused error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept { + // Stage 2 stacks + open_containers.reset(new (std::nothrow) open_container[max_depth]); + is_array.reset(new (std::nothrow) bool[max_depth]); + if (!is_array || !open_containers) { _max_depth = 0; return MEMALLOC; } + + _max_depth = max_depth; + return SUCCESS; +} + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file simdjson/generic/dom_parser_implementation.h for westmere */ +/* including simdjson/generic/implementation_simdjson_result_base.h for westmere: #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base.h for westmere */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { + +// This is a near copy of include/error.h's implementation_simdjson_result_base, except it doesn't use std::pair +// so we can avoid inlining errors +// TODO reconcile these! +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + * + * This is a base class for implementations that want to add functions to the result type for + * chaining. + * + * Override like: + * + * struct simdjson_result : public internal::implementation_simdjson_result_base { + * simdjson_result() noexcept : internal::implementation_simdjson_result_base() {} + * simdjson_result(error_code error) noexcept : internal::implementation_simdjson_result_base(error) {} + * simdjson_result(T &&value) noexcept : internal::implementation_simdjson_result_base(std::forward(value)) {} + * simdjson_result(T &&value, error_code error) noexcept : internal::implementation_simdjson_result_base(value, error) {} + * // Your extra methods here + * } + * + * Then any method returning simdjson_result will be chainable with your methods. + */ +template +struct implementation_simdjson_result_base { + + /** + * Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline implementation_simdjson_result_base() noexcept = default; + + /** + * Create a new error result. + */ + simdjson_inline implementation_simdjson_result_base(error_code error) noexcept; + + /** + * Create a new successful result. + */ + simdjson_inline implementation_simdjson_result_base(T &&value) noexcept; + + /** + * Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline implementation_simdjson_result_base(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); + + +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T& value_unsafe() & noexcept; + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; +protected: + /** users should never directly access first and second. **/ + T first{}; /** Users should never directly access 'first'. **/ + error_code second{UNINITIALIZED}; /** Users should never directly access 'second'. **/ +}; // struct implementation_simdjson_result_base + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H +/* end file simdjson/generic/implementation_simdjson_result_base.h for westmere */ +/* including simdjson/generic/numberparsing.h for westmere: #include "simdjson/generic/numberparsing.h" */ +/* begin file simdjson/generic/numberparsing.h for westmere */ +#ifndef SIMDJSON_GENERIC_NUMBERPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_NUMBERPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include +#include + +namespace simdjson { +namespace westmere { +namespace numberparsing { + +#ifdef JSON_TEST_NUMBERS +#define INVALID_NUMBER(SRC) (found_invalid_number((SRC)), NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (found_integer((VALUE), (SRC)), (WRITER).append_s64((VALUE))) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (found_unsigned_integer((VALUE), (SRC)), (WRITER).append_u64((VALUE))) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (found_float((VALUE), (SRC)), (WRITER).append_double((VALUE))) +#else +#define INVALID_NUMBER(SRC) (NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (WRITER).append_s64((VALUE)) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (WRITER).append_u64((VALUE)) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (WRITER).append_double((VALUE)) +#endif + +namespace { + +// Convert a mantissa, an exponent and a sign bit into an ieee64 double. +// The real_exponent needs to be in [0, 2046] (technically real_exponent = 2047 would be acceptable). +// The mantissa should be in [0,1<<53). The bit at index (1ULL << 52) while be zeroed. +simdjson_inline double to_double(uint64_t mantissa, uint64_t real_exponent, bool negative) { + double d; + mantissa &= ~(1ULL << 52); + mantissa |= real_exponent << 52; + mantissa |= ((static_cast(negative)) << 63); + std::memcpy(&d, &mantissa, sizeof(d)); + return d; +} + +// Attempts to compute i * 10^(power) exactly; and if "negative" is +// true, negate the result. +// This function will only work in some cases, when it does not work, success is +// set to false. This should work *most of the time* (like 99% of the time). +// We assume that power is in the [smallest_power, +// largest_power] interval: the caller is responsible for this check. +simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative, double &d) { + // we start with a fast path + // It was described in + // Clinger WD. How to read floating point numbers accurately. + // ACM SIGPLAN Notices. 1990 +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + // We cannot be certain that x/y is rounded to nearest. + if (0 <= power && power <= 22 && i <= 9007199254740991) +#else + if (-22 <= power && power <= 22 && i <= 9007199254740991) +#endif + { + // convert the integer into a double. This is lossless since + // 0 <= i <= 2^53 - 1. + d = double(i); + // + // The general idea is as follows. + // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then + // 1) Both s and p can be represented exactly as 64-bit floating-point + // values + // (binary64). + // 2) Because s and p can be represented exactly as floating-point values, + // then s * p + // and s / p will produce correctly rounded values. + // + if (power < 0) { + d = d / simdjson::internal::power_of_ten[-power]; + } else { + d = d * simdjson::internal::power_of_ten[power]; + } + if (negative) { + d = -d; + } + return true; + } + // When 22 < power && power < 22 + 16, we could + // hope for another, secondary fast path. It was + // described by David M. Gay in "Correctly rounded + // binary-decimal and decimal-binary conversions." (1990) + // If you need to compute i * 10^(22 + x) for x < 16, + // first compute i * 10^x, if you know that result is exact + // (e.g., when i * 10^x < 2^53), + // then you can still proceed and do (i * 10^x) * 10^22. + // Is this worth your time? + // You need 22 < power *and* power < 22 + 16 *and* (i * 10^(x-22) < 2^53) + // for this second fast path to work. + // If you you have 22 < power *and* power < 22 + 16, and then you + // optimistically compute "i * 10^(x-22)", there is still a chance that you + // have wasted your time if i * 10^(x-22) >= 2^53. It makes the use cases of + // this optimization maybe less common than we would like. Source: + // http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + // also used in RapidJSON: https://rapidjson.org/strtod_8h_source.html + + // The fast path has now failed, so we are failing back on the slower path. + + // In the slow path, we need to adjust i so that it is > 1<<63 which is always + // possible, except if i == 0, so we handle i == 0 separately. + if(i == 0) { + d = negative ? -0.0 : 0.0; + return true; + } + + + // The exponent is 1024 + 63 + power + // + floor(log(5**power)/log(2)). + // The 1024 comes from the ieee64 standard. + // The 63 comes from the fact that we use a 64-bit word. + // + // Computing floor(log(5**power)/log(2)) could be + // slow. Instead we use a fast function. + // + // For power in (-400,350), we have that + // (((152170 + 65536) * power ) >> 16); + // is equal to + // floor(log(5**power)/log(2)) + power when power >= 0 + // and it is equal to + // ceil(log(5**-power)/log(2)) + power when power < 0 + // + // The 65536 is (1<<16) and corresponds to + // (65536 * power) >> 16 ---> power + // + // ((152170 * power ) >> 16) is equal to + // floor(log(5**power)/log(2)) + // + // Note that this is not magic: 152170/(1<<16) is + // approximatively equal to log(5)/log(2). + // The 1<<16 value is a power of two; we could use a + // larger power of 2 if we wanted to. + // + int64_t exponent = (((152170 + 65536) * power) >> 16) + 1024 + 63; + + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(i); + i <<= lz; + + + // We are going to need to do some 64-bit arithmetic to get a precise product. + // We use a table lookup approach. + // It is safe because + // power >= smallest_power + // and power <= largest_power + // We recover the mantissa of the power, it has a leading 1. It is always + // rounded down. + // + // We want the most significant 64 bits of the product. We know + // this will be non-zero because the most significant bit of i is + // 1. + const uint32_t index = 2 * uint32_t(power - simdjson::internal::smallest_power); + // Optimization: It may be that materializing the index as a variable might confuse some compilers and prevent effective complex-addressing loads. (Done for code clarity.) + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); + // Both i and power_of_five_128[index] have their most significant bit set to 1 which + // implies that the either the most or the second most significant bit of the product + // is 1. We pack values in this manner for efficiency reasons: it maximizes the use + // we make of the product. It also makes it easy to reason about the product: there + // is 0 or 1 leading zero in the product. + + // Unless the least significant 9 bits of the high (64-bit) part of the full + // product are all 1s, then we know that the most significant 55 bits are + // exact and no further work is needed. Having 55 bits is necessary because + // we need 53 bits for the mantissa but we have to have one rounding bit and + // we can waste a bit if the most significant bit of the product is zero. + if((firstproduct.high & 0x1FF) == 0x1FF) { + // We want to compute i * 5^q, but only care about the top 55 bits at most. + // Consider the scenario where q>=0. Then 5^q may not fit in 64-bits. Doing + // the full computation is wasteful. So we do what is called a "truncated + // multiplication". + // We take the most significant 64-bits, and we put them in + // power_of_five_128[index]. Usually, that's good enough to approximate i * 5^q + // to the desired approximation using one multiplication. Sometimes it does not suffice. + // Then we store the next most significant 64 bits in power_of_five_128[index + 1], and + // then we get a better approximation to i * 5^q. + // + // That's for when q>=0. The logic for q<0 is somewhat similar but it is somewhat + // more complicated. + // + // There is an extra layer of complexity in that we need more than 55 bits of + // accuracy in the round-to-even scenario. + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if(secondproduct.high > firstproduct.low) { firstproduct.high++; } + // As it has been proven by Noble Mushtak and Daniel Lemire in "Fast Number Parsing Without + // Fallback" (https://arxiv.org/abs/2212.06644), at this point we are sure that the product + // is sufficiently accurate, and more computation is not needed. + } + uint64_t lower = firstproduct.low; + uint64_t upper = firstproduct.high; + // The final mantissa should be 53 bits with a leading 1. + // We shift it so that it occupies 54 bits with a leading 1. + /////// + uint64_t upperbit = upper >> 63; + uint64_t mantissa = upper >> (upperbit + 9); + lz += int(1 ^ upperbit); + + // Here we have mantissa < (1<<54). + int64_t real_exponent = exponent - lz; + if (simdjson_unlikely(real_exponent <= 0)) { // we have a subnormal? + // Here have that real_exponent <= 0 so -real_exponent >= 0 + if(-real_exponent + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure. + d = negative ? -0.0 : 0.0; + return true; + } + // next line is safe because -real_exponent + 1 < 0 + mantissa >>= -real_exponent + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0. + mantissa += (mantissa & 1); // round up + mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + real_exponent = (mantissa < (uint64_t(1) << 52)) ? 0 : 1; + d = to_double(mantissa, real_exponent, negative); + return true; + } + // We have to round to even. The "to even" part + // is only a problem when we are right in between two floats + // which we guard against. + // If we have lots of trailing zeros, we may fall right between two + // floating-point values. + // + // The round-to-even cases take the form of a number 2m+1 which is in (2^53,2^54] + // times a power of two. That is, it is right between a number with binary significand + // m and another number with binary significand m+1; and it must be the case + // that it cannot be represented by a float itself. + // + // We must have that w * 10 ^q == (2m+1) * 2^p for some power of two 2^p. + // Recall that 10^q = 5^q * 2^q. + // When q >= 0, we must have that (2m+1) is divible by 5^q, so 5^q <= 2^54. We have that + // 5^23 <= 2^54 and it is the last power of five to qualify, so q <= 23. + // When q<0, we have w >= (2m+1) x 5^{-q}. We must have that w<2^{64} so + // (2m+1) x 5^{-q} < 2^{64}. We have that 2m+1>2^{53}. Hence, we must have + // 2^{53} x 5^{-q} < 2^{64}. + // Hence we have 5^{-q} < 2^{11}$ or q>= -4. + // + // We require lower <= 1 and not lower == 0 because we could not prove that + // that lower == 0 is implied; but we could prove that lower <= 1 is a necessary and sufficient test. + if (simdjson_unlikely((lower <= 1) && (power >= -4) && (power <= 23) && ((mantissa & 3) == 1))) { + if((mantissa << (upperbit + 64 - 53 - 2)) == upper) { + mantissa &= ~1; // flip it so that we do not round up + } + } + + mantissa += mantissa & 1; + mantissa >>= 1; + + // Here we have mantissa < (1<<53), unless there was an overflow + if (mantissa >= (1ULL << 53)) { + ////////// + // This will happen when parsing values such as 7.2057594037927933e+16 + //////// + mantissa = (1ULL << 52); + real_exponent++; + } + mantissa &= ~(1ULL << 52); + // we have to check that real_exponent is in range, otherwise we bail out + if (simdjson_unlikely(real_exponent > 2046)) { + // We have an infinite value!!! We could actually throw an error here if we could. + return false; + } + d = to_double(mantissa, real_exponent, negative); + return true; +} + +// We call a fallback floating-point parser that might be slow. Note +// it will accept JSON numbers, but the JSON spec. is more restrictive so +// before you call parse_float_fallback, you need to have validated the input +// string with the JSON grammar. +// It will return an error (false) if the parsed number is infinite. +// The string parsing itself always succeeds. We know that there is at least +// one digit. +static bool parse_float_fallback(const uint8_t *ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +static bool parse_float_fallback(const uint8_t *ptr, const uint8_t *end_ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr), reinterpret_cast(end_ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +// check quickly whether the next 8 chars are made of digits +// at a glance, it looks better than Mula's +// http://0x80.pl/articles/swar-digits-validate.html +simdjson_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) { + uint64_t val; + // this can read up to 7 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(7 <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be bigger than 7"); + std::memcpy(&val, chars, 8); + // a branchy method might be faster: + // return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030) + // && (( (val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0 ) == + // 0x3030303030303030); + return (((val & 0xF0F0F0F0F0F0F0F0) | + (((val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4)) == + 0x3333333333333333); +} + +template +SIMDJSON_NO_SANITIZE_UNDEFINED // We deliberately allow overflow here and check later +simdjson_inline bool parse_digit(const uint8_t c, I &i) { + const uint8_t digit = static_cast(c - '0'); + if (digit > 9) { + return false; + } + // PERF NOTE: multiplication by 10 is cheaper than arbitrary integer multiplication + i = 10 * i + digit; // might overflow, we will handle the overflow later + return true; +} + +simdjson_inline error_code parse_decimal_after_separator(simdjson_unused const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) { + // we continue with the fiction that we have an integer. If the + // floating point number is representable as x * 10^z for some integer + // z that fits in 53 bits, then we will be able to convert back the + // the integer into a float in a lossless manner. + const uint8_t *const first_after_period = p; + +#ifdef SIMDJSON_SWAR_NUMBER_PARSING +#if SIMDJSON_SWAR_NUMBER_PARSING + // this helps if we have lots of decimals! + // this turns out to be frequent enough. + if (is_made_of_eight_digits_fast(p)) { + i = i * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + } +#endif // SIMDJSON_SWAR_NUMBER_PARSING +#endif // #ifdef SIMDJSON_SWAR_NUMBER_PARSING + // Unrolling the first digit makes a small difference on some implementations (e.g. westmere) + if (parse_digit(*p, i)) { ++p; } + while (parse_digit(*p, i)) { p++; } + exponent = first_after_period - p; + // Decimal without digits (123.) is illegal + if (exponent == 0) { + return INVALID_NUMBER(src); + } + return SUCCESS; +} + +simdjson_inline error_code parse_exponent(simdjson_unused const uint8_t *const src, const uint8_t *&p, int64_t &exponent) { + // Exp Sign: -123.456e[-]78 + bool neg_exp = ('-' == *p); + if (neg_exp || '+' == *p) { p++; } // Skip + as well + + // Exponent: -123.456e-[78] + auto start_exp = p; + int64_t exp_number = 0; + while (parse_digit(*p, exp_number)) { ++p; } + // It is possible for parse_digit to overflow. + // In particular, it could overflow to INT64_MIN, and we cannot do - INT64_MIN. + // Thus we *must* check for possible overflow before we negate exp_number. + + // Performance notes: it may seem like combining the two "simdjson_unlikely checks" below into + // a single simdjson_unlikely path would be faster. The reasoning is sound, but the compiler may + // not oblige and may, in fact, generate two distinct paths in any case. It might be + // possible to do uint64_t(p - start_exp - 1) >= 18 but it could end up trading off + // instructions for a simdjson_likely branch, an unconclusive gain. + + // If there were no digits, it's an error. + if (simdjson_unlikely(p == start_exp)) { + return INVALID_NUMBER(src); + } + // We have a valid positive exponent in exp_number at this point, except that + // it may have overflowed. + + // If there were more than 18 digits, we may have overflowed the integer. We have to do + // something!!!! + if (simdjson_unlikely(p > start_exp+18)) { + // Skip leading zeroes: 1e000000000000000000001 is technically valid and doesn't overflow + while (*start_exp == '0') { start_exp++; } + // 19 digits could overflow int64_t and is kind of absurd anyway. We don't + // support exponents smaller than -999,999,999,999,999,999 and bigger + // than 999,999,999,999,999,999. + // We can truncate. + // Note that 999999999999999999 is assuredly too large. The maximal ieee64 value before + // infinity is ~1.8e308. The smallest subnormal is ~5e-324. So, actually, we could + // truncate at 324. + // Note that there is no reason to fail per se at this point in time. + // E.g., 0e999999999999999999999 is a fine number. + if (p > start_exp+18) { exp_number = 999999999999999999; } + } + // At this point, we know that exp_number is a sane, positive, signed integer. + // It is <= 999,999,999,999,999,999. As long as 'exponent' is in + // [-8223372036854775808, 8223372036854775808], we won't overflow. Because 'exponent' + // is bounded in magnitude by the size of the JSON input, we are fine in this universe. + // To sum it up: the next line should never overflow. + exponent += (neg_exp ? -exp_number : exp_number); + return SUCCESS; +} + +simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t digit_count) { + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + const uint8_t *start = start_digits; + while ((*start == '0') || (*start == '.')) { ++start; } + // we over-decrement by one when there is a '.' + return digit_count - size_t(start - start_digits); +} + +} // unnamed namespace + +/** @private */ +static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) { + if (parse_float_fallback(src, answer)) { + return SUCCESS; + } + return INVALID_NUMBER(src); +} + +/** @private */ +template +simdjson_inline error_code write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer) { + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon in practice. + // + // 9999999999999999999 < 2**64 so we can accommodate 19 digits. + // If we have a decimal separator, then digit_count - 1 is the number of digits, but we + // may not have a decimal separator! + if (simdjson_unlikely(digit_count > 19 && significant_digits(start_digits, digit_count) > 19)) { + // Ok, chances are good that we had an overflow! + // this is almost never going to get called!!! + // we start anew, going slowly!!! + // This will happen in the following examples: + // 10000000000000000000000000000000000000000000e+308 + // 3.1415926535897932384626433832795028841971693993751 + // + // NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer + // reference to it, it would force it to be stored in memory, preventing the compiler from + // picking it apart and putting into registers. i.e. if we pass it as reference, + // it gets slow. + double d; + error_code error = slow_float_parsing(src, &d); + writer.append_double(d); + return error; + } + // NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other + // way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331 + // To future reader: we'd love if someone found a better way, or at least could explain this result! + if (simdjson_unlikely(exponent < simdjson::internal::smallest_power) || (exponent > simdjson::internal::largest_power)) { + // + // Important: smallest_power is such that it leads to a zero value. + // Observe that 18446744073709551615e-343 == 0, i.e. (2**64 - 1) e -343 is zero + // so something x 10^-343 goes to zero, but not so with something x 10^-342. + static_assert(simdjson::internal::smallest_power <= -342, "smallest_power is not small enough"); + // + if((exponent < simdjson::internal::smallest_power) || (i == 0)) { + // E.g. Parse "-0.0e-999" into the same value as "-0.0". See https://en.wikipedia.org/wiki/Signed_zero + WRITE_DOUBLE(negative ? -0.0 : 0.0, src, writer); + return SUCCESS; + } else { // (exponent > largest_power) and (i != 0) + // We have, for sure, an infinite value and simdjson refuses to parse infinite values. + return INVALID_NUMBER(src); + } + } + double d; + if (!compute_float_64(exponent, i, negative, d)) { + // we are almost never going to get here. + if (!parse_float_fallback(src, &d)) { return INVALID_NUMBER(src); } + } + WRITE_DOUBLE(d, src, writer); + return SUCCESS; +} + +// for performance analysis, it is sometimes useful to skip parsing +#ifdef SIMDJSON_SKIPNUMBERPARSING + +template +simdjson_inline error_code parse_number(const uint8_t *const, W &writer) { + writer.append_s64(0); // always write zero + return SUCCESS; // always succeeds +} + +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { return number_type::signed_integer; } +#else + +// parse the number at src +// define JSON_TEST_NUMBERS for unit testing +// +// It is assumed that the number is followed by a structural ({,},],[) character +// or a white space character. If that is not the case (e.g., when the JSON +// document is made of a single number), then it is necessary to copy the +// content and append a space before calling this function. +// +// Our objective is accurate parsing (ULP of 0) at high speed. +template +simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) { + + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + if (digit_count == 0 || ('0' == *start_digits && digit_count > 1)) { return INVALID_NUMBER(src); } + + // + // Handle floats if there is a . or e (or both) + // + int64_t exponent = 0; + bool is_float = false; + if ('.' == *p) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) ); + digit_count = int(p - start_digits); // used later to guard against overflows + } + if (('e' == *p) || ('E' == *p)) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_exponent(src, p, exponent) ); + } + if (is_float) { + const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p); + SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) ); + if (dirty_end) { return INVALID_NUMBER(src); } + return SUCCESS; + } + + // The longest negative 64-bit number is 19 digits. + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + size_t longest_digit_count = negative ? 19 : 20; + if (digit_count > longest_digit_count) { return INVALID_NUMBER(src); } + if (digit_count == longest_digit_count) { + if (negative) { + // Anything negative above INT64_MAX+1 is invalid + if (i > uint64_t(INT64_MAX)+1) { return INVALID_NUMBER(src); } + WRITE_INTEGER(~i+1, src, writer); + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + } else if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INVALID_NUMBER(src); } + } + + // Write unsigned if it doesn't fit in a signed integer. + if (i > uint64_t(INT64_MAX)) { + WRITE_UNSIGNED(i, src, writer); + } else { + WRITE_INTEGER(negative ? (~i+1) : i, src, writer); + } + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; +} + +// Inlineable functions +namespace { + +// This table can be used to characterize the final character of an integer +// string. For JSON structural character and allowable white space characters, +// we return SUCCESS. For 'e', '.' and 'E', we return INCORRECT_TYPE. Otherwise +// we return NUMBER_ERROR. +// Optimization note: we could easily reduce the size of the table by half (to 128) +// at the cost of an extra branch. +// Optimization note: we want the values to use at most 8 bits (not, e.g., 32 bits): +static_assert(error_code(uint8_t(NUMBER_ERROR))== NUMBER_ERROR, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(SUCCESS))== SUCCESS, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(INCORRECT_TYPE))== INCORRECT_TYPE, "bad NUMBER_ERROR cast"); + +const uint8_t integer_string_finisher[256] = { + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, INCORRECT_TYPE, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, SUCCESS, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR}; + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + + +// Parse any number from 0 to 18,446,744,073,709,551,615 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src, const uint8_t * const src_end) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if ((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { + const uint8_t *p = src + 1; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (*p != '"') { return NUMBER_ERROR; } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + // Note: we use src[1] and not src[0] because src[0] is the quote character in this + // instance. + if (src[1] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src, const uint8_t * const src_end) noexcept { + // + // Check for minus sign + // + if(src == src_end) { return NUMBER_ERROR; } + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = src; + uint64_t i = 0; + while (parse_digit(*src, i)) { src++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(src - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*src)) { + // return (*src == '.' || *src == 'e' || *src == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(*src != '"') { return NUMBER_ERROR; } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { + return (*src == '-'); +} + +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { return true; } + return false; +} + +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { + // We have an integer. + // If the number is negative and valid, it must be a signed integer. + if(negative) { return number_type::signed_integer; } + // We want values larger or equal to 9223372036854775808 to be unsigned + // integers, and the other values to be signed integers. + int digit_count = int(p - src); + if(digit_count >= 19) { + const uint8_t * smaller_big_integer = reinterpret_cast("9223372036854775808"); + if((digit_count >= 20) || (memcmp(src, smaller_big_integer, 19) >= 0)) { + return number_type::unsigned_integer; + } + } + return number_type::signed_integer; + } + // Hopefully, we have 'e' or 'E' or '.'. + return number_type::floating_point_number; +} + +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src, const uint8_t * const src_end) noexcept { + if(src == src_end) { return NUMBER_ERROR; } + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + if(p == src_end) { return NUMBER_ERROR; } + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while ((p != src_end) && parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely((p != src_end) && (*p == '.'))) { + p++; + const uint8_t *start_decimal_digits = p; + if ((p == src_end) || !parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = start_digits-src > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if ((p != src_end) && (*p == 'e' || *p == 'E')) { + p++; + if(p == src_end) { return NUMBER_ERROR; } + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while ((p != src_end) && parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (*p != '"') { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +} // unnamed namespace +#endif // SIMDJSON_SKIPNUMBERPARSING + +} // namespace numberparsing + +inline std::ostream& operator<<(std::ostream& out, number_type type) noexcept { + switch (type) { + case number_type::signed_integer: out << "integer in [-9223372036854775808,9223372036854775808)"; break; + case number_type::unsigned_integer: out << "unsigned integer in [9223372036854775808,18446744073709551616)"; break; + case number_type::floating_point_number: out << "floating-point number (binary64)"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_NUMBERPARSING_H +/* end file simdjson/generic/numberparsing.h for westmere */ + +/* including simdjson/generic/implementation_simdjson_result_base-inl.h for westmere: #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { + +// +// internal::implementation_simdjson_result_base inline implementation +// + +template +simdjson_inline void implementation_simdjson_result_base::tie(T &value, error_code &error) && noexcept { + error = this->second; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +simdjson_warn_unused simdjson_inline error_code implementation_simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; +} + +template +simdjson_inline error_code implementation_simdjson_result_base::error() const noexcept { + return this->second; +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& implementation_simdjson_result_base::value() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline T&& implementation_simdjson_result_base::take_value() && noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& implementation_simdjson_result_base::value_unsafe() const& noexcept { + return this->first; +} + +template +simdjson_inline T& implementation_simdjson_result_base::value_unsafe() & noexcept { + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value_unsafe() && noexcept { + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value, error_code error) noexcept + : first{std::forward(value)}, second{error} {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(error_code error) noexcept + : implementation_simdjson_result_base(T{}, error) {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value) noexcept + : implementation_simdjson_result_base(std::forward(value), SUCCESS) {} + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H +/* end file simdjson/generic/implementation_simdjson_result_base-inl.h for westmere */ +/* end file simdjson/generic/amalgamated.h for westmere */ +/* including simdjson/westmere/end.h: #include "simdjson/westmere/end.h" */ +/* begin file simdjson/westmere/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_WESTMERE +SIMDJSON_UNTARGET_REGION +#endif + +/* undefining SIMDJSON_IMPLEMENTATION from "westmere" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/westmere/end.h */ + +#endif // SIMDJSON_WESTMERE_H +/* end file simdjson/westmere.h */ +/* including simdjson/westmere/implementation.h: #include */ +/* begin file simdjson/westmere/implementation.h */ +#ifndef SIMDJSON_WESTMERE_IMPLEMENTATION_H +#define SIMDJSON_WESTMERE_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_WESTMERE +namespace simdjson { +namespace westmere { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation("westmere", "Intel/AMD SSE4.2", internal::instruction_set::SSE42 | internal::instruction_set::PCLMULQDQ) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_IMPLEMENTATION_H +/* end file simdjson/westmere/implementation.h */ + +/* including simdjson/westmere/begin.h: #include */ +/* begin file simdjson/westmere/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "westmere" */ +#define SIMDJSON_IMPLEMENTATION westmere +/* including simdjson/westmere/base.h: #include "simdjson/westmere/base.h" */ +/* begin file simdjson/westmere/base.h */ +#ifndef SIMDJSON_WESTMERE_BASE_H +#define SIMDJSON_WESTMERE_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_WESTMERE +namespace simdjson { +/** + * Implementation for Westmere (Intel SSE4.2). + */ +namespace westmere { + +class implementation; + +namespace { +namespace simd { + +template struct simd8; +template struct simd8x64; + +} // namespace simd +} // unnamed namespace + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BASE_H +/* end file simdjson/westmere/base.h */ +/* including simdjson/westmere/intrinsics.h: #include "simdjson/westmere/intrinsics.h" */ +/* begin file simdjson/westmere/intrinsics.h */ +#ifndef SIMDJSON_WESTMERE_INTRINSICS_H +#define SIMDJSON_WESTMERE_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + */ +#include // for _mm_alignr_epi8 +#include // for _mm_clmulepi64_si128 +#endif + +static_assert(sizeof(__m128i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for westmere"); + +#endif // SIMDJSON_WESTMERE_INTRINSICS_H +/* end file simdjson/westmere/intrinsics.h */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_WESTMERE +SIMDJSON_TARGET_REGION("sse4.2,pclmul,popcnt") +#endif + +/* including simdjson/westmere/bitmanipulation.h: #include "simdjson/westmere/bitmanipulation.h" */ +/* begin file simdjson/westmere/bitmanipulation.h */ +#ifndef SIMDJSON_WESTMERE_BITMANIPULATION_H +#define SIMDJSON_WESTMERE_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num-1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// SIMDJSON_REGULAR_VISUAL_STUDIO +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BITMANIPULATION_H +/* end file simdjson/westmere/bitmanipulation.h */ +/* including simdjson/westmere/bitmask.h: #include "simdjson/westmere/bitmask.h" */ +/* begin file simdjson/westmere/bitmask.h */ +#ifndef SIMDJSON_WESTMERE_BITMASK_H +#define SIMDJSON_WESTMERE_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(const uint64_t bitmask) { + // There should be no such thing with a processing supporting avx2 + // but not clmul. + __m128i all_ones = _mm_set1_epi8('\xFF'); + __m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0ULL, bitmask), all_ones, 0); + return _mm_cvtsi128_si64(result); +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BITMASK_H +/* end file simdjson/westmere/bitmask.h */ +/* including simdjson/westmere/numberparsing_defs.h: #include "simdjson/westmere/numberparsing_defs.h" */ +/* begin file simdjson/westmere/numberparsing_defs.h */ +#ifndef SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H +#define SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H + +/* including simdjson/westmere/base.h: #include "simdjson/westmere/base.h" */ +/* begin file simdjson/westmere/base.h */ +#ifndef SIMDJSON_WESTMERE_BASE_H +#define SIMDJSON_WESTMERE_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_WESTMERE +namespace simdjson { +/** + * Implementation for Westmere (Intel SSE4.2). + */ +namespace westmere { + +class implementation; + +namespace { +namespace simd { + +template struct simd8; +template struct simd8x64; + +} // namespace simd +} // unnamed namespace + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BASE_H +/* end file simdjson/westmere/base.h */ +/* including simdjson/westmere/intrinsics.h: #include "simdjson/westmere/intrinsics.h" */ +/* begin file simdjson/westmere/intrinsics.h */ +#ifndef SIMDJSON_WESTMERE_INTRINSICS_H +#define SIMDJSON_WESTMERE_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + */ +#include // for _mm_alignr_epi8 +#include // for _mm_clmulepi64_si128 +#endif + +static_assert(sizeof(__m128i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for westmere"); + +#endif // SIMDJSON_WESTMERE_INTRINSICS_H +/* end file simdjson/westmere/intrinsics.h */ + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace numberparsing { + +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + // this actually computes *16* values so we are being wasteful. + const __m128i ascii0 = _mm_set1_epi8('0'); + const __m128i mul_1_10 = + _mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1); + const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1); + const __m128i mul_1_10000 = + _mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1); + const __m128i input = _mm_sub_epi8( + _mm_loadu_si128(reinterpret_cast(chars)), ascii0); + const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10); + const __m128i t2 = _mm_madd_epi16(t1, mul_1_100); + const __m128i t3 = _mm_packus_epi32(t2, t2); + const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000); + return _mm_cvtsi128_si32( + t4); // only captures the sum of the first 8 digits, drop the rest +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace westmere +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H +/* end file simdjson/westmere/numberparsing_defs.h */ +/* including simdjson/westmere/simd.h: #include "simdjson/westmere/simd.h" */ +/* begin file simdjson/westmere/simd.h */ +#ifndef SIMDJSON_WESTMERE_SIMD_H +#define SIMDJSON_WESTMERE_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace simd { + + template + struct base { + __m128i value; + + // Zero constructor + simdjson_inline base() : value{__m128i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m128i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m128i&() const { return this->value; } + simdjson_inline operator __m128i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm_or_si128(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm_and_si128(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm_xor_si128(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm_andnot_si128(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + template> + struct base8: base> { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m128i _value) : base>(_value) {} + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return _mm_cmpeq_epi8(lhs, rhs); } + + static const int SIZE = sizeof(base>::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return _mm_alignr_epi8(*this, prev_chunk, 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m128i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { return _mm_movemask_epi8(*this); } + simdjson_inline bool any() const { return !_mm_testz_si128(*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm_setzero_si128(); } + static simdjson_inline simd8 load(const T values[16]) { + return _mm_loadu_si128(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m128i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[16]) const { return _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), *this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 16 - count_ones(mask) bytes of the result are significant but 16 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + __m128i shufmask = _mm_set_epi64x(thintable_epi8[mask2], thintable_epi8[mask1]); + // we increment by 0x08 the second half of the mask + shufmask = + _mm_add_epi8(shufmask, _mm_set_epi32(0x08080808, 0x08080808, 0, 0)); + // this is the version "nearly pruned" + __m128i pruned = _mm_shuffle_epi8(*this, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + __m128i compactmask = + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop1 * 8)); + __m128i answer = _mm_shuffle_epi8(pruned, compactmask); + _mm_storeu_si128(reinterpret_cast<__m128i *>(output), answer); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epi8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return _mm_cmpgt_epi8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm_cmpgt_epi8(other, *this); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epu8(*this, other); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline simd8 operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline simd8 operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return *this == uint8_t(0); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + simdjson_inline bool is_ascii() const { return _mm_movemask_epi8(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { return _mm_testz_si128(*this, *this); } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return _mm_testz_si128(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline int get_bit() const { return _mm_movemask_epi8(_mm_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, "Westmere kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, const simd8 chunk2, const simd8 chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+16), simd8::load(ptr+32), simd8::load(ptr+48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + this->chunks[2].store(ptr+sizeof(simd8)*2); + this->chunks[3].store(ptr+sizeof(simd8)*3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | (this->chunks[2] | this->chunks[3]); + } + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + this->chunks[0].compress(uint16_t(mask), output); + this->chunks[1].compress(uint16_t(mask >> 16), output + 16 - count_ones(mask & 0xFFFF)); + this->chunks[2].compress(uint16_t(mask >> 32), output + 32 - count_ones(mask & 0xFFFFFFFF)); + this->chunks[3].compress(uint16_t(mask >> 48), output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); + return 64 - count_ones(mask); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r0 = uint32_t(this->chunks[0].to_bitmask() ); + uint64_t r1 = this->chunks[1].to_bitmask() ; + uint64_t r2 = this->chunks[2].to_bitmask() ; + uint64_t r3 = this->chunks[3].to_bitmask() ; + return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask, + this->chunks[2] == mask, + this->chunks[3] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64( + this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1], + this->chunks[2] == other.chunks[2], + this->chunks[3] == other.chunks[3] + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask, + this->chunks[2] <= mask, + this->chunks[3] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_SIMD_INPUT_H +/* end file simdjson/westmere/simd.h */ +/* including simdjson/westmere/stringparsing_defs.h: #include "simdjson/westmere/stringparsing_defs.h" */ +/* begin file simdjson/westmere/stringparsing_defs.h */ +#ifndef SIMDJSON_WESTMERE_STRINGPARSING_DEFS_H +#define SIMDJSON_WESTMERE_STRINGPARSING_DEFS_H + +/* including simdjson/westmere/bitmanipulation.h: #include "simdjson/westmere/bitmanipulation.h" */ +/* begin file simdjson/westmere/bitmanipulation.h */ +#ifndef SIMDJSON_WESTMERE_BITMANIPULATION_H +#define SIMDJSON_WESTMERE_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num-1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// SIMDJSON_REGULAR_VISUAL_STUDIO +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BITMANIPULATION_H +/* end file simdjson/westmere/bitmanipulation.h */ +/* including simdjson/westmere/simd.h: #include "simdjson/westmere/simd.h" */ +/* begin file simdjson/westmere/simd.h */ +#ifndef SIMDJSON_WESTMERE_SIMD_H +#define SIMDJSON_WESTMERE_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace simd { + + template + struct base { + __m128i value; + + // Zero constructor + simdjson_inline base() : value{__m128i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m128i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m128i&() const { return this->value; } + simdjson_inline operator __m128i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm_or_si128(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm_and_si128(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm_xor_si128(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm_andnot_si128(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + template> + struct base8: base> { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m128i _value) : base>(_value) {} + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return _mm_cmpeq_epi8(lhs, rhs); } + + static const int SIZE = sizeof(base>::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return _mm_alignr_epi8(*this, prev_chunk, 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m128i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { return _mm_movemask_epi8(*this); } + simdjson_inline bool any() const { return !_mm_testz_si128(*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm_setzero_si128(); } + static simdjson_inline simd8 load(const T values[16]) { + return _mm_loadu_si128(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m128i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[16]) const { return _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), *this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 16 - count_ones(mask) bytes of the result are significant but 16 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + __m128i shufmask = _mm_set_epi64x(thintable_epi8[mask2], thintable_epi8[mask1]); + // we increment by 0x08 the second half of the mask + shufmask = + _mm_add_epi8(shufmask, _mm_set_epi32(0x08080808, 0x08080808, 0, 0)); + // this is the version "nearly pruned" + __m128i pruned = _mm_shuffle_epi8(*this, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + __m128i compactmask = + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop1 * 8)); + __m128i answer = _mm_shuffle_epi8(pruned, compactmask); + _mm_storeu_si128(reinterpret_cast<__m128i *>(output), answer); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epi8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return _mm_cmpgt_epi8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm_cmpgt_epi8(other, *this); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epu8(*this, other); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline simd8 operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline simd8 operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return *this == uint8_t(0); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + simdjson_inline bool is_ascii() const { return _mm_movemask_epi8(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { return _mm_testz_si128(*this, *this); } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return _mm_testz_si128(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline int get_bit() const { return _mm_movemask_epi8(_mm_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, "Westmere kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, const simd8 chunk2, const simd8 chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+16), simd8::load(ptr+32), simd8::load(ptr+48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + this->chunks[2].store(ptr+sizeof(simd8)*2); + this->chunks[3].store(ptr+sizeof(simd8)*3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | (this->chunks[2] | this->chunks[3]); + } + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + this->chunks[0].compress(uint16_t(mask), output); + this->chunks[1].compress(uint16_t(mask >> 16), output + 16 - count_ones(mask & 0xFFFF)); + this->chunks[2].compress(uint16_t(mask >> 32), output + 32 - count_ones(mask & 0xFFFFFFFF)); + this->chunks[3].compress(uint16_t(mask >> 48), output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); + return 64 - count_ones(mask); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r0 = uint32_t(this->chunks[0].to_bitmask() ); + uint64_t r1 = this->chunks[1].to_bitmask() ; + uint64_t r2 = this->chunks[2].to_bitmask() ; + uint64_t r3 = this->chunks[3].to_bitmask() ; + return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask, + this->chunks[2] == mask, + this->chunks[3] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64( + this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1], + this->chunks[2] == other.chunks[2], + this->chunks[3] == other.chunks[3] + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask, + this->chunks[2] <= mask, + this->chunks[3] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_SIMD_INPUT_H +/* end file simdjson/westmere/simd.h */ + +namespace simdjson { +namespace westmere { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return bs_bits != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 31 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v0(src); + simd8 v1(src + 16); + v0.store(dst); + v1.store(dst + 16); + uint64_t bs_and_quote = simd8x64(v0 == '\\', v1 == '\\', v0 == '"', v1 == '"').to_bitmask(); + return { + uint32_t(bs_and_quote), // bs_bits + uint32_t(bs_and_quote >> 32) // quote_bits + }; +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_STRINGPARSING_DEFS_H +/* end file simdjson/westmere/stringparsing_defs.h */ +/* end file simdjson/westmere/begin.h */ +/* including generic/amalgamated.h for westmere: #include */ +/* begin file generic/amalgamated.h for westmere */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_SRC_GENERIC_DEPENDENCIES_H) +#error generic/dependencies.h must be included before generic/amalgamated.h! +#endif + +/* including generic/base.h for westmere: #include */ +/* begin file generic/base.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { + +struct json_character_block; + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_BASE_H +/* end file generic/base.h for westmere */ +/* including generic/dom_parser_implementation.h for westmere: #include */ +/* begin file generic/dom_parser_implementation.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// Interface a dom parser implementation must fulfill +namespace simdjson { +namespace westmere { +namespace { + +simdjson_inline simd8 must_be_2_3_continuation(const simd8 prev2, const simd8 prev3); +simdjson_inline bool is_ascii(const simd8x64& input); + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file generic/dom_parser_implementation.h for westmere */ +/* including generic/json_character_block.h for westmere: #include */ +/* begin file generic/json_character_block.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { + +struct json_character_block { + static simdjson_inline json_character_block classify(const simd::simd8x64& in); + + simdjson_inline uint64_t whitespace() const noexcept { return _whitespace; } + simdjson_inline uint64_t op() const noexcept { return _op; } + simdjson_inline uint64_t scalar() const noexcept { return ~(op() | whitespace()); } + + uint64_t _whitespace; + uint64_t _op; +}; + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_JSON_CHARACTER_BLOCK_H +/* end file generic/json_character_block.h for westmere */ +/* end file generic/amalgamated.h for westmere */ +/* including generic/stage1/amalgamated.h for westmere: #include */ +/* begin file generic/stage1/amalgamated.h for westmere */ +// Stuff other things depend on +/* including generic/stage1/base.h for westmere: #include */ +/* begin file generic/stage1/base.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace stage1 { + +class bit_indexer; +template +struct buf_block_reader; +struct json_block; +class json_minifier; +class json_scanner; +struct json_string_block; +class json_string_scanner; +class json_structural_indexer; + +} // namespace stage1 + +namespace utf8_validation { +struct utf8_checker; +} // namespace utf8_validation + +using utf8_validation::utf8_checker; + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_BASE_H +/* end file generic/stage1/base.h for westmere */ +/* including generic/stage1/buf_block_reader.h for westmere: #include */ +/* begin file generic/stage1/buf_block_reader.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace westmere { +namespace { +namespace stage1 { + +// Walks through a buffer in block-sized increments, loading the last part with spaces +template +struct buf_block_reader { +public: + simdjson_inline buf_block_reader(const uint8_t *_buf, size_t _len); + simdjson_inline size_t block_index(); + simdjson_inline bool has_full_block() const; + simdjson_inline const uint8_t *full_block() const; + /** + * Get the last block, padded with spaces. + * + * There will always be a last block, with at least 1 byte, unless len == 0 (in which case this + * function fills the buffer with spaces and returns 0. In particular, if len == STEP_SIZE there + * will be 0 full_blocks and 1 remainder block with STEP_SIZE bytes and no spaces for padding. + * + * @return the number of effective characters in the last block. + */ + simdjson_inline size_t get_remainder(uint8_t *dst) const; + simdjson_inline void advance(); +private: + const uint8_t *buf; + const size_t len; + const size_t lenminusstep; + size_t idx; +}; + +// Routines to print masks and text for debugging bitmask operations +simdjson_unused static char * format_input_text_64(const uint8_t *text) { + static char buf[sizeof(simd8x64) + 1]; + for (size_t i=0; i); i++) { + buf[i] = int8_t(text[i]) < ' ' ? '_' : int8_t(text[i]); + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +// Routines to print masks and text for debugging bitmask operations +simdjson_unused static char * format_input_text(const simd8x64& in) { + static char buf[sizeof(simd8x64) + 1]; + in.store(reinterpret_cast(buf)); + for (size_t i=0; i); i++) { + if (buf[i] < ' ') { buf[i] = '_'; } + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +simdjson_unused static char * format_input_text(const simd8x64& in, uint64_t mask) { + static char buf[sizeof(simd8x64) + 1]; + in.store(reinterpret_cast(buf)); + for (size_t i=0; i); i++) { + if (buf[i] <= ' ') { buf[i] = '_'; } + if (!(mask & (size_t(1) << i))) { buf[i] = ' '; } + } + buf[sizeof(simd8x64)] = '\0'; + return buf; +} + +simdjson_unused static char * format_mask(uint64_t mask) { + static char buf[sizeof(simd8x64) + 1]; + for (size_t i=0; i<64; i++) { + buf[i] = (mask & (size_t(1) << i)) ? 'X' : ' '; + } + buf[64] = '\0'; + return buf; +} + +template +simdjson_inline buf_block_reader::buf_block_reader(const uint8_t *_buf, size_t _len) : buf{_buf}, len{_len}, lenminusstep{len < STEP_SIZE ? 0 : len - STEP_SIZE}, idx{0} {} + +template +simdjson_inline size_t buf_block_reader::block_index() { return idx; } + +template +simdjson_inline bool buf_block_reader::has_full_block() const { + return idx < lenminusstep; +} + +template +simdjson_inline const uint8_t *buf_block_reader::full_block() const { + return &buf[idx]; +} + +template +simdjson_inline size_t buf_block_reader::get_remainder(uint8_t *dst) const { + if(len == idx) { return 0; } // memcpy(dst, null, 0) will trigger an error with some sanitizers + std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it's more efficient to write out 8 or 16 bytes at once. + std::memcpy(dst, buf + idx, len - idx); + return len - idx; +} + +template +simdjson_inline void buf_block_reader::advance() { + idx += STEP_SIZE; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_BUF_BLOCK_READER_H +/* end file generic/stage1/buf_block_reader.h for westmere */ +/* including generic/stage1/json_escape_scanner.h for westmere: #include */ +/* begin file generic/stage1/json_escape_scanner.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_ESCAPE_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_ESCAPE_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace stage1 { + +/** + * Scans for escape characters in JSON, taking care with multiple backslashes (\\n vs. \n). + */ +struct json_escape_scanner { + /** The actual escape characters (the backslashes themselves). */ + uint64_t next_is_escaped = 0ULL; + + struct escaped_and_escape { + /** + * Mask of escaped characters. + * + * ``` + * \n \\n \\\n \\\\n \ + * 0100100010100101000 + * n \ \ n \ \ + * ``` + */ + uint64_t escaped; + /** + * Mask of escape characters. + * + * ``` + * \n \\n \\\n \\\\n \ + * 1001000101001010001 + * \ \ \ \ \ \ \ + * ``` + */ + uint64_t escape; + }; + + /** + * Get a mask of both escape and escaped characters (the characters following a backslash). + * + * @param potential_escape A mask of the character that can escape others (but could be + * escaped itself). e.g. block.eq('\\') + */ + simdjson_really_inline escaped_and_escape next(uint64_t backslash) noexcept { + +#if !SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT + if (!backslash) { return {next_escaped_without_backslashes(), 0}; } +#endif + + // | | Mask (shows characters instead of 1's) | Depth | Instructions | + // |--------------------------------|----------------------------------------|-------|---------------------| + // | string | `\\n_\\\n___\\\n___\\\\___\\\\__\\\` | | | + // | | ` even odd even odd odd` | | | + // | potential_escape | ` \ \\\ \\\ \\\\ \\\\ \\\` | 1 | 1 (backslash & ~first_is_escaped) + // | escape_and_terminal_code | ` \n \ \n \ \n \ \ \ \ \ \` | 5 | 5 (next_escape_and_terminal_code()) + // | escaped | `\ \ n \ n \ \ \ \ \ ` X | 6 | 7 (escape_and_terminal_code ^ (potential_escape | first_is_escaped)) + // | escape | ` \ \ \ \ \ \ \ \ \ \` | 6 | 8 (escape_and_terminal_code & backslash) + // | first_is_escaped | `\ ` | 7 (*) | 9 (escape >> 63) () + // (*) this is not needed until the next iteration + uint64_t escape_and_terminal_code = next_escape_and_terminal_code(backslash & ~this->next_is_escaped); + uint64_t escaped = escape_and_terminal_code ^ (backslash | this->next_is_escaped); + uint64_t escape = escape_and_terminal_code & backslash; + this->next_is_escaped = escape >> 63; + return {escaped, escape}; + } + +private: + static constexpr const uint64_t ODD_BITS = 0xAAAAAAAAAAAAAAAAULL; + + simdjson_really_inline uint64_t next_escaped_without_backslashes() noexcept { + uint64_t escaped = this->next_is_escaped; + this->next_is_escaped = 0; + return escaped; + } + + /** + * Returns a mask of the next escape characters (masking out escaped backslashes), along with + * any non-backslash escape codes. + * + * \n \\n \\\n \\\\n returns: + * \n \ \ \n \ \ + * 11 100 1011 10100 + * + * You are expected to mask out the first bit yourself if the previous block had a trailing + * escape. + * + * & the result with potential_escape to get just the escape characters. + * ^ the result with (potential_escape | first_is_escaped) to get escaped characters. + */ + static simdjson_really_inline uint64_t next_escape_and_terminal_code(uint64_t potential_escape) noexcept { + // If we were to just shift and mask out any odd bits, we'd actually get a *half* right answer: + // any even-aligned backslash runs would be correct! Odd-aligned backslash runs would be + // inverted (\\\ would be 010 instead of 101). + // + // ``` + // string: | ____\\\\_\\\\_____ | + // maybe_escaped | ODD | \ \ \ \ | + // even-aligned ^^^ ^^^^ odd-aligned + // ``` + // + // Taking that into account, our basic strategy is: + // + // 1. Use subtraction to produce a mask with 1's for even-aligned runs and 0's for + // odd-aligned runs. + // 2. XOR all odd bits, which masks out the odd bits in even-aligned runs, and brings IN the + // odd bits in odd-aligned runs. + // 3. & with backslash to clean up any stray bits. + // runs are set to 0, and then XORing with "odd": + // + // | | Mask (shows characters instead of 1's) | Instructions | + // |--------------------------------|----------------------------------------|---------------------| + // | string | `\\n_\\\n___\\\n___\\\\___\\\\__\\\` | + // | | ` even odd even odd odd` | + // | maybe_escaped | ` n \\n \\n \\\_ \\\_ \\` X | 1 (potential_escape << 1) + // | maybe_escaped_and_odd | ` \n_ \\n _ \\\n_ _ \\\__ _\\\_ \\\` | 1 (maybe_escaped | odd) + // | even_series_codes_and_odd | ` n_\\\ _ n_ _\\\\ _ _ ` | 1 (maybe_escaped_and_odd - potential_escape) + // | escape_and_terminal_code | ` \n \ \n \ \n \ \ \ \ \ \` | 1 (^ odd) + // + + // Escaped characters are characters following an escape. + uint64_t maybe_escaped = potential_escape << 1; + + // To distinguish odd from even escape sequences, therefore, we turn on any *starting* + // escapes that are on an odd byte. (We actually bring in all odd bits, for speed.) + // - Odd runs of backslashes are 0000, and the code at the end ("n" in \n or \\n) is 1. + // - Odd runs of backslashes are 1111, and the code at the end ("n" in \n or \\n) is 0. + // - All other odd bytes are 1, and even bytes are 0. + uint64_t maybe_escaped_and_odd_bits = maybe_escaped | ODD_BITS; + uint64_t even_series_codes_and_odd_bits = maybe_escaped_and_odd_bits - potential_escape; + + // Now we flip all odd bytes back with xor. This: + // - Makes odd runs of backslashes go from 0000 to 1010 + // - Makes even runs of backslashes go from 1111 to 1010 + // - Sets actually-escaped codes to 1 (the n in \n and \\n: \n = 11, \\n = 100) + // - Resets all other bytes to 0 + return even_series_codes_and_odd_bits ^ ODD_BITS; + } +}; + +} // namespace stage1 +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H +/* end file generic/stage1/json_escape_scanner.h for westmere */ +/* including generic/stage1/json_string_scanner.h for westmere: #include */ +/* begin file generic/stage1/json_string_scanner.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace stage1 { + +struct json_string_block { + // We spell out the constructors in the hope of resolving inlining issues with Visual Studio 2017 + simdjson_really_inline json_string_block(uint64_t escaped, uint64_t quote, uint64_t in_string) : + _escaped(escaped), _quote(quote), _in_string(in_string) {} + + // Escaped characters (characters following an escape() character) + simdjson_really_inline uint64_t escaped() const { return _escaped; } + // Real (non-backslashed) quotes + simdjson_really_inline uint64_t quote() const { return _quote; } + // Only characters inside the string (not including the quotes) + simdjson_really_inline uint64_t string_content() const { return _in_string & ~_quote; } + // Return a mask of whether the given characters are inside a string (only works on non-quotes) + simdjson_really_inline uint64_t non_quote_inside_string(uint64_t mask) const { return mask & _in_string; } + // Return a mask of whether the given characters are inside a string (only works on non-quotes) + simdjson_really_inline uint64_t non_quote_outside_string(uint64_t mask) const { return mask & ~_in_string; } + // Tail of string (everything except the start quote) + simdjson_really_inline uint64_t string_tail() const { return _in_string ^ _quote; } + + // escaped characters (backslashed--does not include the hex characters after \u) + uint64_t _escaped; + // real quotes (non-escaped ones) + uint64_t _quote; + // string characters (includes start quote but not end quote) + uint64_t _in_string; +}; + +// Scans blocks for string characters, storing the state necessary to do so +class json_string_scanner { +public: + simdjson_really_inline json_string_block next(const simd::simd8x64& in); + // Returns either UNCLOSED_STRING or SUCCESS + simdjson_really_inline error_code finish(); + +private: + // Scans for escape characters + json_escape_scanner escape_scanner{}; + // Whether the last iteration was still inside a string (all 1's = true, all 0's = false). + uint64_t prev_in_string = 0ULL; +}; + +// +// Return a mask of all string characters plus end quotes. +// +// prev_escaped is overflow saying whether the next character is escaped. +// prev_in_string is overflow saying whether we're still in a string. +// +// Backslash sequences outside of quotes will be detected in stage 2. +// +simdjson_really_inline json_string_block json_string_scanner::next(const simd::simd8x64& in) { + const uint64_t backslash = in.eq('\\'); + const uint64_t escaped = escape_scanner.next(backslash).escaped; + const uint64_t quote = in.eq('"') & ~escaped; + + // + // prefix_xor flips on bits inside the string (and flips off the end quote). + // + // Then we xor with prev_in_string: if we were in a string already, its effect is flipped + // (characters inside strings are outside, and characters outside strings are inside). + // + const uint64_t in_string = prefix_xor(quote) ^ prev_in_string; + + // + // Check if we're still in a string at the end of the box so the next block will know + // + prev_in_string = uint64_t(static_cast(in_string) >> 63); + + // Use ^ to turn the beginning quote off, and the end quote on. + + // We are returning a function-local object so either we get a move constructor + // or we get copy elision. + return json_string_block(escaped, quote, in_string); +} + +simdjson_really_inline error_code json_string_scanner::finish() { + if (prev_in_string) { + return UNCLOSED_STRING; + } + return SUCCESS; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRING_SCANNER_H +/* end file generic/stage1/json_string_scanner.h for westmere */ +/* including generic/stage1/utf8_lookup4_algorithm.h for westmere: #include */ +/* begin file generic/stage1/utf8_lookup4_algorithm.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace utf8_validation { + +using namespace simd; + + simdjson_inline simd8 check_special_cases(const simd8 input, const simd8 prev1) { +// Bit 0 = Too Short (lead byte/ASCII followed by lead byte/ASCII) +// Bit 1 = Too Long (ASCII followed by continuation) +// Bit 2 = Overlong 3-byte +// Bit 4 = Surrogate +// Bit 5 = Overlong 2-byte +// Bit 7 = Two Continuations + constexpr const uint8_t TOO_SHORT = 1<<0; // 11______ 0_______ + // 11______ 11______ + constexpr const uint8_t TOO_LONG = 1<<1; // 0_______ 10______ + constexpr const uint8_t OVERLONG_3 = 1<<2; // 11100000 100_____ + constexpr const uint8_t SURROGATE = 1<<4; // 11101101 101_____ + constexpr const uint8_t OVERLONG_2 = 1<<5; // 1100000_ 10______ + constexpr const uint8_t TWO_CONTS = 1<<7; // 10______ 10______ + constexpr const uint8_t TOO_LARGE = 1<<3; // 11110100 1001____ + // 11110100 101_____ + // 11110101 1001____ + // 11110101 101_____ + // 1111011_ 1001____ + // 1111011_ 101_____ + // 11111___ 1001____ + // 11111___ 101_____ + constexpr const uint8_t TOO_LARGE_1000 = 1<<6; + // 11110101 1000____ + // 1111011_ 1000____ + // 11111___ 1000____ + constexpr const uint8_t OVERLONG_4 = 1<<6; // 11110000 1000____ + + const simd8 byte_1_high = prev1.shr<4>().lookup_16( + // 0_______ ________ + TOO_LONG, TOO_LONG, TOO_LONG, TOO_LONG, + TOO_LONG, TOO_LONG, TOO_LONG, TOO_LONG, + // 10______ ________ + TWO_CONTS, TWO_CONTS, TWO_CONTS, TWO_CONTS, + // 1100____ ________ + TOO_SHORT | OVERLONG_2, + // 1101____ ________ + TOO_SHORT, + // 1110____ ________ + TOO_SHORT | OVERLONG_3 | SURROGATE, + // 1111____ ________ + TOO_SHORT | TOO_LARGE | TOO_LARGE_1000 | OVERLONG_4 + ); + constexpr const uint8_t CARRY = TOO_SHORT | TOO_LONG | TWO_CONTS; // These all have ____ in byte 1 . + const simd8 byte_1_low = (prev1 & 0x0F).lookup_16( + // ____0000 ________ + CARRY | OVERLONG_3 | OVERLONG_2 | OVERLONG_4, + // ____0001 ________ + CARRY | OVERLONG_2, + // ____001_ ________ + CARRY, + CARRY, + + // ____0100 ________ + CARRY | TOO_LARGE, + // ____0101 ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + // ____011_ ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + + // ____1___ ________ + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000, + // ____1101 ________ + CARRY | TOO_LARGE | TOO_LARGE_1000 | SURROGATE, + CARRY | TOO_LARGE | TOO_LARGE_1000, + CARRY | TOO_LARGE | TOO_LARGE_1000 + ); + const simd8 byte_2_high = input.shr<4>().lookup_16( + // ________ 0_______ + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT, + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT, + + // ________ 1000____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | OVERLONG_3 | TOO_LARGE_1000 | OVERLONG_4, + // ________ 1001____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | OVERLONG_3 | TOO_LARGE, + // ________ 101_____ + TOO_LONG | OVERLONG_2 | TWO_CONTS | SURROGATE | TOO_LARGE, + TOO_LONG | OVERLONG_2 | TWO_CONTS | SURROGATE | TOO_LARGE, + + // ________ 11______ + TOO_SHORT, TOO_SHORT, TOO_SHORT, TOO_SHORT + ); + return (byte_1_high & byte_1_low & byte_2_high); + } + simdjson_inline simd8 check_multibyte_lengths(const simd8 input, + const simd8 prev_input, const simd8 sc) { + simd8 prev2 = input.prev<2>(prev_input); + simd8 prev3 = input.prev<3>(prev_input); + simd8 must23 = simd8(must_be_2_3_continuation(prev2, prev3)); + simd8 must23_80 = must23 & uint8_t(0x80); + return must23_80 ^ sc; + } + + // + // Return nonzero if there are incomplete multibyte characters at the end of the block: + // e.g. if there is a 4-byte character, but it's 3 bytes from the end. + // + simdjson_inline simd8 is_incomplete(const simd8 input) { + // If the previous input's last 3 bytes match this, they're too short (they ended at EOF): + // ... 1111____ 111_____ 11______ +#if SIMDJSON_IMPLEMENTATION_ICELAKE + static const uint8_t max_array[64] = { + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 0xf0u-1, 0xe0u-1, 0xc0u-1 + }; +#else + static const uint8_t max_array[32] = { + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 0xf0u-1, 0xe0u-1, 0xc0u-1 + }; +#endif + const simd8 max_value(&max_array[sizeof(max_array)-sizeof(simd8)]); + return input.gt_bits(max_value); + } + + struct utf8_checker { + // If this is nonzero, there has been a UTF-8 error. + simd8 error; + // The last input we received + simd8 prev_input_block; + // Whether the last input we received was incomplete (used for ASCII fast path) + simd8 prev_incomplete; + + // + // Check whether the current bytes are valid UTF-8. + // + simdjson_inline void check_utf8_bytes(const simd8 input, const simd8 prev_input) { + // Flip prev1...prev3 so we can easily determine if they are 2+, 3+ or 4+ lead bytes + // (2, 3, 4-byte leads become large positive numbers instead of small negative numbers) + simd8 prev1 = input.prev<1>(prev_input); + simd8 sc = check_special_cases(input, prev1); + this->error |= check_multibyte_lengths(input, prev_input, sc); + } + + // The only problem that can happen at EOF is that a multibyte character is too short + // or a byte value too large in the last bytes: check_special_cases only checks for bytes + // too large in the first of two bytes. + simdjson_inline void check_eof() { + // If the previous block had incomplete UTF-8 characters at the end, an ASCII block can't + // possibly finish them. + this->error |= this->prev_incomplete; + } + + simdjson_inline void check_next_input(const simd8x64& input) { + if(simdjson_likely(is_ascii(input))) { + this->error |= this->prev_incomplete; + } else { + // you might think that a for-loop would work, but under Visual Studio, it is not good enough. + static_assert((simd8x64::NUM_CHUNKS == 1) + ||(simd8x64::NUM_CHUNKS == 2) + || (simd8x64::NUM_CHUNKS == 4), + "We support one, two or four chunks per 64-byte block."); + SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 1) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + } else SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 2) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + this->check_utf8_bytes(input.chunks[1], input.chunks[0]); + } else SIMDJSON_IF_CONSTEXPR (simd8x64::NUM_CHUNKS == 4) { + this->check_utf8_bytes(input.chunks[0], this->prev_input_block); + this->check_utf8_bytes(input.chunks[1], input.chunks[0]); + this->check_utf8_bytes(input.chunks[2], input.chunks[1]); + this->check_utf8_bytes(input.chunks[3], input.chunks[2]); + } + this->prev_incomplete = is_incomplete(input.chunks[simd8x64::NUM_CHUNKS-1]); + this->prev_input_block = input.chunks[simd8x64::NUM_CHUNKS-1]; + } + } + // do not forget to call check_eof! + simdjson_inline error_code errors() { + return this->error.any_bits_set_anywhere() ? error_code::UTF8_ERROR : error_code::SUCCESS; + } + + }; // struct utf8_checker +} // namespace utf8_validation + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_UTF8_LOOKUP4_ALGORITHM_H +/* end file generic/stage1/utf8_lookup4_algorithm.h for westmere */ +/* including generic/stage1/json_scanner.h for westmere: #include */ +/* begin file generic/stage1/json_scanner.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace stage1 { + +/** + * A block of scanned json, with information on operators and scalars. + * + * We seek to identify pseudo-structural characters. Anything that is inside + * a string must be omitted (hence & ~_string.string_tail()). + * Otherwise, pseudo-structural characters come in two forms. + * 1. We have the structural characters ([,],{,},:, comma). The + * term 'structural character' is from the JSON RFC. + * 2. We have the 'scalar pseudo-structural characters'. + * Scalars are quotes, and any character except structural characters and white space. + * + * To identify the scalar pseudo-structural characters, we must look at what comes + * before them: it must be a space, a quote or a structural characters. + * Starting with simdjson v0.3, we identify them by + * negation: we identify everything that is followed by a non-quote scalar, + * and we negate that. Whatever remains must be a 'scalar pseudo-structural character'. + */ +struct json_block { +public: + // We spell out the constructors in the hope of resolving inlining issues with Visual Studio 2017 + simdjson_inline json_block(json_string_block&& string, json_character_block characters, uint64_t follows_potential_nonquote_scalar) : + _string(std::move(string)), _characters(characters), _follows_potential_nonquote_scalar(follows_potential_nonquote_scalar) {} + simdjson_inline json_block(json_string_block string, json_character_block characters, uint64_t follows_potential_nonquote_scalar) : + _string(string), _characters(characters), _follows_potential_nonquote_scalar(follows_potential_nonquote_scalar) {} + + /** + * The start of structurals. + * In simdjson prior to v0.3, these were called the pseudo-structural characters. + **/ + simdjson_inline uint64_t structural_start() const noexcept { return potential_structural_start() & ~_string.string_tail(); } + /** All JSON whitespace (i.e. not in a string) */ + simdjson_inline uint64_t whitespace() const noexcept { return non_quote_outside_string(_characters.whitespace()); } + + // Helpers + + /** Whether the given characters are inside a string (only works on non-quotes) */ + simdjson_inline uint64_t non_quote_inside_string(uint64_t mask) const noexcept { return _string.non_quote_inside_string(mask); } + /** Whether the given characters are outside a string (only works on non-quotes) */ + simdjson_inline uint64_t non_quote_outside_string(uint64_t mask) const noexcept { return _string.non_quote_outside_string(mask); } + + // string and escape characters + json_string_block _string; + // whitespace, structural characters ('operators'), scalars + json_character_block _characters; + // whether the previous character was a scalar + uint64_t _follows_potential_nonquote_scalar; +private: + // Potential structurals (i.e. disregarding strings) + + /** + * structural elements ([,],{,},:, comma) plus scalar starts like 123, true and "abc". + * They may reside inside a string. + **/ + simdjson_inline uint64_t potential_structural_start() const noexcept { return _characters.op() | potential_scalar_start(); } + /** + * The start of non-operator runs, like 123, true and "abc". + * It main reside inside a string. + **/ + simdjson_inline uint64_t potential_scalar_start() const noexcept { + // The term "scalar" refers to anything except structural characters and white space + // (so letters, numbers, quotes). + // Whenever it is preceded by something that is not a structural element ({,},[,],:, ") nor a white-space + // then we know that it is irrelevant structurally. + return _characters.scalar() & ~follows_potential_scalar(); + } + /** + * Whether the given character is immediately after a non-operator like 123, true. + * The characters following a quote are not included. + */ + simdjson_inline uint64_t follows_potential_scalar() const noexcept { + // _follows_potential_nonquote_scalar: is defined as marking any character that follows a character + // that is not a structural element ({,},[,],:, comma) nor a quote (") and that is not a + // white space. + // It is understood that within quoted region, anything at all could be marked (irrelevant). + return _follows_potential_nonquote_scalar; + } +}; + +/** + * Scans JSON for important bits: structural characters or 'operators', strings, and scalars. + * + * The scanner starts by calculating two distinct things: + * - string characters (taking \" into account) + * - structural characters or 'operators' ([]{},:, comma) + * and scalars (runs of non-operators like 123, true and "abc") + * + * To minimize data dependency (a key component of the scanner's speed), it finds these in parallel: + * in particular, the operator/scalar bit will find plenty of things that are actually part of + * strings. When we're done, json_block will fuse the two together by masking out tokens that are + * part of a string. + */ +class json_scanner { +public: + json_scanner() = default; + simdjson_inline json_block next(const simd::simd8x64& in); + // Returns either UNCLOSED_STRING or SUCCESS + simdjson_inline error_code finish(); + +private: + // Whether the last character of the previous iteration is part of a scalar token + // (anything except whitespace or a structural character/'operator'). + uint64_t prev_scalar = 0ULL; + json_string_scanner string_scanner{}; +}; + + +// +// Check if the current character immediately follows a matching character. +// +// For example, this checks for quotes with backslashes in front of them: +// +// const uint64_t backslashed_quote = in.eq('"') & immediately_follows(in.eq('\'), prev_backslash); +// +simdjson_inline uint64_t follows(const uint64_t match, uint64_t &overflow) { + const uint64_t result = match << 1 | overflow; + overflow = match >> 63; + return result; +} + +simdjson_inline json_block json_scanner::next(const simd::simd8x64& in) { + json_string_block strings = string_scanner.next(in); + // identifies the white-space and the structural characters + json_character_block characters = json_character_block::classify(in); + // The term "scalar" refers to anything except structural characters and white space + // (so letters, numbers, quotes). + // We want follows_scalar to mark anything that follows a non-quote scalar (so letters and numbers). + // + // A terminal quote should either be followed by a structural character (comma, brace, bracket, colon) + // or nothing. However, we still want ' "a string"true ' to mark the 't' of 'true' as a potential + // pseudo-structural character just like we would if we had ' "a string" true '; otherwise we + // may need to add an extra check when parsing strings. + // + // Performance: there are many ways to skin this cat. + const uint64_t nonquote_scalar = characters.scalar() & ~strings.quote(); + uint64_t follows_nonquote_scalar = follows(nonquote_scalar, prev_scalar); + // We are returning a function-local object so either we get a move constructor + // or we get copy elision. + return json_block( + strings,// strings is a function-local object so either it moves or the copy is elided. + characters, + follows_nonquote_scalar + ); +} + +simdjson_inline error_code json_scanner::finish() { + return string_scanner.finish(); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_SCANNER_H +/* end file generic/stage1/json_scanner.h for westmere */ + +// All other declarations +/* including generic/stage1/find_next_document_index.h for westmere: #include */ +/* begin file generic/stage1/find_next_document_index.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace stage1 { + +/** + * This algorithm is used to quickly identify the last structural position that + * makes up a complete document. + * + * It does this by going backwards and finding the last *document boundary* (a + * place where one value follows another without a comma between them). If the + * last document (the characters after the boundary) has an equal number of + * start and end brackets, it is considered complete. + * + * Simply put, we iterate over the structural characters, starting from + * the end. We consider that we found the end of a JSON document when the + * first element of the pair is NOT one of these characters: '{' '[' ':' ',' + * and when the second element is NOT one of these characters: '}' ']' ':' ','. + * + * This simple comparison works most of the time, but it does not cover cases + * where the batch's structural indexes contain a perfect amount of documents. + * In such a case, we do not have access to the structural index which follows + * the last document, therefore, we do not have access to the second element in + * the pair, and that means we cannot identify the last document. To fix this + * issue, we keep a count of the open and closed curly/square braces we found + * while searching for the pair. When we find a pair AND the count of open and + * closed curly/square braces is the same, we know that we just passed a + * complete document, therefore the last json buffer location is the end of the + * batch. + */ +simdjson_inline uint32_t find_next_document_index(dom_parser_implementation &parser) { + // Variant: do not count separately, just figure out depth + if(parser.n_structural_indexes == 0) { return 0; } + auto arr_cnt = 0; + auto obj_cnt = 0; + for (auto i = parser.n_structural_indexes - 1; i > 0; i--) { + auto idxb = parser.structural_indexes[i]; + switch (parser.buf[idxb]) { + case ':': + case ',': + continue; + case '}': + obj_cnt--; + continue; + case ']': + arr_cnt--; + continue; + case '{': + obj_cnt++; + break; + case '[': + arr_cnt++; + break; + } + auto idxa = parser.structural_indexes[i - 1]; + switch (parser.buf[idxa]) { + case '{': + case '[': + case ':': + case ',': + continue; + } + // Last document is complete, so the next document will appear after! + if (!arr_cnt && !obj_cnt) { + return parser.n_structural_indexes; + } + // Last document is incomplete; mark the document at i + 1 as the next one + return i; + } + // If we made it to the end, we want to finish counting to see if we have a full document. + switch (parser.buf[parser.structural_indexes[0]]) { + case '}': + obj_cnt--; + break; + case ']': + arr_cnt--; + break; + case '{': + obj_cnt++; + break; + case '[': + arr_cnt++; + break; + } + if (!arr_cnt && !obj_cnt) { + // We have a complete document. + return parser.n_structural_indexes; + } + return 0; +} + +} // namespace stage1 +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_FIND_NEXT_DOCUMENT_INDEX_H +/* end file generic/stage1/find_next_document_index.h for westmere */ +/* including generic/stage1/json_minifier.h for westmere: #include */ +/* begin file generic/stage1/json_minifier.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses in stage1 +// It is intended to be included multiple times and compiled multiple times +// We assume the file in which it is included already includes +// "simdjson/stage1.h" (this simplifies amalgation) + +namespace simdjson { +namespace westmere { +namespace { +namespace stage1 { + +class json_minifier { +public: + template + static error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept; + +private: + simdjson_inline json_minifier(uint8_t *_dst) + : dst{_dst} + {} + template + simdjson_inline void step(const uint8_t *block_buf, buf_block_reader &reader) noexcept; + simdjson_inline void next(const simd::simd8x64& in, const json_block& block); + simdjson_inline error_code finish(uint8_t *dst_start, size_t &dst_len); + json_scanner scanner{}; + uint8_t *dst; +}; + +simdjson_inline void json_minifier::next(const simd::simd8x64& in, const json_block& block) { + uint64_t mask = block.whitespace(); + dst += in.compress(mask, dst); +} + +simdjson_inline error_code json_minifier::finish(uint8_t *dst_start, size_t &dst_len) { + error_code error = scanner.finish(); + if (error) { dst_len = 0; return error; } + dst_len = dst - dst_start; + return SUCCESS; +} + +template<> +simdjson_inline void json_minifier::step<128>(const uint8_t *block_buf, buf_block_reader<128> &reader) noexcept { + simd::simd8x64 in_1(block_buf); + simd::simd8x64 in_2(block_buf+64); + json_block block_1 = scanner.next(in_1); + json_block block_2 = scanner.next(in_2); + this->next(in_1, block_1); + this->next(in_2, block_2); + reader.advance(); +} + +template<> +simdjson_inline void json_minifier::step<64>(const uint8_t *block_buf, buf_block_reader<64> &reader) noexcept { + simd::simd8x64 in_1(block_buf); + json_block block_1 = scanner.next(in_1); + this->next(block_buf, block_1); + reader.advance(); +} + +template +error_code json_minifier::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept { + buf_block_reader reader(buf, len); + json_minifier minifier(dst); + + // Index the first n-1 blocks + while (reader.has_full_block()) { + minifier.step(reader.full_block(), reader); + } + + // Index the last (remainder) block, padded with spaces + uint8_t block[STEP_SIZE]; + size_t remaining_bytes = reader.get_remainder(block); + if (remaining_bytes > 0) { + // We do not want to write directly to the output stream. Rather, we write + // to a local buffer (for safety). + uint8_t out_block[STEP_SIZE]; + uint8_t * const guarded_dst{minifier.dst}; + minifier.dst = out_block; + minifier.step(block, reader); + size_t to_write = minifier.dst - out_block; + // In some cases, we could be enticed to consider the padded spaces + // as part of the string. This is fine as long as we do not write more + // than we consumed. + if(to_write > remaining_bytes) { to_write = remaining_bytes; } + memcpy(guarded_dst, out_block, to_write); + minifier.dst = guarded_dst + to_write; + } + return minifier.finish(dst, dst_len); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_MINIFIER_H +/* end file generic/stage1/json_minifier.h for westmere */ +/* including generic/stage1/json_structural_indexer.h for westmere: #include */ +/* begin file generic/stage1/json_structural_indexer.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses in stage1 +// It is intended to be included multiple times and compiled multiple times +// We assume the file in which it is included already includes +// "simdjson/stage1.h" (this simplifies amalgation) + +namespace simdjson { +namespace westmere { +namespace { +namespace stage1 { + +class bit_indexer { +public: + uint32_t *tail; + + simdjson_inline bit_indexer(uint32_t *index_buf) : tail(index_buf) {} + +#if SIMDJSON_PREFER_REVERSE_BITS + /** + * ARM lacks a fast trailing zero instruction, but it has a fast + * bit reversal instruction and a fast leading zero instruction. + * Thus it may be profitable to reverse the bits (once) and then + * to rely on a sequence of instructions that call the leading + * zero instruction. + * + * Performance notes: + * The chosen routine is not optimal in terms of data dependency + * since zero_leading_bit might require two instructions. However, + * it tends to minimize the total number of instructions which is + * beneficial. + */ + simdjson_inline void write_index(uint32_t idx, uint64_t& rev_bits, int i) { + int lz = leading_zeroes(rev_bits); + this->tail[i] = static_cast(idx) + lz; + rev_bits = zero_leading_bit(rev_bits, lz); + } +#else + /** + * Under recent x64 systems, we often have both a fast trailing zero + * instruction and a fast 'clear-lower-bit' instruction so the following + * algorithm can be competitive. + */ + + simdjson_inline void write_index(uint32_t idx, uint64_t& bits, int i) { + this->tail[i] = idx + trailing_zeroes(bits); + bits = clear_lowest_bit(bits); + } +#endif // SIMDJSON_PREFER_REVERSE_BITS + + template + simdjson_inline int write_indexes(uint32_t idx, uint64_t& bits) { + write_index(idx, bits, START); + SIMDJSON_IF_CONSTEXPR (N > 1) { + write_indexes<(N-1>0?START+1:START), (N-1>=0?N-1:1)>(idx, bits); + } + return START+N; + } + + template + simdjson_inline int write_indexes_stepped(uint32_t idx, uint64_t& bits, int cnt) { + write_indexes(idx, bits); + SIMDJSON_IF_CONSTEXPR ((START+STEP) < END) { + if (simdjson_unlikely((START+STEP) < cnt)) { + write_indexes_stepped<(START+STEP(idx, bits, cnt); + } + } + return ((END-START) % STEP) == 0 ? END : (END-START) - ((END-START) % STEP) + STEP; + } + + // flatten out values in 'bits' assuming that they are are to have values of idx + // plus their position in the bitvector, and store these indexes at + // base_ptr[base] incrementing base as we go + // will potentially store extra values beyond end of valid bits, so base_ptr + // needs to be large enough to handle this + // + // If the kernel sets SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER, then it + // will provide its own version of the code. +#ifdef SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + simdjson_inline void write(uint32_t idx, uint64_t bits); +#else + simdjson_inline void write(uint32_t idx, uint64_t bits) { + // In some instances, the next branch is expensive because it is mispredicted. + // Unfortunately, in other cases, + // it helps tremendously. + if (bits == 0) + return; + + int cnt = static_cast(count_ones(bits)); + +#if SIMDJSON_PREFER_REVERSE_BITS + bits = reverse_bits(bits); +#endif +#ifdef SIMDJSON_STRUCTURAL_INDEXER_STEP + static constexpr const int STEP = SIMDJSON_STRUCTURAL_INDEXER_STEP; +#else + static constexpr const int STEP = 4; +#endif + static constexpr const int STEP_UNTIL = 24; + + write_indexes_stepped<0, STEP_UNTIL, STEP>(idx, bits, cnt); + SIMDJSON_IF_CONSTEXPR (STEP_UNTIL < 64) { + if (simdjson_unlikely(STEP_UNTIL < cnt)) { + for (int i=STEP_UNTIL; itail += cnt; + } +#endif // SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + +}; + +class json_structural_indexer { +public: + /** + * Find the important bits of JSON in a 128-byte chunk, and add them to structural_indexes. + * + * @param partial Setting the partial parameter to true allows the find_structural_bits to + * tolerate unclosed strings. 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 + static error_code index(const uint8_t *buf, size_t len, dom_parser_implementation &parser, stage1_mode partial) noexcept; + +private: + simdjson_inline json_structural_indexer(uint32_t *structural_indexes); + template + simdjson_inline void step(const uint8_t *block, buf_block_reader &reader) noexcept; + simdjson_inline void next(const simd::simd8x64& in, const json_block& block, size_t idx); + simdjson_inline error_code finish(dom_parser_implementation &parser, size_t idx, size_t len, stage1_mode partial); + + json_scanner scanner{}; + utf8_checker checker{}; + bit_indexer indexer; + uint64_t prev_structurals = 0; + uint64_t unescaped_chars_error = 0; +}; + +simdjson_inline json_structural_indexer::json_structural_indexer(uint32_t *structural_indexes) : indexer{structural_indexes} {} + +// Skip the last character if it is partial +simdjson_inline size_t trim_partial_utf8(const uint8_t *buf, size_t len) { + if (simdjson_unlikely(len < 3)) { + switch (len) { + case 2: + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + if (buf[len-2] >= 0xe0) { return len-2; } // 3- and 4-byte characters with only 2 bytes left + return len; + case 1: + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + return len; + case 0: + return len; + } + } + if (buf[len-1] >= 0xc0) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left + if (buf[len-2] >= 0xe0) { return len-2; } // 3- and 4-byte characters with only 1 byte left + if (buf[len-3] >= 0xf0) { return len-3; } // 4-byte characters with only 3 bytes left + return len; +} + +// +// PERF NOTES: +// We pipe 2 inputs through these stages: +// 1. Load JSON into registers. This takes a long time and is highly parallelizable, so we load +// 2 inputs' worth at once so that by the time step 2 is looking for them input, it's available. +// 2. Scan the JSON for critical data: strings, scalars and operators. This is the critical path. +// The output of step 1 depends entirely on this information. These functions don't quite use +// up enough CPU: the second half of the functions is highly serial, only using 1 execution core +// at a time. The second input's scans has some dependency on the first ones finishing it, but +// they can make a lot of progress before they need that information. +// 3. Step 1 doesn't use enough capacity, so we run some extra stuff while we're waiting for that +// to finish: utf-8 checks and generating the output from the last iteration. +// +// The reason we run 2 inputs at a time, is steps 2 and 3 are *still* not enough to soak up all +// available capacity with just one input. Running 2 at a time seems to give the CPU a good enough +// workout. +// +template +error_code json_structural_indexer::index(const uint8_t *buf, size_t len, dom_parser_implementation &parser, stage1_mode partial) noexcept { + if (simdjson_unlikely(len > parser.capacity())) { return CAPACITY; } + // We guard the rest of the code so that we can assume that len > 0 throughout. + if (len == 0) { return EMPTY; } + if (is_streaming(partial)) { + len = trim_partial_utf8(buf, len); + // If you end up with an empty window after trimming + // the partial UTF-8 bytes, then chances are good that you + // have an UTF-8 formatting error. + if(len == 0) { return UTF8_ERROR; } + } + buf_block_reader reader(buf, len); + json_structural_indexer indexer(parser.structural_indexes.get()); + + // Read all but the last block + while (reader.has_full_block()) { + indexer.step(reader.full_block(), reader); + } + // Take care of the last block (will always be there unless file is empty which is + // not supposed to happen.) + uint8_t block[STEP_SIZE]; + if (simdjson_unlikely(reader.get_remainder(block) == 0)) { return UNEXPECTED_ERROR; } + indexer.step(block, reader); + return indexer.finish(parser, reader.block_index(), len, partial); +} + +template<> +simdjson_inline void json_structural_indexer::step<128>(const uint8_t *block, buf_block_reader<128> &reader) noexcept { + simd::simd8x64 in_1(block); + simd::simd8x64 in_2(block+64); + json_block block_1 = scanner.next(in_1); + json_block block_2 = scanner.next(in_2); + this->next(in_1, block_1, reader.block_index()); + this->next(in_2, block_2, reader.block_index()+64); + reader.advance(); +} + +template<> +simdjson_inline void json_structural_indexer::step<64>(const uint8_t *block, buf_block_reader<64> &reader) noexcept { + simd::simd8x64 in_1(block); + json_block block_1 = scanner.next(in_1); + this->next(in_1, block_1, reader.block_index()); + reader.advance(); +} + +simdjson_inline void json_structural_indexer::next(const simd::simd8x64& in, const json_block& block, size_t idx) { + uint64_t unescaped = in.lteq(0x1F); +#if SIMDJSON_UTF8VALIDATION + checker.check_next_input(in); +#endif + indexer.write(uint32_t(idx-64), prev_structurals); // Output *last* iteration's structurals to the parser + prev_structurals = block.structural_start(); + unescaped_chars_error |= block.non_quote_inside_string(unescaped); +} + +simdjson_inline error_code json_structural_indexer::finish(dom_parser_implementation &parser, size_t idx, size_t len, stage1_mode partial) { + // Write out the final iteration's structurals + indexer.write(uint32_t(idx-64), prev_structurals); + error_code error = scanner.finish(); + // We deliberately break down the next expression so that it is + // human readable. + const bool should_we_exit = is_streaming(partial) ? + ((error != SUCCESS) && (error != UNCLOSED_STRING)) // when partial we tolerate UNCLOSED_STRING + : (error != SUCCESS); // if partial is false, we must have SUCCESS + const bool have_unclosed_string = (error == UNCLOSED_STRING); + if (simdjson_unlikely(should_we_exit)) { return error; } + + if (unescaped_chars_error) { + return UNESCAPED_CHARS; + } + parser.n_structural_indexes = uint32_t(indexer.tail - parser.structural_indexes.get()); + /*** + * The On Demand API requires special padding. + * + * This is related to https://github.com/simdjson/simdjson/issues/906 + * Basically, we want to make sure that if the parsing continues beyond the last (valid) + * structural character, it quickly stops. + * Only three structural characters can be repeated without triggering an error in JSON: [,] and }. + * We repeat the padding character (at 'len'). We don't know what it is, but if the parsing + * continues, then it must be [,] or }. + * Suppose it is ] or }. We backtrack to the first character, what could it be that would + * not trigger an error? It could be ] or } but no, because you can't start a document that way. + * It can't be a comma, a colon or any simple value. So the only way we could continue is + * if the repeated character is [. But if so, the document must start with [. But if the document + * starts with [, it should end with ]. If we enforce that rule, then we would get + * ][[ which is invalid. + * + * This is illustrated with the test array_iterate_unclosed_error() on the following input: + * R"({ "a": [,,)" + **/ + parser.structural_indexes[parser.n_structural_indexes] = uint32_t(len); // used later in partial == stage1_mode::streaming_final + parser.structural_indexes[parser.n_structural_indexes + 1] = uint32_t(len); + parser.structural_indexes[parser.n_structural_indexes + 2] = 0; + parser.next_structural_index = 0; + // a valid JSON file cannot have zero structural indexes - we should have found something + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { + return EMPTY; + } + if (simdjson_unlikely(parser.structural_indexes[parser.n_structural_indexes - 1] > len)) { + return UNEXPECTED_ERROR; + } + if (partial == stage1_mode::streaming_partial) { + // If we have an unclosed string, then the last structural + // will be the quote and we want to make sure to omit it. + if(have_unclosed_string) { + parser.n_structural_indexes--; + // a valid JSON file cannot have zero structural indexes - we should have found something + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { return CAPACITY; } + } + // We truncate the input to the end of the last complete document (or zero). + auto new_structural_indexes = find_next_document_index(parser); + if (new_structural_indexes == 0 && parser.n_structural_indexes > 0) { + if(parser.structural_indexes[0] == 0) { + // If the buffer is partial and we started at index 0 but the document is + // incomplete, it's too big to parse. + return CAPACITY; + } else { + // It is possible that the document could be parsed, we just had a lot + // of white space. + parser.n_structural_indexes = 0; + return EMPTY; + } + } + + parser.n_structural_indexes = new_structural_indexes; + } else if (partial == stage1_mode::streaming_final) { + if(have_unclosed_string) { parser.n_structural_indexes--; } + // We truncate the input to the end of the last complete document (or zero). + // Because partial == stage1_mode::streaming_final, it means that we may + // silently ignore trailing garbage. Though it sounds bad, we do it + // deliberately because many people who have streams of JSON documents + // will truncate them for processing. E.g., imagine that you are uncompressing + // the data from a size file or receiving it in chunks from the network. You + // may not know where exactly the last document will be. Meanwhile the + // document_stream instances allow people to know the JSON documents they are + // parsing (see the iterator.source() method). + parser.n_structural_indexes = find_next_document_index(parser); + // We store the initial n_structural_indexes so that the client can see + // whether we used truncation. If initial_n_structural_indexes == parser.n_structural_indexes, + // then this will query parser.structural_indexes[parser.n_structural_indexes] which is len, + // otherwise, it will copy some prior index. + parser.structural_indexes[parser.n_structural_indexes + 1] = parser.structural_indexes[parser.n_structural_indexes]; + // This next line is critical, do not change it unless you understand what you are + // doing. + parser.structural_indexes[parser.n_structural_indexes] = uint32_t(len); + if (simdjson_unlikely(parser.n_structural_indexes == 0u)) { + // We tolerate an unclosed string at the very end of the stream. Indeed, users + // often load their data in bulk without being careful and they want us to ignore + // the trailing garbage. + return EMPTY; + } + } + checker.check_eof(); + return checker.errors(); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +// Clear CUSTOM_BIT_INDEXER so other implementations can set it if they need to. +#undef SIMDJSON_GENERIC_JSON_STRUCTURAL_INDEXER_CUSTOM_BIT_INDEXER + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_JSON_STRUCTURAL_INDEXER_H +/* end file generic/stage1/json_structural_indexer.h for westmere */ +/* including generic/stage1/utf8_validator.h for westmere: #include */ +/* begin file generic/stage1/utf8_validator.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace stage1 { + +/** + * Validates that the string is actual UTF-8. + */ +template +bool generic_validate_utf8(const uint8_t * input, size_t length) { + checker c{}; + buf_block_reader<64> reader(input, length); + while (reader.has_full_block()) { + simd::simd8x64 in(reader.full_block()); + c.check_next_input(in); + reader.advance(); + } + uint8_t block[64]{}; + reader.get_remainder(block); + simd::simd8x64 in(block); + c.check_next_input(in); + reader.advance(); + c.check_eof(); + return c.errors() == error_code::SUCCESS; +} + +bool generic_validate_utf8(const char * input, size_t length) { + return generic_validate_utf8(reinterpret_cast(input),length); +} + +} // namespace stage1 +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE1_UTF8_VALIDATOR_H +/* end file generic/stage1/utf8_validator.h for westmere */ +/* end file generic/stage1/amalgamated.h for westmere */ +/* including generic/stage2/amalgamated.h for westmere: #include */ +/* begin file generic/stage2/amalgamated.h for westmere */ +// Stuff other things depend on +/* including generic/stage2/base.h for westmere: #include */ +/* begin file generic/stage2/base.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_BASE_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace stage2 { + +class json_iterator; +class structural_iterator; +struct tape_builder; +struct tape_writer; + +} // namespace stage2 +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_BASE_H +/* end file generic/stage2/base.h for westmere */ +/* including generic/stage2/tape_writer.h for westmere: #include */ +/* begin file generic/stage2/tape_writer.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace westmere { +namespace { +namespace stage2 { + +struct tape_writer { + /** The next place to write to tape */ + uint64_t *next_tape_loc; + + /** Write a signed 64-bit value to tape. */ + simdjson_inline void append_s64(int64_t value) noexcept; + + /** Write an unsigned 64-bit value to tape. */ + simdjson_inline void append_u64(uint64_t value) noexcept; + + /** Write a double value to tape. */ + simdjson_inline void append_double(double value) noexcept; + + /** + * Append a tape entry (an 8-bit type,and 56 bits worth of value). + */ + simdjson_inline void append(uint64_t val, internal::tape_type t) noexcept; + + /** + * Skip the current tape entry without writing. + * + * Used to skip the start of the container, since we'll come back later to fill it in when the + * container ends. + */ + simdjson_inline void skip() noexcept; + + /** + * Skip the number of tape entries necessary to write a large u64 or i64. + */ + simdjson_inline void skip_large_integer() noexcept; + + /** + * Skip the number of tape entries necessary to write a double. + */ + simdjson_inline void skip_double() noexcept; + + /** + * Write a value to a known location on tape. + * + * Used to go back and write out the start of a container after the container ends. + */ + simdjson_inline static void write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept; + +private: + /** + * Append both the tape entry, and a supplementary value following it. Used for types that need + * all 64 bits, such as double and uint64_t. + */ + template + simdjson_inline void append2(uint64_t val, T val2, internal::tape_type t) noexcept; +}; // struct tape_writer + +simdjson_inline void tape_writer::append_s64(int64_t value) noexcept { + append2(0, value, internal::tape_type::INT64); +} + +simdjson_inline void tape_writer::append_u64(uint64_t value) noexcept { + append(0, internal::tape_type::UINT64); + *next_tape_loc = value; + next_tape_loc++; +} + +/** Write a double value to tape. */ +simdjson_inline void tape_writer::append_double(double value) noexcept { + append2(0, value, internal::tape_type::DOUBLE); +} + +simdjson_inline void tape_writer::skip() noexcept { + next_tape_loc++; +} + +simdjson_inline void tape_writer::skip_large_integer() noexcept { + next_tape_loc += 2; +} + +simdjson_inline void tape_writer::skip_double() noexcept { + next_tape_loc += 2; +} + +simdjson_inline void tape_writer::append(uint64_t val, internal::tape_type t) noexcept { + *next_tape_loc = val | ((uint64_t(char(t))) << 56); + next_tape_loc++; +} + +template +simdjson_inline void tape_writer::append2(uint64_t val, T val2, internal::tape_type t) noexcept { + append(val, t); + static_assert(sizeof(val2) == sizeof(*next_tape_loc), "Type is not 64 bits!"); + memcpy(next_tape_loc, &val2, sizeof(val2)); + next_tape_loc++; +} + +simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept { + tape_loc = val | ((uint64_t(char(t))) << 56); +} + +} // namespace stage2 +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_TAPE_WRITER_H +/* end file generic/stage2/tape_writer.h for westmere */ +/* including generic/stage2/logger.h for westmere: #include */ +/* begin file generic/stage2/logger.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_LOGGER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_LOGGER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + + +// This is for an internal-only stage 2 specific logger. +// Set LOG_ENABLED = true to log what stage 2 is doing! +namespace simdjson { +namespace westmere { +namespace { +namespace logger { + + static constexpr const char * DASHES = "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"; + +#if SIMDJSON_VERBOSE_LOGGING + static constexpr const bool LOG_ENABLED = true; +#else + static constexpr const bool LOG_ENABLED = false; +#endif + static constexpr const int LOG_EVENT_LEN = 20; + static constexpr const int LOG_BUFFER_LEN = 30; + static constexpr const int LOG_SMALL_BUFFER_LEN = 10; + static constexpr const int LOG_INDEX_LEN = 5; + + static int log_depth; // Not threadsafe. Log only. + + // Helper to turn unprintable or newline characters into spaces + static simdjson_inline char printable_char(char c) { + if (c >= 0x20) { + return c; + } else { + return ' '; + } + } + + // Print the header and set up log_start + static simdjson_inline void log_start() { + if (LOG_ENABLED) { + log_depth = 0; + printf("\n"); + printf("| %-*s | %-*s | %-*s | %-*s | Detail |\n", LOG_EVENT_LEN, "Event", LOG_BUFFER_LEN, "Buffer", LOG_SMALL_BUFFER_LEN, "Next", 5, "Next#"); + printf("|%.*s|%.*s|%.*s|%.*s|--------|\n", LOG_EVENT_LEN+2, DASHES, LOG_BUFFER_LEN+2, DASHES, LOG_SMALL_BUFFER_LEN+2, DASHES, 5+2, DASHES); + } + } + + simdjson_unused static simdjson_inline void log_string(const char *message) { + if (LOG_ENABLED) { + printf("%s\n", message); + } + } + + // Logs a single line from the stage 2 DOM parser + template + static simdjson_inline void log_line(S &structurals, const char *title_prefix, const char *title, const char *detail) { + if (LOG_ENABLED) { + printf("| %*s%s%-*s ", log_depth*2, "", title_prefix, LOG_EVENT_LEN - log_depth*2 - int(strlen(title_prefix)), title); + auto current_index = structurals.at_beginning() ? nullptr : structurals.next_structural-1; + auto next_index = structurals.next_structural; + auto current = current_index ? &structurals.buf[*current_index] : reinterpret_cast(" "); + auto next = &structurals.buf[*next_index]; + { + // Print the next N characters in the buffer. + printf("| "); + // Otherwise, print the characters starting from the buffer position. + // Print spaces for unprintable or newline characters. + for (int i=0;i */ +/* begin file generic/stage2/json_iterator.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace stage2 { + +class json_iterator { +public: + const uint8_t* const buf; + uint32_t *next_structural; + dom_parser_implementation &dom_parser; + uint32_t depth{0}; + + /** + * Walk the JSON document. + * + * The visitor receives callbacks when values are encountered. All callbacks pass the iterator as + * the first parameter; some callbacks have other parameters as well: + * + * - visit_document_start() - at the beginning. + * - visit_document_end() - at the end (if things were successful). + * + * - visit_array_start() - at the start `[` of a non-empty array. + * - visit_array_end() - at the end `]` of a non-empty array. + * - visit_empty_array() - when an empty array is encountered. + * + * - visit_object_end() - at the start `]` of a non-empty object. + * - visit_object_start() - at the end `]` of a non-empty object. + * - visit_empty_object() - when an empty object is encountered. + * - visit_key(const uint8_t *key) - when a key in an object field is encountered. key is + * guaranteed to point at the first quote of the string (`"key"`). + * - visit_primitive(const uint8_t *value) - when a value is a string, number, boolean or null. + * - visit_root_primitive(iter, uint8_t *value) - when the top-level value is a string, number, boolean or null. + * + * - increment_count(iter) - each time a value is found in an array or object. + */ + template + simdjson_warn_unused simdjson_inline error_code walk_document(V &visitor) noexcept; + + /** + * Create an iterator capable of walking a JSON document. + * + * The document must have already passed through stage 1. + */ + simdjson_inline json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index); + + /** + * Look at the next token. + * + * Tokens can be strings, numbers, booleans, null, or operators (`[{]},:`)). + * + * They may include invalid JSON as well (such as `1.2.3` or `ture`). + */ + simdjson_inline const uint8_t *peek() const noexcept; + /** + * Advance to the next token. + * + * Tokens can be strings, numbers, booleans, null, or operators (`[{]},:`)). + * + * They may include invalid JSON as well (such as `1.2.3` or `ture`). + */ + simdjson_inline const uint8_t *advance() noexcept; + /** + * Get the remaining length of the document, from the start of the current token. + */ + simdjson_inline size_t remaining_len() const noexcept; + /** + * Check if we are at the end of the document. + * + * If this is true, there are no more tokens. + */ + simdjson_inline bool at_eof() const noexcept; + /** + * Check if we are at the beginning of the document. + */ + simdjson_inline bool at_beginning() const noexcept; + simdjson_inline uint8_t last_structural() const noexcept; + + /** + * Log that a value has been found. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_value(const char *type) const noexcept; + /** + * Log the start of a multipart value. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_start_value(const char *type) const noexcept; + /** + * Log the end of a multipart value. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_end_value(const char *type) const noexcept; + /** + * Log an error. + * + * Set LOG_ENABLED=true in logger.h to see logging. + */ + simdjson_inline void log_error(const char *error) const noexcept; + + template + simdjson_warn_unused simdjson_inline error_code visit_root_primitive(V &visitor, const uint8_t *value) noexcept; + template + simdjson_warn_unused simdjson_inline error_code visit_primitive(V &visitor, const uint8_t *value) noexcept; +}; + +template +simdjson_warn_unused simdjson_inline error_code json_iterator::walk_document(V &visitor) noexcept { + logger::log_start(); + + // + // Start the document + // + if (at_eof()) { return EMPTY; } + log_start_value("document"); + SIMDJSON_TRY( visitor.visit_document_start(*this) ); + + // + // Read first value + // + { + auto value = advance(); + + // Make sure the outer object or array is closed before continuing; otherwise, there are ways we + // could get into memory corruption. See https://github.com/simdjson/simdjson/issues/906 + if (!STREAMING) { + switch (*value) { + case '{': if (last_structural() != '}') { log_value("starting brace unmatched"); return TAPE_ERROR; }; break; + case '[': if (last_structural() != ']') { log_value("starting bracket unmatched"); return TAPE_ERROR; }; break; + } + } + + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_root_primitive(*this, value) ); break; + } + } + goto document_end; + +// +// Object parser states +// +object_begin: + log_start_value("object"); + depth++; + if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; } + dom_parser.is_array[depth] = false; + SIMDJSON_TRY( visitor.visit_object_start(*this) ); + + { + auto key = advance(); + if (*key != '"') { log_error("Object does not start with a key"); return TAPE_ERROR; } + SIMDJSON_TRY( visitor.increment_count(*this) ); + SIMDJSON_TRY( visitor.visit_key(*this, key) ); + } + +object_field: + if (simdjson_unlikely( *advance() != ':' )) { log_error("Missing colon after key in object"); return TAPE_ERROR; } + { + auto value = advance(); + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break; + } + } + +object_continue: + switch (*advance()) { + case ',': + SIMDJSON_TRY( visitor.increment_count(*this) ); + { + auto key = advance(); + if (simdjson_unlikely( *key != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; } + SIMDJSON_TRY( visitor.visit_key(*this, key) ); + } + goto object_field; + case '}': log_end_value("object"); SIMDJSON_TRY( visitor.visit_object_end(*this) ); goto scope_end; + default: log_error("No comma between object fields"); return TAPE_ERROR; + } + +scope_end: + depth--; + if (depth == 0) { goto document_end; } + if (dom_parser.is_array[depth]) { goto array_continue; } + goto object_continue; + +// +// Array parser states +// +array_begin: + log_start_value("array"); + depth++; + if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; } + dom_parser.is_array[depth] = true; + SIMDJSON_TRY( visitor.visit_array_start(*this) ); + SIMDJSON_TRY( visitor.increment_count(*this) ); + +array_value: + { + auto value = advance(); + switch (*value) { + case '{': if (*peek() == '}') { advance(); log_value("empty object"); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin; + case '[': if (*peek() == ']') { advance(); log_value("empty array"); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin; + default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break; + } + } + +array_continue: + switch (*advance()) { + case ',': SIMDJSON_TRY( visitor.increment_count(*this) ); goto array_value; + case ']': log_end_value("array"); SIMDJSON_TRY( visitor.visit_array_end(*this) ); goto scope_end; + default: log_error("Missing comma between array values"); return TAPE_ERROR; + } + +document_end: + log_end_value("document"); + SIMDJSON_TRY( visitor.visit_document_end(*this) ); + + dom_parser.next_structural_index = uint32_t(next_structural - &dom_parser.structural_indexes[0]); + + // If we didn't make it to the end, it's an error + if ( !STREAMING && dom_parser.next_structural_index != dom_parser.n_structural_indexes ) { + log_error("More than one JSON value at the root of the document, or extra characters at the end of the JSON!"); + return TAPE_ERROR; + } + + return SUCCESS; + +} // walk_document() + +simdjson_inline json_iterator::json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index) + : buf{_dom_parser.buf}, + next_structural{&_dom_parser.structural_indexes[start_structural_index]}, + dom_parser{_dom_parser} { +} + +simdjson_inline const uint8_t *json_iterator::peek() const noexcept { + return &buf[*(next_structural)]; +} +simdjson_inline const uint8_t *json_iterator::advance() noexcept { + return &buf[*(next_structural++)]; +} +simdjson_inline size_t json_iterator::remaining_len() const noexcept { + return dom_parser.len - *(next_structural-1); +} + +simdjson_inline bool json_iterator::at_eof() const noexcept { + return next_structural == &dom_parser.structural_indexes[dom_parser.n_structural_indexes]; +} +simdjson_inline bool json_iterator::at_beginning() const noexcept { + return next_structural == dom_parser.structural_indexes.get(); +} +simdjson_inline uint8_t json_iterator::last_structural() const noexcept { + return buf[dom_parser.structural_indexes[dom_parser.n_structural_indexes - 1]]; +} + +simdjson_inline void json_iterator::log_value(const char *type) const noexcept { + logger::log_line(*this, "", type, ""); +} + +simdjson_inline void json_iterator::log_start_value(const char *type) const noexcept { + logger::log_line(*this, "+", type, ""); + if (logger::LOG_ENABLED) { logger::log_depth++; } +} + +simdjson_inline void json_iterator::log_end_value(const char *type) const noexcept { + if (logger::LOG_ENABLED) { logger::log_depth--; } + logger::log_line(*this, "-", type, ""); +} + +simdjson_inline void json_iterator::log_error(const char *error) const noexcept { + logger::log_line(*this, "", "ERROR", error); +} + +template +simdjson_warn_unused simdjson_inline error_code json_iterator::visit_root_primitive(V &visitor, const uint8_t *value) noexcept { + switch (*value) { + case '"': return visitor.visit_root_string(*this, value); + case 't': return visitor.visit_root_true_atom(*this, value); + case 'f': return visitor.visit_root_false_atom(*this, value); + case 'n': return visitor.visit_root_null_atom(*this, value); + case '-': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return visitor.visit_root_number(*this, value); + default: + log_error("Document starts with a non-value character"); + return TAPE_ERROR; + } +} +template +simdjson_warn_unused simdjson_inline error_code json_iterator::visit_primitive(V &visitor, const uint8_t *value) noexcept { + // Use the fact that most scalars are going to be either strings or numbers. + if(*value == '"') { + return visitor.visit_string(*this, value); + } else if (((*value - '0') < 10) || (*value == '-')) { + return visitor.visit_number(*this, value); + } + // true, false, null are uncommon. + switch (*value) { + case 't': return visitor.visit_true_atom(*this, value); + case 'f': return visitor.visit_false_atom(*this, value); + case 'n': return visitor.visit_null_atom(*this, value); + default: + log_error("Non-value found when value was expected!"); + return TAPE_ERROR; + } +} + +} // namespace stage2 +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H +/* end file generic/stage2/json_iterator.h for westmere */ +/* including generic/stage2/stringparsing.h for westmere: #include */ +/* begin file generic/stage2/stringparsing.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This file contains the common code every implementation uses +// It is intended to be included multiple times and compiled multiple times + +namespace simdjson { +namespace westmere { +namespace { +/// @private +namespace stringparsing { + +// begin copypasta +// These chars yield themselves: " \ / +// b -> backspace, f -> formfeed, n -> newline, r -> cr, t -> horizontal tab +// u not handled in this table as it's complex +static const uint8_t escape_map[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0x22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2f, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x4. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5c, 0, 0, 0, // 0x5. + 0, 0, 0x08, 0, 0, 0, 0x0c, 0, 0, 0, 0, 0, 0, 0, 0x0a, 0, // 0x6. + 0, 0, 0x0d, 0, 0x09, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x7. + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +// handle a unicode codepoint +// write appropriate values into dest +// src will advance 6 bytes or 12 bytes +// dest will advance a variable amount (return via pointer) +// return true if the unicode codepoint was valid +// We work in little-endian then swap at write time +simdjson_warn_unused +simdjson_inline bool handle_unicode_codepoint(const uint8_t **src_ptr, + uint8_t **dst_ptr, bool allow_replacement) { + // Use the default Unicode Character 'REPLACEMENT CHARACTER' (U+FFFD) + constexpr uint32_t substitution_code_point = 0xfffd; + // jsoncharutils::hex_to_u32_nocheck fills high 16 bits of the return value with 1s if the + // conversion isn't valid; we defer the check for this to inside the + // multilingual plane check + uint32_t code_point = jsoncharutils::hex_to_u32_nocheck(*src_ptr + 2); + *src_ptr += 6; + + // If we found a high surrogate, we must + // check for low surrogate for characters + // outside the Basic + // Multilingual Plane. + if (code_point >= 0xd800 && code_point < 0xdc00) { + const uint8_t *src_data = *src_ptr; + /* Compiler optimizations convert this to a single 16-bit load and compare on most platforms */ + if (((src_data[0] << 8) | src_data[1]) != ((static_cast ('\\') << 8) | static_cast ('u'))) { + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } else { + uint32_t code_point_2 = jsoncharutils::hex_to_u32_nocheck(src_data + 2); + + // We have already checked that the high surrogate is valid and + // (code_point - 0xd800) < 1024. + // + // Check that code_point_2 is in the range 0xdc00..0xdfff + // and that code_point_2 was parsed from valid hex. + uint32_t low_bit = code_point_2 - 0xdc00; + if (low_bit >> 10) { + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } else { + code_point = (((code_point - 0xd800) << 10) | low_bit) + 0x10000; + *src_ptr += 6; + } + + } + } else if (code_point >= 0xdc00 && code_point <= 0xdfff) { + // If we encounter a low surrogate (not preceded by a high surrogate) + // then we have an error. + if(!allow_replacement) { return false; } + code_point = substitution_code_point; + } + size_t offset = jsoncharutils::codepoint_to_utf8(code_point, *dst_ptr); + *dst_ptr += offset; + return offset > 0; +} + + +// handle a unicode codepoint using the wobbly convention +// https://simonsapin.github.io/wtf-8/ +// write appropriate values into dest +// src will advance 6 bytes or 12 bytes +// dest will advance a variable amount (return via pointer) +// return true if the unicode codepoint was valid +// We work in little-endian then swap at write time +simdjson_warn_unused +simdjson_inline bool handle_unicode_codepoint_wobbly(const uint8_t **src_ptr, + uint8_t **dst_ptr) { + // It is not ideal that this function is nearly identical to handle_unicode_codepoint. + // + // jsoncharutils::hex_to_u32_nocheck fills high 16 bits of the return value with 1s if the + // conversion isn't valid; we defer the check for this to inside the + // multilingual plane check + uint32_t code_point = jsoncharutils::hex_to_u32_nocheck(*src_ptr + 2); + *src_ptr += 6; + // If we found a high surrogate, we must + // check for low surrogate for characters + // outside the Basic + // Multilingual Plane. + if (code_point >= 0xd800 && code_point < 0xdc00) { + const uint8_t *src_data = *src_ptr; + /* Compiler optimizations convert this to a single 16-bit load and compare on most platforms */ + if (((src_data[0] << 8) | src_data[1]) == ((static_cast ('\\') << 8) | static_cast ('u'))) { + uint32_t code_point_2 = jsoncharutils::hex_to_u32_nocheck(src_data + 2); + uint32_t low_bit = code_point_2 - 0xdc00; + if ((low_bit >> 10) == 0) { + code_point = + (((code_point - 0xd800) << 10) | low_bit) + 0x10000; + *src_ptr += 6; + } + } + } + + size_t offset = jsoncharutils::codepoint_to_utf8(code_point, *dst_ptr); + *dst_ptr += offset; + return offset > 0; +} + + +/** + * Unescape a valid UTF-8 string from src to dst, stopping at a final unescaped quote. There + * must be an unescaped quote terminating the string. It returns the final output + * position as pointer. In case of error (e.g., the string has bad escaped codes), + * then null_nullptrptr is returned. It is assumed that the output buffer is large + * enough. E.g., if src points at 'joe"', then dst needs to have four free bytes + + * SIMDJSON_PADDING bytes. + */ +simdjson_warn_unused simdjson_inline uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) { + while (1) { + // Copy the next n bytes, and find the backslash and quote in them. + auto bs_quote = backslash_and_quote::copy_and_find(src, dst); + // If the next thing is the end quote, copy and return + if (bs_quote.has_quote_first()) { + // we encountered quotes first. Move dst to point to quotes and exit + return dst + bs_quote.quote_index(); + } + if (bs_quote.has_backslash()) { + /* find out where the backspace is */ + auto bs_dist = bs_quote.backslash_index(); + uint8_t escape_char = src[bs_dist + 1]; + /* we encountered backslash first. Handle backslash */ + if (escape_char == 'u') { + /* move src/dst up to the start; they will be further adjusted + within the unicode codepoint handling code. */ + src += bs_dist; + dst += bs_dist; + if (!handle_unicode_codepoint(&src, &dst, allow_replacement)) { + return nullptr; + } + } else { + /* simple 1:1 conversion. Will eat bs_dist+2 characters in input and + * write bs_dist+1 characters to output + * note this may reach beyond the part of the buffer we've actually + * seen. I think this is ok */ + uint8_t escape_result = escape_map[escape_char]; + if (escape_result == 0u) { + return nullptr; /* bogus escape value is an error */ + } + dst[bs_dist] = escape_result; + src += bs_dist + 2; + dst += bs_dist + 1; + } + } else { + /* they are the same. Since they can't co-occur, it means we + * encountered neither. */ + src += backslash_and_quote::BYTES_PROCESSED; + dst += backslash_and_quote::BYTES_PROCESSED; + } + } +} + +simdjson_warn_unused simdjson_inline uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) { + // It is not ideal that this function is nearly identical to parse_string. + while (1) { + // Copy the next n bytes, and find the backslash and quote in them. + auto bs_quote = backslash_and_quote::copy_and_find(src, dst); + // If the next thing is the end quote, copy and return + if (bs_quote.has_quote_first()) { + // we encountered quotes first. Move dst to point to quotes and exit + return dst + bs_quote.quote_index(); + } + if (bs_quote.has_backslash()) { + /* find out where the backspace is */ + auto bs_dist = bs_quote.backslash_index(); + uint8_t escape_char = src[bs_dist + 1]; + /* we encountered backslash first. Handle backslash */ + if (escape_char == 'u') { + /* move src/dst up to the start; they will be further adjusted + within the unicode codepoint handling code. */ + src += bs_dist; + dst += bs_dist; + if (!handle_unicode_codepoint_wobbly(&src, &dst)) { + return nullptr; + } + } else { + /* simple 1:1 conversion. Will eat bs_dist+2 characters in input and + * write bs_dist+1 characters to output + * note this may reach beyond the part of the buffer we've actually + * seen. I think this is ok */ + uint8_t escape_result = escape_map[escape_char]; + if (escape_result == 0u) { + return nullptr; /* bogus escape value is an error */ + } + dst[bs_dist] = escape_result; + src += bs_dist + 2; + dst += bs_dist + 1; + } + } else { + /* they are the same. Since they can't co-occur, it means we + * encountered neither. */ + src += backslash_and_quote::BYTES_PROCESSED; + dst += backslash_and_quote::BYTES_PROCESSED; + } + } +} + +} // namespace stringparsing +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_STRINGPARSING_H +/* end file generic/stage2/stringparsing.h for westmere */ +/* including generic/stage2/structural_iterator.h for westmere: #include */ +/* begin file generic/stage2/structural_iterator.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace stage2 { + +class structural_iterator { +public: + const uint8_t* const buf; + uint32_t *next_structural; + dom_parser_implementation &dom_parser; + + // Start a structural + simdjson_inline structural_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index) + : buf{_dom_parser.buf}, + next_structural{&_dom_parser.structural_indexes[start_structural_index]}, + dom_parser{_dom_parser} { + } + // Get the buffer position of the current structural character + simdjson_inline const uint8_t* current() { + return &buf[*(next_structural-1)]; + } + // Get the current structural character + simdjson_inline char current_char() { + return buf[*(next_structural-1)]; + } + // Get the next structural character without advancing + simdjson_inline char peek_next_char() { + return buf[*next_structural]; + } + simdjson_inline const uint8_t* peek() { + return &buf[*next_structural]; + } + simdjson_inline const uint8_t* advance() { + return &buf[*(next_structural++)]; + } + simdjson_inline char advance_char() { + return buf[*(next_structural++)]; + } + simdjson_inline size_t remaining_len() { + return dom_parser.len - *(next_structural-1); + } + + simdjson_inline bool at_end() { + return next_structural == &dom_parser.structural_indexes[dom_parser.n_structural_indexes]; + } + simdjson_inline bool at_beginning() { + return next_structural == dom_parser.structural_indexes.get(); + } +}; + +} // namespace stage2 +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_STRUCTURAL_ITERATOR_H +/* end file generic/stage2/structural_iterator.h for westmere */ +/* including generic/stage2/tape_builder.h for westmere: #include */ +/* begin file generic/stage2/tape_builder.h for westmere */ +#ifndef SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #include */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + + +namespace simdjson { +namespace westmere { +namespace { +namespace stage2 { + +struct tape_builder { + template + simdjson_warn_unused static simdjson_inline error_code parse_document( + dom_parser_implementation &dom_parser, + dom::document &doc) noexcept; + + /** Called when a non-empty document starts. */ + simdjson_warn_unused simdjson_inline error_code visit_document_start(json_iterator &iter) noexcept; + /** Called when a non-empty document ends without error. */ + simdjson_warn_unused simdjson_inline error_code visit_document_end(json_iterator &iter) noexcept; + + /** Called when a non-empty array starts. */ + simdjson_warn_unused simdjson_inline error_code visit_array_start(json_iterator &iter) noexcept; + /** Called when a non-empty array ends. */ + simdjson_warn_unused simdjson_inline error_code visit_array_end(json_iterator &iter) noexcept; + /** Called when an empty array is found. */ + simdjson_warn_unused simdjson_inline error_code visit_empty_array(json_iterator &iter) noexcept; + + /** Called when a non-empty object starts. */ + simdjson_warn_unused simdjson_inline error_code visit_object_start(json_iterator &iter) noexcept; + /** + * Called when a key in a field is encountered. + * + * primitive, visit_object_start, visit_empty_object, visit_array_start, or visit_empty_array + * will be called after this with the field value. + */ + simdjson_warn_unused simdjson_inline error_code visit_key(json_iterator &iter, const uint8_t *key) noexcept; + /** Called when a non-empty object ends. */ + simdjson_warn_unused simdjson_inline error_code visit_object_end(json_iterator &iter) noexcept; + /** Called when an empty object is found. */ + simdjson_warn_unused simdjson_inline error_code visit_empty_object(json_iterator &iter) noexcept; + + /** + * Called when a string, number, boolean or null is found. + */ + simdjson_warn_unused simdjson_inline error_code visit_primitive(json_iterator &iter, const uint8_t *value) noexcept; + /** + * Called when a string, number, boolean or null is found at the top level of a document (i.e. + * when there is no array or object and the entire document is a single string, number, boolean or + * null. + * + * This is separate from primitive() because simdjson's normal primitive parsing routines assume + * there is at least one more token after the value, which is only true in an array or object. + */ + simdjson_warn_unused simdjson_inline error_code visit_root_primitive(json_iterator &iter, const uint8_t *value) noexcept; + + simdjson_warn_unused simdjson_inline error_code visit_string(json_iterator &iter, const uint8_t *value, bool key = false) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_number(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_true_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_false_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_null_atom(json_iterator &iter, const uint8_t *value) noexcept; + + simdjson_warn_unused simdjson_inline error_code visit_root_string(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_number(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_true_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_false_atom(json_iterator &iter, const uint8_t *value) noexcept; + simdjson_warn_unused simdjson_inline error_code visit_root_null_atom(json_iterator &iter, const uint8_t *value) noexcept; + + /** Called each time a new field or element in an array or object is found. */ + simdjson_warn_unused simdjson_inline error_code increment_count(json_iterator &iter) noexcept; + + /** Next location to write to tape */ + tape_writer tape; +private: + /** Next write location in the string buf for stage 2 parsing */ + uint8_t *current_string_buf_loc; + + simdjson_inline tape_builder(dom::document &doc) noexcept; + + simdjson_inline uint32_t next_tape_index(json_iterator &iter) const noexcept; + simdjson_inline void start_container(json_iterator &iter) noexcept; + simdjson_warn_unused simdjson_inline error_code end_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept; + simdjson_warn_unused simdjson_inline error_code empty_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept; + simdjson_inline uint8_t *on_start_string(json_iterator &iter) noexcept; + simdjson_inline void on_end_string(uint8_t *dst) noexcept; +}; // struct tape_builder + +template +simdjson_warn_unused simdjson_inline error_code tape_builder::parse_document( + dom_parser_implementation &dom_parser, + dom::document &doc) noexcept { + dom_parser.doc = &doc; + json_iterator iter(dom_parser, STREAMING ? dom_parser.next_structural_index : 0); + tape_builder builder(doc); + return iter.walk_document(builder); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_primitive(json_iterator &iter, const uint8_t *value) noexcept { + return iter.visit_root_primitive(*this, value); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_primitive(json_iterator &iter, const uint8_t *value) noexcept { + return iter.visit_primitive(*this, value); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_empty_object(json_iterator &iter) noexcept { + return empty_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_empty_array(json_iterator &iter) noexcept { + return empty_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_document_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_object_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_array_start(json_iterator &iter) noexcept { + start_container(iter); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_object_end(json_iterator &iter) noexcept { + return end_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_array_end(json_iterator &iter) noexcept { + return end_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY); +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_document_end(json_iterator &iter) noexcept { + constexpr uint32_t start_tape_index = 0; + tape.append(start_tape_index, internal::tape_type::ROOT); + tape_writer::write(iter.dom_parser.doc->tape[start_tape_index], next_tape_index(iter), internal::tape_type::ROOT); + return SUCCESS; +} +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_key(json_iterator &iter, const uint8_t *key) noexcept { + return visit_string(iter, key, true); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::increment_count(json_iterator &iter) noexcept { + iter.dom_parser.open_containers[iter.depth].count++; // we have a key value pair in the object at parser.dom_parser.depth - 1 + return SUCCESS; +} + +simdjson_inline tape_builder::tape_builder(dom::document &doc) noexcept : tape{doc.tape.get()}, current_string_buf_loc{doc.string_buf.get()} {} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_string(json_iterator &iter, const uint8_t *value, bool key) noexcept { + iter.log_value(key ? "key" : "string"); + uint8_t *dst = on_start_string(iter); + dst = stringparsing::parse_string(value+1, dst, false); // We do not allow replacement when the escape characters are invalid. + if (dst == nullptr) { + iter.log_error("Invalid escape in string"); + return STRING_ERROR; + } + on_end_string(dst); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(json_iterator &iter, const uint8_t *value) noexcept { + return visit_string(iter, value); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("number"); + return numberparsing::parse_number(value, tape); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept { + // + // We need to make a copy to make sure that the string is space terminated. + // This is not about padding the input, which should already padded up + // to len + SIMDJSON_PADDING. However, we have no control at this stage + // on how the padding was done. What if the input string was padded with nulls? + // It is quite common for an input string to have an extra null character (C string). + // We do not want to allow 9\0 (where \0 is the null character) inside a JSON + // document, but the string "9\0" by itself is fine. So we make a copy and + // pad the input with spaces when we know that there is just one input element. + // This copy is relatively expensive, but it will almost never be called in + // practice unless you are in the strange scenario where you have many JSON + // documents made of single atoms. + // + std::unique_ptrcopy(new (std::nothrow) uint8_t[iter.remaining_len() + SIMDJSON_PADDING]); + if (copy.get() == nullptr) { return MEMALLOC; } + std::memcpy(copy.get(), value, iter.remaining_len()); + std::memset(copy.get() + iter.remaining_len(), ' ', SIMDJSON_PADDING); + error_code error = visit_number(iter, copy.get()); + return error; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_true_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("true"); + if (!atomparsing::is_valid_true_atom(value)) { return T_ATOM_ERROR; } + tape.append(0, internal::tape_type::TRUE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_true_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("true"); + if (!atomparsing::is_valid_true_atom(value, iter.remaining_len())) { return T_ATOM_ERROR; } + tape.append(0, internal::tape_type::TRUE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_false_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("false"); + if (!atomparsing::is_valid_false_atom(value)) { return F_ATOM_ERROR; } + tape.append(0, internal::tape_type::FALSE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_false_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("false"); + if (!atomparsing::is_valid_false_atom(value, iter.remaining_len())) { return F_ATOM_ERROR; } + tape.append(0, internal::tape_type::FALSE_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_null_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("null"); + if (!atomparsing::is_valid_null_atom(value)) { return N_ATOM_ERROR; } + tape.append(0, internal::tape_type::NULL_VALUE); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_null_atom(json_iterator &iter, const uint8_t *value) noexcept { + iter.log_value("null"); + if (!atomparsing::is_valid_null_atom(value, iter.remaining_len())) { return N_ATOM_ERROR; } + tape.append(0, internal::tape_type::NULL_VALUE); + return SUCCESS; +} + +// private: + +simdjson_inline uint32_t tape_builder::next_tape_index(json_iterator &iter) const noexcept { + return uint32_t(tape.next_tape_loc - iter.dom_parser.doc->tape.get()); +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::empty_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept { + auto start_index = next_tape_index(iter); + tape.append(start_index+2, start); + tape.append(start_index, end); + return SUCCESS; +} + +simdjson_inline void tape_builder::start_container(json_iterator &iter) noexcept { + iter.dom_parser.open_containers[iter.depth].tape_index = next_tape_index(iter); + iter.dom_parser.open_containers[iter.depth].count = 0; + tape.skip(); // We don't actually *write* the start element until the end. +} + +simdjson_warn_unused simdjson_inline error_code tape_builder::end_container(json_iterator &iter, internal::tape_type start, internal::tape_type end) noexcept { + // Write the ending tape element, pointing at the start location + const uint32_t start_tape_index = iter.dom_parser.open_containers[iter.depth].tape_index; + tape.append(start_tape_index, end); + // Write the start tape element, pointing at the end location (and including count) + // count can overflow if it exceeds 24 bits... so we saturate + // the convention being that a cnt of 0xffffff or more is undetermined in value (>= 0xffffff). + const uint32_t count = iter.dom_parser.open_containers[iter.depth].count; + const uint32_t cntsat = count > 0xFFFFFF ? 0xFFFFFF : count; + tape_writer::write(iter.dom_parser.doc->tape[start_tape_index], next_tape_index(iter) | (uint64_t(cntsat) << 32), start); + return SUCCESS; +} + +simdjson_inline uint8_t *tape_builder::on_start_string(json_iterator &iter) noexcept { + // we advance the point, accounting for the fact that we have a NULL termination + tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::STRING); + return current_string_buf_loc + sizeof(uint32_t); +} + +simdjson_inline void tape_builder::on_end_string(uint8_t *dst) noexcept { + uint32_t str_length = uint32_t(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 + // Currently unneeded because we refuse to parse docs larger or equal to 4GB. + memcpy(current_string_buf_loc, &str_length, sizeof(uint32_t)); + // NULL termination is still handy if you expect all your strings to + // be NULL terminated? It comes at a small cost + *dst = 0; + current_string_buf_loc = dst + 1; +} + +} // namespace stage2 +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H +/* end file generic/stage2/tape_builder.h for westmere */ +/* end file generic/stage2/amalgamated.h for westmere */ + +// +// Stage 1 +// + +namespace simdjson { +namespace westmere { + +simdjson_warn_unused error_code implementation::create_dom_parser_implementation( + size_t capacity, + size_t max_depth, + std::unique_ptr& dst +) const noexcept { + dst.reset( new (std::nothrow) dom_parser_implementation() ); + if (!dst) { return MEMALLOC; } + if (auto err = dst->set_capacity(capacity)) + return err; + if (auto err = dst->set_max_depth(max_depth)) + return err; + return SUCCESS; +} + +namespace { + +using namespace simd; + +simdjson_inline json_character_block json_character_block::classify(const simd::simd8x64& in) { + // These lookups rely on the fact that anything < 127 will match the lower 4 bits, which is why + // we can't use the generic lookup_16. + auto whitespace_table = simd8::repeat_16(' ', 100, 100, 100, 17, 100, 113, 2, 100, '\t', '\n', 112, 100, '\r', 100, 100); + + // The 6 operators (:,[]{}) have these values: + // + // , 2C + // : 3A + // [ 5B + // { 7B + // ] 5D + // } 7D + // + // If you use | 0x20 to turn [ and ] into { and }, the lower 4 bits of each character is unique. + // We exploit this, using a simd 4-bit lookup to tell us which character match against, and then + // match it (against | 0x20). + // + // To prevent recognizing other characters, everything else gets compared with 0, which cannot + // match due to the | 0x20. + // + // NOTE: Due to the | 0x20, this ALSO treats and (control characters 0C and 1A) like , + // and :. This gets caught in stage 2, which checks the actual character to ensure the right + // operators are in the right places. + const auto op_table = simd8::repeat_16( + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, ':', '{', // : = 3A, [ = 5B, { = 7B + ',', '}', 0, 0 // , = 2C, ] = 5D, } = 7D + ); + + // We compute whitespace and op separately. If the code later only use one or the + // other, given the fact that all functions are aggressively inlined, we can + // hope that useless computations will be omitted. This is namely case when + // minifying (we only need whitespace). + + + const uint64_t whitespace = in.eq({ + _mm_shuffle_epi8(whitespace_table, in.chunks[0]), + _mm_shuffle_epi8(whitespace_table, in.chunks[1]), + _mm_shuffle_epi8(whitespace_table, in.chunks[2]), + _mm_shuffle_epi8(whitespace_table, in.chunks[3]) + }); + // Turn [ and ] into { and } + const simd8x64 curlified{ + in.chunks[0] | 0x20, + in.chunks[1] | 0x20, + in.chunks[2] | 0x20, + in.chunks[3] | 0x20 + }; + const uint64_t op = curlified.eq({ + _mm_shuffle_epi8(op_table, in.chunks[0]), + _mm_shuffle_epi8(op_table, in.chunks[1]), + _mm_shuffle_epi8(op_table, in.chunks[2]), + _mm_shuffle_epi8(op_table, in.chunks[3]) + }); + return { whitespace, op }; +} + +simdjson_inline bool is_ascii(const simd8x64& input) { + return input.reduce_or().is_ascii(); +} + +simdjson_unused simdjson_inline simd8 must_be_continuation(const simd8 prev1, const simd8 prev2, const simd8 prev3) { + simd8 is_second_byte = prev1.saturating_sub(0xc0u-1); // Only 11______ will be > 0 + simd8 is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0 + simd8 is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0 + // Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine. + return simd8(is_second_byte | is_third_byte | is_fourth_byte) > int8_t(0); +} + +simdjson_inline simd8 must_be_2_3_continuation(const simd8 prev2, const simd8 prev3) { + simd8 is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0 + simd8 is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0 + // Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine. + return simd8(is_third_byte | is_fourth_byte) > int8_t(0); +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +// +// Stage 2 +// + +// +// Implementation-specific overrides +// + +namespace simdjson { +namespace westmere { + +simdjson_warn_unused error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept { + return westmere::stage1::json_minifier::minify<64>(buf, len, dst, dst_len); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, stage1_mode streaming) noexcept { + this->buf = _buf; + this->len = _len; + return westmere::stage1::json_structural_indexer::index<64>(_buf, _len, *this, streaming); +} + +simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t len) const noexcept { + return westmere::stage1::generic_validate_utf8(buf,len); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { + return stage2::tape_builder::parse_document(*this, _doc); +} + +simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { + return stage2::tape_builder::parse_document(*this, _doc); +} + +simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { + return westmere::stringparsing::parse_string(src, dst, replacement_char); +} + +simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept { + return westmere::stringparsing::parse_wobbly_string(src, dst); +} + +simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { + auto error = stage1(_buf, _len, stage1_mode::regular); + if (error) { return error; } + return stage2(_doc); +} + +} // namespace westmere +} // namespace simdjson + +/* including simdjson/westmere/end.h: #include */ +/* begin file simdjson/westmere/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_WESTMERE +SIMDJSON_UNTARGET_REGION +#endif + +/* undefining SIMDJSON_IMPLEMENTATION from "westmere" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/westmere/end.h */ + +#endif // SIMDJSON_SRC_WESTMERE_CPP +/* end file westmere.cpp */ +#endif + +/* undefining SIMDJSON_CONDITIONAL_INCLUDE */ +#undef SIMDJSON_CONDITIONAL_INCLUDE + +SIMDJSON_POP_DISABLE_UNUSED_WARNINGS + +/* end file simdjson.cpp */ diff --git a/src/privateer/cpp/third-party/simdjson/simdjson.h b/src/privateer/cpp/third-party/simdjson/simdjson.h new file mode 100644 index 000000000..8f8141275 --- /dev/null +++ b/src/privateer/cpp/third-party/simdjson/simdjson.h @@ -0,0 +1,88545 @@ +/* auto-generated on . Do not edit! */ +/* including simdjson.h: */ +/* begin file simdjson.h */ +#ifndef SIMDJSON_H +#define SIMDJSON_H + +/** + * @mainpage + * + * Check the [README.md](https://github.com/simdjson/simdjson/blob/master/README.md#simdjson--parsing-gigabytes-of-json-per-second). + * + * Sample code. See https://github.com/simdjson/simdjson/blob/master/doc/basics.md for more examples. + + #include "simdjson.h" + + int main(void) { + // load from `twitter.json` file: + simdjson::dom::parser parser; + simdjson::dom::element tweets = parser.load("twitter.json"); + std::cout << tweets["search_metadata"]["count"] << " results." << std::endl; + + // Parse and iterate through an array of objects + auto abstract_json = R"( [ + { "12345" : {"a":12.34, "b":56.78, "c": 9998877} }, + { "12545" : {"a":11.44, "b":12.78, "c": 11111111} } + ] )"_padded; + + for (simdjson::dom::object obj : parser.parse(abstract_json)) { + for(const auto key_value : obj) { + cout << "key: " << key_value.key << " : "; + simdjson::dom::object innerobj = key_value.value; + cout << "a: " << double(innerobj["a"]) << ", "; + cout << "b: " << double(innerobj["b"]) << ", "; + cout << "c: " << int64_t(innerobj["c"]) << endl; + } + } + } + */ + +/* including simdjson/common_defs.h: #include "simdjson/common_defs.h" */ +/* begin file simdjson/common_defs.h */ +#ifndef SIMDJSON_COMMON_DEFS_H +#define SIMDJSON_COMMON_DEFS_H + +#include +/* including simdjson/compiler_check.h: #include "simdjson/compiler_check.h" */ +/* begin file simdjson/compiler_check.h */ +#ifndef SIMDJSON_COMPILER_CHECK_H +#define SIMDJSON_COMPILER_CHECK_H + +#ifndef __cplusplus +#error simdjson requires a C++ compiler +#endif + +#ifndef SIMDJSON_CPLUSPLUS +#if defined(_MSVC_LANG) && !defined(__clang__) +#define SIMDJSON_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG) +#else +#define SIMDJSON_CPLUSPLUS __cplusplus +#endif +#endif + +// C++ 17 +#if !defined(SIMDJSON_CPLUSPLUS17) && (SIMDJSON_CPLUSPLUS >= 201703L) +#define SIMDJSON_CPLUSPLUS17 1 +#endif + +// C++ 14 +#if !defined(SIMDJSON_CPLUSPLUS14) && (SIMDJSON_CPLUSPLUS >= 201402L) +#define SIMDJSON_CPLUSPLUS14 1 +#endif + +// C++ 11 +#if !defined(SIMDJSON_CPLUSPLUS11) && (SIMDJSON_CPLUSPLUS >= 201103L) +#define SIMDJSON_CPLUSPLUS11 1 +#endif + +#ifndef SIMDJSON_CPLUSPLUS11 +#error simdjson requires a compiler compliant with the C++11 standard +#endif + +#ifndef SIMDJSON_IF_CONSTEXPR +#if SIMDJSON_CPLUSPLUS17 +#define SIMDJSON_IF_CONSTEXPR if constexpr +#else +#define SIMDJSON_IF_CONSTEXPR if +#endif +#endif + +#endif // SIMDJSON_COMPILER_CHECK_H +/* end file simdjson/compiler_check.h */ +/* including simdjson/portability.h: #include "simdjson/portability.h" */ +/* begin file simdjson/portability.h */ +#ifndef SIMDJSON_PORTABILITY_H +#define SIMDJSON_PORTABILITY_H + +#include +#include +#include +#include +#include +#ifndef _WIN32 +// strcasecmp, strncasecmp +#include +#endif + +#ifdef _MSC_VER +#define SIMDJSON_VISUAL_STUDIO 1 +/** + * We want to differentiate carefully between + * clang under visual studio and regular visual + * studio. + * + * Under clang for Windows, we enable: + * * target pragmas so that part and only part of the + * code gets compiled for advanced instructions. + * + */ +#ifdef __clang__ +// clang under visual studio +#define SIMDJSON_CLANG_VISUAL_STUDIO 1 +#else +// just regular visual studio (best guess) +#define SIMDJSON_REGULAR_VISUAL_STUDIO 1 +#endif // __clang__ +#endif // _MSC_VER + +#if defined(__x86_64__) || defined(_M_AMD64) +#define SIMDJSON_IS_X86_64 1 +#elif defined(__aarch64__) || defined(_M_ARM64) +#define SIMDJSON_IS_ARM64 1 +#elif defined(__riscv) && __riscv_xlen == 64 +#define SIMDJSON_IS_RISCV64 1 +#elif defined(__PPC64__) || defined(_M_PPC64) +#if defined(__ALTIVEC__) +#define SIMDJSON_IS_PPC64_VMX 1 +#endif // defined(__ALTIVEC__) +#else +#define SIMDJSON_IS_32BITS 1 + +#if defined(_M_IX86) || defined(__i386__) +#define SIMDJSON_IS_X86_32BITS 1 +#elif defined(__arm__) || defined(_M_ARM) +#define SIMDJSON_IS_ARM_32BITS 1 +#elif defined(__PPC__) || defined(_M_PPC) +#define SIMDJSON_IS_PPC_32BITS 1 +#endif + +#endif // defined(__x86_64__) || defined(_M_AMD64) +#ifndef SIMDJSON_IS_32BITS +#define SIMDJSON_IS_32BITS 0 +#endif + +#if SIMDJSON_IS_32BITS +#ifndef SIMDJSON_NO_PORTABILITY_WARNING +// In the future, we should allow programmers +// to get warning. +#endif // SIMDJSON_NO_PORTABILITY_WARNING +#endif // SIMDJSON_IS_32BITS + +#define SIMDJSON_CAT_IMPLEMENTATION_(a,...) a ## __VA_ARGS__ +#define SIMDJSON_CAT(a,...) SIMDJSON_CAT_IMPLEMENTATION_(a, __VA_ARGS__) + +#define SIMDJSON_STRINGIFY_IMPLEMENTATION_(a,...) #a SIMDJSON_STRINGIFY(__VA_ARGS__) +#define SIMDJSON_STRINGIFY(a,...) SIMDJSON_CAT_IMPLEMENTATION_(a, __VA_ARGS__) + +// this is almost standard? +#undef SIMDJSON_STRINGIFY_IMPLEMENTATION_ +#undef SIMDJSON_STRINGIFY +#define SIMDJSON_STRINGIFY_IMPLEMENTATION_(a) #a +#define SIMDJSON_STRINGIFY(a) SIMDJSON_STRINGIFY_IMPLEMENTATION_(a) + +// Our fast kernels require 64-bit systems. +// +// On 32-bit x86, we lack 64-bit popcnt, lzcnt, blsr instructions. +// Furthermore, the number of SIMD registers is reduced. +// +// On 32-bit ARM, we would have smaller registers. +// +// The simdjson users should still have the fallback kernel. It is +// slower, but it should run everywhere. + +// +// Enable valid runtime implementations, and select SIMDJSON_BUILTIN_IMPLEMENTATION +// + +// We are going to use runtime dispatch. +#if SIMDJSON_IS_X86_64 +#ifdef __clang__ +// clang does not have GCC push pop +// warning: clang attribute push can't be used within a namespace in clang up +// til 8.0 so SIMDJSON_TARGET_REGION and SIMDJSON_UNTARGET_REGION must be *outside* of a +// namespace. +#define SIMDJSON_TARGET_REGION(T) \ + _Pragma(SIMDJSON_STRINGIFY( \ + clang attribute push(__attribute__((target(T))), apply_to = function))) +#define SIMDJSON_UNTARGET_REGION _Pragma("clang attribute pop") +#elif defined(__GNUC__) +// GCC is easier +#define SIMDJSON_TARGET_REGION(T) \ + _Pragma("GCC push_options") _Pragma(SIMDJSON_STRINGIFY(GCC target(T))) +#define SIMDJSON_UNTARGET_REGION _Pragma("GCC pop_options") +#endif // clang then gcc + +#endif // x86 + +// Default target region macros don't do anything. +#ifndef SIMDJSON_TARGET_REGION +#define SIMDJSON_TARGET_REGION(T) +#define SIMDJSON_UNTARGET_REGION +#endif + +// Is threading enabled? +#if defined(_REENTRANT) || defined(_MT) +#ifndef SIMDJSON_THREADS_ENABLED +#define SIMDJSON_THREADS_ENABLED +#endif +#endif + +// workaround for large stack sizes under -O0. +// https://github.com/simdjson/simdjson/issues/691 +#ifdef __APPLE__ +#ifndef __OPTIMIZE__ +// Apple systems have small stack sizes in secondary threads. +// Lack of compiler optimization may generate high stack usage. +// Users may want to disable threads for safety, but only when +// in debug mode which we detect by the fact that the __OPTIMIZE__ +// macro is not defined. +#undef SIMDJSON_THREADS_ENABLED +#endif +#endif + + +#if defined(__clang__) +#define SIMDJSON_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"))) +#elif defined(__GNUC__) +#define SIMDJSON_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined)) +#else +#define SIMDJSON_NO_SANITIZE_UNDEFINED +#endif + + +#if defined(__clang__) || defined(__GNUC__) +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) +#define SIMDJSON_NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory"))) +# endif // if __has_feature(memory_sanitizer) +#endif // defined(__has_feature) +#endif +// make sure it is defined as 'nothing' if it is unapplicable. +#ifndef SIMDJSON_NO_SANITIZE_MEMORY +#define SIMDJSON_NO_SANITIZE_MEMORY +#endif + +#if SIMDJSON_VISUAL_STUDIO +// This is one case where we do not distinguish between +// regular visual studio and clang under visual studio. +// clang under Windows has _stricmp (like visual studio) but not strcasecmp (as clang normally has) +#define simdjson_strcasecmp _stricmp +#define simdjson_strncasecmp _strnicmp +#else +// The strcasecmp, strncasecmp, and strcasestr functions do not work with multibyte strings (e.g. UTF-8). +// So they are only useful for ASCII in our context. +// https://www.gnu.org/software/libunistring/manual/libunistring.html#char-_002a-strings +#define simdjson_strcasecmp strcasecmp +#define simdjson_strncasecmp strncasecmp +#endif + +#if defined(NDEBUG) || defined(__OPTIMIZE__) || (defined(_MSC_VER) && !defined(_DEBUG)) +// If NDEBUG is set, or __OPTIMIZE__ is set, or we are under MSVC in release mode, +// then do away with asserts and use __assume. +#if SIMDJSON_VISUAL_STUDIO +#define SIMDJSON_UNREACHABLE() __assume(0) +#define SIMDJSON_ASSUME(COND) __assume(COND) +#else +#define SIMDJSON_UNREACHABLE() __builtin_unreachable(); +#define SIMDJSON_ASSUME(COND) do { if (!(COND)) __builtin_unreachable(); } while (0) +#endif + +#else // defined(NDEBUG) || defined(__OPTIMIZE__) || (defined(_MSC_VER) && !defined(_DEBUG)) +// This should only ever be enabled in debug mode. +#define SIMDJSON_UNREACHABLE() assert(0); +#define SIMDJSON_ASSUME(COND) assert(COND) + +#endif + +#endif // SIMDJSON_PORTABILITY_H +/* end file simdjson/portability.h */ + +namespace simdjson { +namespace internal { +/** + * @private + * Our own implementation of the C++17 to_chars function. + * Defined in src/to_chars + */ +char *to_chars(char *first, const char *last, double value); +/** + * @private + * A number parsing routine. + * Defined in src/from_chars + */ +double from_chars(const char *first) noexcept; +double from_chars(const char *first, const char* end) noexcept; +} + +#ifndef SIMDJSON_EXCEPTIONS +#if __cpp_exceptions +#define SIMDJSON_EXCEPTIONS 1 +#else +#define SIMDJSON_EXCEPTIONS 0 +#endif +#endif + +} // namespace simdjson + +#if defined(__GNUC__) + // Marks a block with a name so that MCA analysis can see it. + #define SIMDJSON_BEGIN_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-BEGIN " #name); + #define SIMDJSON_END_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-END " #name); + #define SIMDJSON_DEBUG_BLOCK(name, block) BEGIN_DEBUG_BLOCK(name); block; END_DEBUG_BLOCK(name); +#else + #define SIMDJSON_BEGIN_DEBUG_BLOCK(name) + #define SIMDJSON_END_DEBUG_BLOCK(name) + #define SIMDJSON_DEBUG_BLOCK(name, block) +#endif + +// Align to N-byte boundary +#define SIMDJSON_ROUNDUP_N(a, n) (((a) + ((n)-1)) & ~((n)-1)) +#define SIMDJSON_ROUNDDOWN_N(a, n) ((a) & ~((n)-1)) + +#define SIMDJSON_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0) + +#if SIMDJSON_REGULAR_VISUAL_STUDIO + + #define simdjson_really_inline __forceinline + #define simdjson_never_inline __declspec(noinline) + + #define simdjson_unused + #define simdjson_warn_unused + + #ifndef simdjson_likely + #define simdjson_likely(x) x + #endif + #ifndef simdjson_unlikely + #define simdjson_unlikely(x) x + #endif + + #define SIMDJSON_PUSH_DISABLE_WARNINGS __pragma(warning( push )) + #define SIMDJSON_PUSH_DISABLE_ALL_WARNINGS __pragma(warning( push, 0 )) + #define SIMDJSON_DISABLE_VS_WARNING(WARNING_NUMBER) __pragma(warning( disable : WARNING_NUMBER )) + // Get rid of Intellisense-only warnings (Code Analysis) + // Though __has_include is C++17, it is supported in Visual Studio 2017 or better (_MSC_VER>=1910). + #ifdef __has_include + #if __has_include() + #include + #define SIMDJSON_DISABLE_UNDESIRED_WARNINGS SIMDJSON_DISABLE_VS_WARNING(ALL_CPPCORECHECK_WARNINGS) + #endif + #endif + + #ifndef SIMDJSON_DISABLE_UNDESIRED_WARNINGS + #define SIMDJSON_DISABLE_UNDESIRED_WARNINGS + #endif + + #define SIMDJSON_DISABLE_DEPRECATED_WARNING SIMDJSON_DISABLE_VS_WARNING(4996) + #define SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING + #define SIMDJSON_POP_DISABLE_WARNINGS __pragma(warning( pop )) + + #define SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS + #define SIMDJSON_POP_DISABLE_UNUSED_WARNINGS + +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + + #define simdjson_really_inline inline __attribute__((always_inline)) + #define simdjson_never_inline inline __attribute__((noinline)) + + #define simdjson_unused __attribute__((unused)) + #define simdjson_warn_unused __attribute__((warn_unused_result)) + + #ifndef simdjson_likely + #define simdjson_likely(x) __builtin_expect(!!(x), 1) + #endif + #ifndef simdjson_unlikely + #define simdjson_unlikely(x) __builtin_expect(!!(x), 0) + #endif + + #define SIMDJSON_PUSH_DISABLE_WARNINGS _Pragma("GCC diagnostic push") + // gcc doesn't seem to disable all warnings with all and extra, add warnings here as necessary + // We do it separately for clang since it has different warnings. + #ifdef __clang__ + // clang is missing -Wmaybe-uninitialized. + #define SIMDJSON_PUSH_DISABLE_ALL_WARNINGS SIMDJSON_PUSH_DISABLE_WARNINGS \ + SIMDJSON_DISABLE_GCC_WARNING(-Weffc++) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wall) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wconversion) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wextra) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wattributes) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wimplicit-fallthrough) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wnon-virtual-dtor) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wreturn-type) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wshadow) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wunused-parameter) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wunused-variable) + #else // __clang__ + #define SIMDJSON_PUSH_DISABLE_ALL_WARNINGS SIMDJSON_PUSH_DISABLE_WARNINGS \ + SIMDJSON_DISABLE_GCC_WARNING(-Weffc++) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wall) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wconversion) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wextra) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wattributes) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wimplicit-fallthrough) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wnon-virtual-dtor) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wreturn-type) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wshadow) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wunused-parameter) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wunused-variable) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wmaybe-uninitialized) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wformat-security) + #endif // __clang__ + + #define SIMDJSON_PRAGMA(P) _Pragma(#P) + #define SIMDJSON_DISABLE_GCC_WARNING(WARNING) SIMDJSON_PRAGMA(GCC diagnostic ignored #WARNING) + #if SIMDJSON_CLANG_VISUAL_STUDIO + #define SIMDJSON_DISABLE_UNDESIRED_WARNINGS SIMDJSON_DISABLE_GCC_WARNING(-Wmicrosoft-include) + #else + #define SIMDJSON_DISABLE_UNDESIRED_WARNINGS + #endif + #define SIMDJSON_DISABLE_DEPRECATED_WARNING SIMDJSON_DISABLE_GCC_WARNING(-Wdeprecated-declarations) + #define SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING SIMDJSON_DISABLE_GCC_WARNING(-Wstrict-overflow) + #define SIMDJSON_POP_DISABLE_WARNINGS _Pragma("GCC diagnostic pop") + + #define SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS SIMDJSON_PUSH_DISABLE_WARNINGS \ + SIMDJSON_DISABLE_GCC_WARNING(-Wunused) + #define SIMDJSON_POP_DISABLE_UNUSED_WARNINGS SIMDJSON_POP_DISABLE_WARNINGS + + + +#endif // MSC_VER + +#if defined(simdjson_inline) + // Prefer the user's definition of simdjson_inline; don't define it ourselves. +#elif defined(__GNUC__) && !defined(__OPTIMIZE__) + // If optimizations are disabled, forcing inlining can lead to significant + // code bloat and high compile times. Don't use simdjson_really_inline for + // unoptimized builds. + #define simdjson_inline inline +#else + // Force inlining for most simdjson functions. + #define simdjson_inline simdjson_really_inline +#endif + +#if SIMDJSON_VISUAL_STUDIO + /** + * Windows users need to do some extra work when building + * or using a dynamic library (DLL). When building, we need + * to set SIMDJSON_DLLIMPORTEXPORT to __declspec(dllexport). + * When *using* the DLL, the user needs to set + * SIMDJSON_DLLIMPORTEXPORT __declspec(dllimport). + * + * Static libraries not need require such work. + * + * It does not matter here whether you are using + * the regular visual studio or clang under visual + * studio, you still need to handle these issues. + * + * Non-Windows systems do not have this complexity. + */ + #if SIMDJSON_BUILDING_WINDOWS_DYNAMIC_LIBRARY + // We set SIMDJSON_BUILDING_WINDOWS_DYNAMIC_LIBRARY when we build a DLL under Windows. + // It should never happen that both SIMDJSON_BUILDING_WINDOWS_DYNAMIC_LIBRARY and + // SIMDJSON_USING_WINDOWS_DYNAMIC_LIBRARY are set. + #define SIMDJSON_DLLIMPORTEXPORT __declspec(dllexport) + #elif SIMDJSON_USING_WINDOWS_DYNAMIC_LIBRARY + // Windows user who call a dynamic library should set SIMDJSON_USING_WINDOWS_DYNAMIC_LIBRARY to 1. + #define SIMDJSON_DLLIMPORTEXPORT __declspec(dllimport) + #else + // We assume by default static linkage + #define SIMDJSON_DLLIMPORTEXPORT + #endif + +/** + * Workaround for the vcpkg package manager. Only vcpkg should + * ever touch the next line. The SIMDJSON_USING_LIBRARY macro is otherwise unused. + */ +#if SIMDJSON_USING_LIBRARY +#define SIMDJSON_DLLIMPORTEXPORT __declspec(dllimport) +#endif +/** + * End of workaround for the vcpkg package manager. + */ +#else + #define SIMDJSON_DLLIMPORTEXPORT +#endif + +// C++17 requires string_view. +#if SIMDJSON_CPLUSPLUS17 +#define SIMDJSON_HAS_STRING_VIEW +#include // by the standard, this has to be safe. +#endif + +// This macro (__cpp_lib_string_view) has to be defined +// for C++17 and better, but if it is otherwise defined, +// we are going to assume that string_view is available +// even if we do not have C++17 support. +#ifdef __cpp_lib_string_view +#define SIMDJSON_HAS_STRING_VIEW +#endif + +// Some systems have string_view even if we do not have C++17 support, +// and even if __cpp_lib_string_view is undefined, it is the case +// with Apple clang version 11. +// We must handle it. *This is important.* +#ifndef SIMDJSON_HAS_STRING_VIEW +#if defined __has_include +// do not combine the next #if with the previous one (unsafe) +#if __has_include () +// now it is safe to trigger the include +#include // though the file is there, it does not follow that we got the implementation +#if defined(_LIBCPP_STRING_VIEW) +// Ah! So we under libc++ which under its Library Fundamentals Technical Specification, which preceded C++17, +// included string_view. +// This means that we have string_view *even though* we may not have C++17. +#define SIMDJSON_HAS_STRING_VIEW +#endif // _LIBCPP_STRING_VIEW +#endif // __has_include () +#endif // defined __has_include +#endif // def SIMDJSON_HAS_STRING_VIEW +// end of complicated but important routine to try to detect string_view. + +// +// Backfill std::string_view using nonstd::string_view on systems where +// we expect that string_view is missing. Important: if we get this wrong, +// we will end up with two string_view definitions and potential trouble. +// That is why we work so hard above to avoid it. +// +#ifndef SIMDJSON_HAS_STRING_VIEW +SIMDJSON_PUSH_DISABLE_ALL_WARNINGS +/* including simdjson/nonstd/string_view.hpp: #include "simdjson/nonstd/string_view.hpp" */ +/* begin file simdjson/nonstd/string_view.hpp */ +// Copyright 2017-2020 by Martin Moene +// +// string-view lite, a C++17-like string_view for C++98 and later. +// For more information see https://github.com/martinmoene/string-view-lite +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// #pragma once // We remove #pragma once here as it generates a warning in some cases. We rely on the include guard. + +#ifndef NONSTD_SV_LITE_H_INCLUDED +#define NONSTD_SV_LITE_H_INCLUDED + +#define string_view_lite_MAJOR 1 +#define string_view_lite_MINOR 7 +#define string_view_lite_PATCH 0 + +#define string_view_lite_VERSION nssv_STRINGIFY(string_view_lite_MAJOR) "." nssv_STRINGIFY(string_view_lite_MINOR) "." nssv_STRINGIFY(string_view_lite_PATCH) + +#define nssv_STRINGIFY( x ) nssv_STRINGIFY_( x ) +#define nssv_STRINGIFY_( x ) #x + +// string-view lite configuration: + +#define nssv_STRING_VIEW_DEFAULT 0 +#define nssv_STRING_VIEW_NONSTD 1 +#define nssv_STRING_VIEW_STD 2 + +// tweak header support: + +#ifdef __has_include +# if __has_include() +# include +# endif +#define nssv_HAVE_TWEAK_HEADER 1 +#else +#define nssv_HAVE_TWEAK_HEADER 0 +//# pragma message("string_view.hpp: Note: Tweak header not supported.") +#endif + +// string_view selection and configuration: + +#if !defined( nssv_CONFIG_SELECT_STRING_VIEW ) +# define nssv_CONFIG_SELECT_STRING_VIEW ( nssv_HAVE_STD_STRING_VIEW ? nssv_STRING_VIEW_STD : nssv_STRING_VIEW_NONSTD ) +#endif + +#ifndef nssv_CONFIG_STD_SV_OPERATOR +# define nssv_CONFIG_STD_SV_OPERATOR 0 +#endif + +#ifndef nssv_CONFIG_USR_SV_OPERATOR +# define nssv_CONFIG_USR_SV_OPERATOR 1 +#endif + +#ifdef nssv_CONFIG_CONVERSION_STD_STRING +# define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS nssv_CONFIG_CONVERSION_STD_STRING +# define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS nssv_CONFIG_CONVERSION_STD_STRING +#endif + +#ifndef nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS +# define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS 1 +#endif + +#ifndef nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS +# define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS 1 +#endif + +#ifndef nssv_CONFIG_NO_STREAM_INSERTION +# define nssv_CONFIG_NO_STREAM_INSERTION 0 +#endif + +#ifndef nssv_CONFIG_CONSTEXPR11_STD_SEARCH +# define nssv_CONFIG_CONSTEXPR11_STD_SEARCH 1 +#endif + +// Control presence of exception handling (try and auto discover): + +#ifndef nssv_CONFIG_NO_EXCEPTIONS +# if defined(_MSC_VER) +# include // for _HAS_EXCEPTIONS +# endif +# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS) +# define nssv_CONFIG_NO_EXCEPTIONS 0 +# else +# define nssv_CONFIG_NO_EXCEPTIONS 1 +# endif +#endif + +// C++ language version detection (C++23 is speculative): +// Note: VC14.0/1900 (VS2015) lacks too much from C++14. + +#ifndef nssv_CPLUSPLUS +# if defined(_MSVC_LANG ) && !defined(__clang__) +# define nssv_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG ) +# else +# define nssv_CPLUSPLUS __cplusplus +# endif +#endif + +#define nssv_CPP98_OR_GREATER ( nssv_CPLUSPLUS >= 199711L ) +#define nssv_CPP11_OR_GREATER ( nssv_CPLUSPLUS >= 201103L ) +#define nssv_CPP11_OR_GREATER_ ( nssv_CPLUSPLUS >= 201103L ) +#define nssv_CPP14_OR_GREATER ( nssv_CPLUSPLUS >= 201402L ) +#define nssv_CPP17_OR_GREATER ( nssv_CPLUSPLUS >= 201703L ) +#define nssv_CPP20_OR_GREATER ( nssv_CPLUSPLUS >= 202002L ) +#define nssv_CPP23_OR_GREATER ( nssv_CPLUSPLUS >= 202300L ) + +// use C++17 std::string_view if available and requested: + +#if nssv_CPP17_OR_GREATER && defined(__has_include ) +# if __has_include( ) +# define nssv_HAVE_STD_STRING_VIEW 1 +# else +# define nssv_HAVE_STD_STRING_VIEW 0 +# endif +#else +# define nssv_HAVE_STD_STRING_VIEW 0 +#endif + +#define nssv_USES_STD_STRING_VIEW ( (nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_STD) || ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_DEFAULT) && nssv_HAVE_STD_STRING_VIEW) ) + +#define nssv_HAVE_STARTS_WITH ( nssv_CPP20_OR_GREATER || !nssv_USES_STD_STRING_VIEW ) +#define nssv_HAVE_ENDS_WITH nssv_HAVE_STARTS_WITH + +// +// Use C++17 std::string_view: +// + +#if nssv_USES_STD_STRING_VIEW + +#include + +// Extensions for std::string: + +#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS + +namespace nonstd { + +template< class CharT, class Traits, class Allocator = std::allocator > +std::basic_string +to_string( std::basic_string_view v, Allocator const & a = Allocator() ) +{ + return std::basic_string( v.begin(), v.end(), a ); +} + +template< class CharT, class Traits, class Allocator > +std::basic_string_view +to_string_view( std::basic_string const & s ) +{ + return std::basic_string_view( s.data(), s.size() ); +} + +// Literal operators sv and _sv: + +#if nssv_CONFIG_STD_SV_OPERATOR + +using namespace std::literals::string_view_literals; + +#endif + +#if nssv_CONFIG_USR_SV_OPERATOR + +inline namespace literals { +inline namespace string_view_literals { + + +constexpr std::string_view operator "" _sv( const char* str, size_t len ) noexcept // (1) +{ + return std::string_view{ str, len }; +} + +constexpr std::u16string_view operator "" _sv( const char16_t* str, size_t len ) noexcept // (2) +{ + return std::u16string_view{ str, len }; +} + +constexpr std::u32string_view operator "" _sv( const char32_t* str, size_t len ) noexcept // (3) +{ + return std::u32string_view{ str, len }; +} + +constexpr std::wstring_view operator "" _sv( const wchar_t* str, size_t len ) noexcept // (4) +{ + return std::wstring_view{ str, len }; +} + +}} // namespace literals::string_view_literals + +#endif // nssv_CONFIG_USR_SV_OPERATOR + +} // namespace nonstd + +#endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS + +namespace nonstd { + +using std::string_view; +using std::wstring_view; +using std::u16string_view; +using std::u32string_view; +using std::basic_string_view; + +// literal "sv" and "_sv", see above + +using std::operator==; +using std::operator!=; +using std::operator<; +using std::operator<=; +using std::operator>; +using std::operator>=; + +using std::operator<<; + +} // namespace nonstd + +#else // nssv_HAVE_STD_STRING_VIEW + +// +// Before C++17: use string_view lite: +// + +// Compiler versions: +// +// MSVC++ 6.0 _MSC_VER == 1200 nssv_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0) +// MSVC++ 7.0 _MSC_VER == 1300 nssv_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002) +// MSVC++ 7.1 _MSC_VER == 1310 nssv_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003) +// MSVC++ 8.0 _MSC_VER == 1400 nssv_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005) +// MSVC++ 9.0 _MSC_VER == 1500 nssv_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008) +// MSVC++ 10.0 _MSC_VER == 1600 nssv_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010) +// MSVC++ 11.0 _MSC_VER == 1700 nssv_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012) +// MSVC++ 12.0 _MSC_VER == 1800 nssv_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013) +// MSVC++ 14.0 _MSC_VER == 1900 nssv_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015) +// MSVC++ 14.1 _MSC_VER >= 1910 nssv_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017) +// MSVC++ 14.2 _MSC_VER >= 1920 nssv_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019) + +#if defined(_MSC_VER ) && !defined(__clang__) +# define nssv_COMPILER_MSVC_VER (_MSC_VER ) +# define nssv_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) ) +#else +# define nssv_COMPILER_MSVC_VER 0 +# define nssv_COMPILER_MSVC_VERSION 0 +#endif + +#define nssv_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) ) + +#if defined( __apple_build_version__ ) +# define nssv_COMPILER_APPLECLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) +# define nssv_COMPILER_CLANG_VERSION 0 +#elif defined( __clang__ ) +# define nssv_COMPILER_APPLECLANG_VERSION 0 +# define nssv_COMPILER_CLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) +#else +# define nssv_COMPILER_APPLECLANG_VERSION 0 +# define nssv_COMPILER_CLANG_VERSION 0 +#endif + +#if defined(__GNUC__) && !defined(__clang__) +# define nssv_COMPILER_GNUC_VERSION nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +#else +# define nssv_COMPILER_GNUC_VERSION 0 +#endif + +// half-open range [lo..hi): +#define nssv_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) ) + +// Presence of language and library features: + +#ifdef _HAS_CPP0X +# define nssv_HAS_CPP0X _HAS_CPP0X +#else +# define nssv_HAS_CPP0X 0 +#endif + +// Unless defined otherwise below, consider VC14 as C++11 for string-view-lite: + +#if nssv_COMPILER_MSVC_VER >= 1900 +# undef nssv_CPP11_OR_GREATER +# define nssv_CPP11_OR_GREATER 1 +#endif + +#define nssv_CPP11_90 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1500) +#define nssv_CPP11_100 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1600) +#define nssv_CPP11_110 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1700) +#define nssv_CPP11_120 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1800) +#define nssv_CPP11_140 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1900) +#define nssv_CPP11_141 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1910) + +#define nssv_CPP14_000 (nssv_CPP14_OR_GREATER) +#define nssv_CPP17_000 (nssv_CPP17_OR_GREATER) + +// Presence of C++11 language features: + +#define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140 +#define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140 +#define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140 +#define nssv_HAVE_IS_DEFAULT nssv_CPP11_140 +#define nssv_HAVE_IS_DELETE nssv_CPP11_140 +#define nssv_HAVE_NOEXCEPT nssv_CPP11_140 +#define nssv_HAVE_NULLPTR nssv_CPP11_100 +#define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140 +#define nssv_HAVE_UNICODE_LITERALS nssv_CPP11_140 +#define nssv_HAVE_USER_DEFINED_LITERALS nssv_CPP11_140 +#define nssv_HAVE_WCHAR16_T nssv_CPP11_100 +#define nssv_HAVE_WCHAR32_T nssv_CPP11_100 + +#if ! ( ( nssv_CPP11_OR_GREATER && nssv_COMPILER_CLANG_VERSION ) || nssv_BETWEEN( nssv_COMPILER_CLANG_VERSION, 300, 400 ) ) +# define nssv_HAVE_STD_DEFINED_LITERALS nssv_CPP11_140 +#else +# define nssv_HAVE_STD_DEFINED_LITERALS 0 +#endif + +// Presence of C++14 language features: + +#define nssv_HAVE_CONSTEXPR_14 nssv_CPP14_000 + +// Presence of C++17 language features: + +#define nssv_HAVE_NODISCARD nssv_CPP17_000 + +// Presence of C++ library features: + +#define nssv_HAVE_STD_HASH nssv_CPP11_120 + +// Presence of compiler intrinsics: + +// Providing char-type specializations for compare() and length() that +// use compiler intrinsics can improve compile- and run-time performance. +// +// The challenge is in using the right combinations of builtin availability +// and its constexpr-ness. +// +// | compiler | __builtin_memcmp (constexpr) | memcmp (constexpr) | +// |----------|------------------------------|---------------------| +// | clang | 4.0 (>= 4.0 ) | any (? ) | +// | clang-a | 9.0 (>= 9.0 ) | any (? ) | +// | gcc | any (constexpr) | any (? ) | +// | msvc | >= 14.2 C++17 (>= 14.2 ) | any (? ) | + +#define nssv_HAVE_BUILTIN_VER ( (nssv_CPP17_000 && nssv_COMPILER_MSVC_VERSION >= 142) || nssv_COMPILER_GNUC_VERSION > 0 || nssv_COMPILER_CLANG_VERSION >= 400 || nssv_COMPILER_APPLECLANG_VERSION >= 900 ) +#define nssv_HAVE_BUILTIN_CE ( nssv_HAVE_BUILTIN_VER ) + +#define nssv_HAVE_BUILTIN_MEMCMP ( (nssv_HAVE_CONSTEXPR_14 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_14 ) +#define nssv_HAVE_BUILTIN_STRLEN ( (nssv_HAVE_CONSTEXPR_11 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_11 ) + +#ifdef __has_builtin +# define nssv_HAVE_BUILTIN( x ) __has_builtin( x ) +#else +# define nssv_HAVE_BUILTIN( x ) 0 +#endif + +#if nssv_HAVE_BUILTIN(__builtin_memcmp) || nssv_HAVE_BUILTIN_VER +# define nssv_BUILTIN_MEMCMP __builtin_memcmp +#else +# define nssv_BUILTIN_MEMCMP memcmp +#endif + +#if nssv_HAVE_BUILTIN(__builtin_strlen) || nssv_HAVE_BUILTIN_VER +# define nssv_BUILTIN_STRLEN __builtin_strlen +#else +# define nssv_BUILTIN_STRLEN strlen +#endif + +// C++ feature usage: + +#if nssv_HAVE_CONSTEXPR_11 +# define nssv_constexpr constexpr +#else +# define nssv_constexpr /*constexpr*/ +#endif + +#if nssv_HAVE_CONSTEXPR_14 +# define nssv_constexpr14 constexpr +#else +# define nssv_constexpr14 /*constexpr*/ +#endif + +#if nssv_HAVE_EXPLICIT_CONVERSION +# define nssv_explicit explicit +#else +# define nssv_explicit /*explicit*/ +#endif + +#if nssv_HAVE_INLINE_NAMESPACE +# define nssv_inline_ns inline +#else +# define nssv_inline_ns /*inline*/ +#endif + +#if nssv_HAVE_NOEXCEPT +# define nssv_noexcept noexcept +#else +# define nssv_noexcept /*noexcept*/ +#endif + +//#if nssv_HAVE_REF_QUALIFIER +//# define nssv_ref_qual & +//# define nssv_refref_qual && +//#else +//# define nssv_ref_qual /*&*/ +//# define nssv_refref_qual /*&&*/ +//#endif + +#if nssv_HAVE_NULLPTR +# define nssv_nullptr nullptr +#else +# define nssv_nullptr NULL +#endif + +#if nssv_HAVE_NODISCARD +# define nssv_nodiscard [[nodiscard]] +#else +# define nssv_nodiscard /*[[nodiscard]]*/ +#endif + +// Additional includes: + +#include +#include +#include +#include +#include // std::char_traits<> + +#if ! nssv_CONFIG_NO_STREAM_INSERTION +# include +#endif + +#if ! nssv_CONFIG_NO_EXCEPTIONS +# include +#endif + +#if nssv_CPP11_OR_GREATER +# include +#endif + +// Clang, GNUC, MSVC warning suppression macros: + +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wreserved-user-defined-literal" +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wuser-defined-literals" +#elif nssv_COMPILER_GNUC_VERSION >= 480 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wliteral-suffix" +#endif // __clang__ + +#if nssv_COMPILER_MSVC_VERSION >= 140 +# define nssv_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]] +# define nssv_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress: code) ) +# define nssv_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable: codes)) +#else +# define nssv_SUPPRESS_MSGSL_WARNING(expr) +# define nssv_SUPPRESS_MSVC_WARNING(code, descr) +# define nssv_DISABLE_MSVC_WARNINGS(codes) +#endif + +#if defined(__clang__) +# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop") +#elif nssv_COMPILER_GNUC_VERSION >= 480 +# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop") +#elif nssv_COMPILER_MSVC_VERSION >= 140 +# define nssv_RESTORE_WARNINGS() __pragma(warning(pop )) +#else +# define nssv_RESTORE_WARNINGS() +#endif + +// Suppress the following MSVC (GSL) warnings: +// - C4455, non-gsl : 'operator ""sv': literal suffix identifiers that do not +// start with an underscore are reserved +// - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions; +// use brace initialization, gsl::narrow_cast or gsl::narow +// - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead + +nssv_DISABLE_MSVC_WARNINGS( 4455 26481 26472 ) +//nssv_DISABLE_CLANG_WARNINGS( "-Wuser-defined-literals" ) +//nssv_DISABLE_GNUC_WARNINGS( -Wliteral-suffix ) + +namespace nonstd { namespace sv_lite { + +// +// basic_string_view declaration: +// + +template +< + class CharT, + class Traits = std::char_traits +> +class basic_string_view; + +namespace detail { + +// support constexpr comparison in C++14; +// for C++17 and later, use provided traits: + +template< typename CharT > +inline nssv_constexpr14 int compare( CharT const * s1, CharT const * s2, std::size_t count ) +{ + while ( count-- != 0 ) + { + if ( *s1 < *s2 ) return -1; + if ( *s1 > *s2 ) return +1; + ++s1; ++s2; + } + return 0; +} + +#if nssv_HAVE_BUILTIN_MEMCMP + +// specialization of compare() for char, see also generic compare() above: + +inline nssv_constexpr14 int compare( char const * s1, char const * s2, std::size_t count ) +{ + return nssv_BUILTIN_MEMCMP( s1, s2, count ); +} + +#endif + +#if nssv_HAVE_BUILTIN_STRLEN + +// specialization of length() for char, see also generic length() further below: + +inline nssv_constexpr std::size_t length( char const * s ) +{ + return nssv_BUILTIN_STRLEN( s ); +} + +#endif + +#if defined(__OPTIMIZE__) + +// gcc, clang provide __OPTIMIZE__ +// Expect tail call optimization to make length() non-recursive: + +template< typename CharT > +inline nssv_constexpr std::size_t length( CharT * s, std::size_t result = 0 ) +{ + return *s == '\0' ? result : length( s + 1, result + 1 ); +} + +#else // OPTIMIZE + +// non-recursive: + +template< typename CharT > +inline nssv_constexpr14 std::size_t length( CharT * s ) +{ + std::size_t result = 0; + while ( *s++ != '\0' ) + { + ++result; + } + return result; +} + +#endif // OPTIMIZE + +#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER +#if defined(__OPTIMIZE__) + +// gcc, clang provide __OPTIMIZE__ +// Expect tail call optimization to make search() non-recursive: + +template< class CharT, class Traits = std::char_traits > +constexpr const CharT* search( basic_string_view haystack, basic_string_view needle ) +{ + return haystack.starts_with( needle ) ? haystack.begin() : + haystack.empty() ? haystack.end() : search( haystack.substr(1), needle ); +} + +#else // OPTIMIZE + +// non-recursive: + +#if nssv_CONFIG_CONSTEXPR11_STD_SEARCH + +template< class CharT, class Traits = std::char_traits > +constexpr const CharT* search( basic_string_view haystack, basic_string_view needle ) +{ + return std::search( haystack.begin(), haystack.end(), needle.begin(), needle.end() ); +} + +#else // nssv_CONFIG_CONSTEXPR11_STD_SEARCH + +template< class CharT, class Traits = std::char_traits > +nssv_constexpr14 const CharT* search( basic_string_view haystack, basic_string_view needle ) +{ + while ( needle.size() <= haystack.size() ) + { + if ( haystack.starts_with(needle) ) + { + return haystack.cbegin(); + } + haystack = basic_string_view{ haystack.begin() + 1, haystack.size() - 1U }; + } + return haystack.cend(); +} +#endif // nssv_CONFIG_CONSTEXPR11_STD_SEARCH + +#endif // OPTIMIZE +#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER + +} // namespace detail + +// +// basic_string_view: +// + +template +< + class CharT, + class Traits /* = std::char_traits */ +> +class basic_string_view +{ +public: + // Member types: + + typedef Traits traits_type; + typedef CharT value_type; + + typedef CharT * pointer; + typedef CharT const * const_pointer; + typedef CharT & reference; + typedef CharT const & const_reference; + + typedef const_pointer iterator; + typedef const_pointer const_iterator; + typedef std::reverse_iterator< const_iterator > reverse_iterator; + typedef std::reverse_iterator< const_iterator > const_reverse_iterator; + + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + // 24.4.2.1 Construction and assignment: + + nssv_constexpr basic_string_view() nssv_noexcept + : data_( nssv_nullptr ) + , size_( 0 ) + {} + +#if nssv_CPP11_OR_GREATER + nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept = default; +#else + nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept + : data_( other.data_) + , size_( other.size_) + {} +#endif + + nssv_constexpr basic_string_view( CharT const * s, size_type count ) nssv_noexcept // non-standard noexcept + : data_( s ) + , size_( count ) + {} + + nssv_constexpr basic_string_view( CharT const * s) nssv_noexcept // non-standard noexcept + : data_( s ) +#if nssv_CPP17_OR_GREATER + , size_( Traits::length(s) ) +#elif nssv_CPP11_OR_GREATER + , size_( detail::length(s) ) +#else + , size_( Traits::length(s) ) +#endif + {} + +#if nssv_HAVE_NULLPTR +# if nssv_HAVE_IS_DELETE + nssv_constexpr basic_string_view( std::nullptr_t ) nssv_noexcept = delete; +# else + private: nssv_constexpr basic_string_view( std::nullptr_t ) nssv_noexcept; public: +# endif +#endif + + // Assignment: + +#if nssv_CPP11_OR_GREATER + nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept = default; +#else + nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept + { + data_ = other.data_; + size_ = other.size_; + return *this; + } +#endif + + // 24.4.2.2 Iterator support: + + nssv_constexpr const_iterator begin() const nssv_noexcept { return data_; } + nssv_constexpr const_iterator end() const nssv_noexcept { return data_ + size_; } + + nssv_constexpr const_iterator cbegin() const nssv_noexcept { return begin(); } + nssv_constexpr const_iterator cend() const nssv_noexcept { return end(); } + + nssv_constexpr const_reverse_iterator rbegin() const nssv_noexcept { return const_reverse_iterator( end() ); } + nssv_constexpr const_reverse_iterator rend() const nssv_noexcept { return const_reverse_iterator( begin() ); } + + nssv_constexpr const_reverse_iterator crbegin() const nssv_noexcept { return rbegin(); } + nssv_constexpr const_reverse_iterator crend() const nssv_noexcept { return rend(); } + + // 24.4.2.3 Capacity: + + nssv_constexpr size_type size() const nssv_noexcept { return size_; } + nssv_constexpr size_type length() const nssv_noexcept { return size_; } + nssv_constexpr size_type max_size() const nssv_noexcept { return (std::numeric_limits< size_type >::max)(); } + + // since C++20 + nssv_nodiscard nssv_constexpr bool empty() const nssv_noexcept + { + return 0 == size_; + } + + // 24.4.2.4 Element access: + + nssv_constexpr const_reference operator[]( size_type pos ) const + { + return data_at( pos ); + } + + nssv_constexpr14 const_reference at( size_type pos ) const + { +#if nssv_CONFIG_NO_EXCEPTIONS + assert( pos < size() ); +#else + if ( pos >= size() ) + { + throw std::out_of_range("nonstd::string_view::at()"); + } +#endif + return data_at( pos ); + } + + nssv_constexpr const_reference front() const { return data_at( 0 ); } + nssv_constexpr const_reference back() const { return data_at( size() - 1 ); } + + nssv_constexpr const_pointer data() const nssv_noexcept { return data_; } + + // 24.4.2.5 Modifiers: + + nssv_constexpr14 void remove_prefix( size_type n ) + { + assert( n <= size() ); + data_ += n; + size_ -= n; + } + + nssv_constexpr14 void remove_suffix( size_type n ) + { + assert( n <= size() ); + size_ -= n; + } + + nssv_constexpr14 void swap( basic_string_view & other ) nssv_noexcept + { + const basic_string_view tmp(other); + other = *this; + *this = tmp; + } + + // 24.4.2.6 String operations: + + size_type copy( CharT * dest, size_type n, size_type pos = 0 ) const + { +#if nssv_CONFIG_NO_EXCEPTIONS + assert( pos <= size() ); +#else + if ( pos > size() ) + { + throw std::out_of_range("nonstd::string_view::copy()"); + } +#endif + const size_type rlen = (std::min)( n, size() - pos ); + + (void) Traits::copy( dest, data() + pos, rlen ); + + return rlen; + } + + nssv_constexpr14 basic_string_view substr( size_type pos = 0, size_type n = npos ) const + { +#if nssv_CONFIG_NO_EXCEPTIONS + assert( pos <= size() ); +#else + if ( pos > size() ) + { + throw std::out_of_range("nonstd::string_view::substr()"); + } +#endif + return basic_string_view( data() + pos, (std::min)( n, size() - pos ) ); + } + + // compare(), 6x: + + nssv_constexpr14 int compare( basic_string_view other ) const nssv_noexcept // (1) + { +#if nssv_CPP17_OR_GREATER + if ( const int result = Traits::compare( data(), other.data(), (std::min)( size(), other.size() ) ) ) +#else + if ( const int result = detail::compare( data(), other.data(), (std::min)( size(), other.size() ) ) ) +#endif + { + return result; + } + + return size() == other.size() ? 0 : size() < other.size() ? -1 : 1; + } + + nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other ) const // (2) + { + return substr( pos1, n1 ).compare( other ); + } + + nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other, size_type pos2, size_type n2 ) const // (3) + { + return substr( pos1, n1 ).compare( other.substr( pos2, n2 ) ); + } + + nssv_constexpr int compare( CharT const * s ) const // (4) + { + return compare( basic_string_view( s ) ); + } + + nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s ) const // (5) + { + return substr( pos1, n1 ).compare( basic_string_view( s ) ); + } + + nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s, size_type n2 ) const // (6) + { + return substr( pos1, n1 ).compare( basic_string_view( s, n2 ) ); + } + + // 24.4.2.7 Searching: + + // starts_with(), 3x, since C++20: + + nssv_constexpr bool starts_with( basic_string_view v ) const nssv_noexcept // (1) + { + return size() >= v.size() && compare( 0, v.size(), v ) == 0; + } + + nssv_constexpr bool starts_with( CharT c ) const nssv_noexcept // (2) + { + return starts_with( basic_string_view( &c, 1 ) ); + } + + nssv_constexpr bool starts_with( CharT const * s ) const // (3) + { + return starts_with( basic_string_view( s ) ); + } + + // ends_with(), 3x, since C++20: + + nssv_constexpr bool ends_with( basic_string_view v ) const nssv_noexcept // (1) + { + return size() >= v.size() && compare( size() - v.size(), npos, v ) == 0; + } + + nssv_constexpr bool ends_with( CharT c ) const nssv_noexcept // (2) + { + return ends_with( basic_string_view( &c, 1 ) ); + } + + nssv_constexpr bool ends_with( CharT const * s ) const // (3) + { + return ends_with( basic_string_view( s ) ); + } + + // find(), 4x: + + nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1) + { + return assert( v.size() == 0 || v.data() != nssv_nullptr ) + , pos >= size() + ? npos : to_pos( +#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER + detail::search( substr(pos), v ) +#else + std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) +#endif + ); + } + + nssv_constexpr size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept // (2) + { + return find( basic_string_view( &c, 1 ), pos ); + } + + nssv_constexpr size_type find( CharT const * s, size_type pos, size_type n ) const // (3) + { + return find( basic_string_view( s, n ), pos ); + } + + nssv_constexpr size_type find( CharT const * s, size_type pos = 0 ) const // (4) + { + return find( basic_string_view( s ), pos ); + } + + // rfind(), 4x: + + nssv_constexpr14 size_type rfind( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1) + { + if ( size() < v.size() ) + { + return npos; + } + + if ( v.empty() ) + { + return (std::min)( size(), pos ); + } + + const_iterator last = cbegin() + (std::min)( size() - v.size(), pos ) + v.size(); + const_iterator result = std::find_end( cbegin(), last, v.cbegin(), v.cend(), Traits::eq ); + + return result != last ? size_type( result - cbegin() ) : npos; + } + + nssv_constexpr14 size_type rfind( CharT c, size_type pos = npos ) const nssv_noexcept // (2) + { + return rfind( basic_string_view( &c, 1 ), pos ); + } + + nssv_constexpr14 size_type rfind( CharT const * s, size_type pos, size_type n ) const // (3) + { + return rfind( basic_string_view( s, n ), pos ); + } + + nssv_constexpr14 size_type rfind( CharT const * s, size_type pos = npos ) const // (4) + { + return rfind( basic_string_view( s ), pos ); + } + + // find_first_of(), 4x: + + nssv_constexpr size_type find_first_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1) + { + return pos >= size() + ? npos + : to_pos( std::find_first_of( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) ); + } + + nssv_constexpr size_type find_first_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2) + { + return find_first_of( basic_string_view( &c, 1 ), pos ); + } + + nssv_constexpr size_type find_first_of( CharT const * s, size_type pos, size_type n ) const // (3) + { + return find_first_of( basic_string_view( s, n ), pos ); + } + + nssv_constexpr size_type find_first_of( CharT const * s, size_type pos = 0 ) const // (4) + { + return find_first_of( basic_string_view( s ), pos ); + } + + // find_last_of(), 4x: + + nssv_constexpr size_type find_last_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1) + { + return empty() + ? npos + : pos >= size() + ? find_last_of( v, size() - 1 ) + : to_pos( std::find_first_of( const_reverse_iterator( cbegin() + pos + 1 ), crend(), v.cbegin(), v.cend(), Traits::eq ) ); + } + + nssv_constexpr size_type find_last_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2) + { + return find_last_of( basic_string_view( &c, 1 ), pos ); + } + + nssv_constexpr size_type find_last_of( CharT const * s, size_type pos, size_type count ) const // (3) + { + return find_last_of( basic_string_view( s, count ), pos ); + } + + nssv_constexpr size_type find_last_of( CharT const * s, size_type pos = npos ) const // (4) + { + return find_last_of( basic_string_view( s ), pos ); + } + + // find_first_not_of(), 4x: + + nssv_constexpr size_type find_first_not_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1) + { + return pos >= size() + ? npos + : to_pos( std::find_if( cbegin() + pos, cend(), not_in_view( v ) ) ); + } + + nssv_constexpr size_type find_first_not_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2) + { + return find_first_not_of( basic_string_view( &c, 1 ), pos ); + } + + nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos, size_type count ) const // (3) + { + return find_first_not_of( basic_string_view( s, count ), pos ); + } + + nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos = 0 ) const // (4) + { + return find_first_not_of( basic_string_view( s ), pos ); + } + + // find_last_not_of(), 4x: + + nssv_constexpr size_type find_last_not_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1) + { + return empty() + ? npos + : pos >= size() + ? find_last_not_of( v, size() - 1 ) + : to_pos( std::find_if( const_reverse_iterator( cbegin() + pos + 1 ), crend(), not_in_view( v ) ) ); + } + + nssv_constexpr size_type find_last_not_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2) + { + return find_last_not_of( basic_string_view( &c, 1 ), pos ); + } + + nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos, size_type count ) const // (3) + { + return find_last_not_of( basic_string_view( s, count ), pos ); + } + + nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos = npos ) const // (4) + { + return find_last_not_of( basic_string_view( s ), pos ); + } + + // Constants: + +#if nssv_CPP17_OR_GREATER + static nssv_constexpr size_type npos = size_type(-1); +#elif nssv_CPP11_OR_GREATER + enum : size_type { npos = size_type(-1) }; +#else + enum { npos = size_type(-1) }; +#endif + +private: + struct not_in_view + { + const basic_string_view v; + + nssv_constexpr explicit not_in_view( basic_string_view v_ ) : v( v_ ) {} + + nssv_constexpr bool operator()( CharT c ) const + { + return npos == v.find_first_of( c ); + } + }; + + nssv_constexpr size_type to_pos( const_iterator it ) const + { + return it == cend() ? npos : size_type( it - cbegin() ); + } + + nssv_constexpr size_type to_pos( const_reverse_iterator it ) const + { + return it == crend() ? npos : size_type( crend() - it - 1 ); + } + + nssv_constexpr const_reference data_at( size_type pos ) const + { +#if nssv_BETWEEN( nssv_COMPILER_GNUC_VERSION, 1, 500 ) + return data_[pos]; +#else + return assert( pos < size() ), data_[pos]; +#endif + } + +private: + const_pointer data_; + size_type size_; + +public: +#if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS + + template< class Allocator > + basic_string_view( std::basic_string const & s ) nssv_noexcept + : data_( s.data() ) + , size_( s.size() ) + {} + +#if nssv_HAVE_EXPLICIT_CONVERSION + + template< class Allocator > + explicit operator std::basic_string() const + { + return to_string( Allocator() ); + } + +#endif // nssv_HAVE_EXPLICIT_CONVERSION + +#if nssv_CPP11_OR_GREATER + + template< class Allocator = std::allocator > + std::basic_string + to_string( Allocator const & a = Allocator() ) const + { + return std::basic_string( begin(), end(), a ); + } + +#else + + std::basic_string + to_string() const + { + return std::basic_string( begin(), end() ); + } + + template< class Allocator > + std::basic_string + to_string( Allocator const & a ) const + { + return std::basic_string( begin(), end(), a ); + } + +#endif // nssv_CPP11_OR_GREATER + +#endif // nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS +}; + +// +// Non-member functions: +// + +// 24.4.3 Non-member comparison functions: +// lexicographically compare two string views (function template): + +template< class CharT, class Traits > +nssv_constexpr bool operator== ( + basic_string_view lhs, + basic_string_view rhs ) nssv_noexcept +{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } + +template< class CharT, class Traits > +nssv_constexpr bool operator!= ( + basic_string_view lhs, + basic_string_view rhs ) nssv_noexcept +{ return !( lhs == rhs ); } + +template< class CharT, class Traits > +nssv_constexpr bool operator< ( + basic_string_view lhs, + basic_string_view rhs ) nssv_noexcept +{ return lhs.compare( rhs ) < 0; } + +template< class CharT, class Traits > +nssv_constexpr bool operator<= ( + basic_string_view lhs, + basic_string_view rhs ) nssv_noexcept +{ return lhs.compare( rhs ) <= 0; } + +template< class CharT, class Traits > +nssv_constexpr bool operator> ( + basic_string_view lhs, + basic_string_view rhs ) nssv_noexcept +{ return lhs.compare( rhs ) > 0; } + +template< class CharT, class Traits > +nssv_constexpr bool operator>= ( + basic_string_view lhs, + basic_string_view rhs ) nssv_noexcept +{ return lhs.compare( rhs ) >= 0; } + +// Let S be basic_string_view, and sv be an instance of S. +// Implementations shall provide sufficient additional overloads marked +// constexpr and noexcept so that an object t with an implicit conversion +// to S can be compared according to Table 67. + +#if ! nssv_CPP11_OR_GREATER || nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 100, 141 ) + +// accommodate for older compilers: + +// == + +template< class CharT, class Traits> +nssv_constexpr bool operator==( + basic_string_view lhs, + CharT const * rhs ) nssv_noexcept +{ return lhs.size() == detail::length( rhs ) && lhs.compare( rhs ) == 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator==( + CharT const * lhs, + basic_string_view rhs ) nssv_noexcept +{ return detail::length( lhs ) == rhs.size() && rhs.compare( lhs ) == 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator==( + basic_string_view lhs, + std::basic_string rhs ) nssv_noexcept +{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator==( + std::basic_string rhs, + basic_string_view lhs ) nssv_noexcept +{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } + +// != + +template< class CharT, class Traits> +nssv_constexpr bool operator!=( + basic_string_view lhs, + CharT const * rhs ) nssv_noexcept +{ return !( lhs == rhs ); } + +template< class CharT, class Traits> +nssv_constexpr bool operator!=( + CharT const * lhs, + basic_string_view rhs ) nssv_noexcept +{ return !( lhs == rhs ); } + +template< class CharT, class Traits> +nssv_constexpr bool operator!=( + basic_string_view lhs, + std::basic_string rhs ) nssv_noexcept +{ return !( lhs == rhs ); } + +template< class CharT, class Traits> +nssv_constexpr bool operator!=( + std::basic_string rhs, + basic_string_view lhs ) nssv_noexcept +{ return !( lhs == rhs ); } + +// < + +template< class CharT, class Traits> +nssv_constexpr bool operator<( + basic_string_view lhs, + CharT const * rhs ) nssv_noexcept +{ return lhs.compare( rhs ) < 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator<( + CharT const * lhs, + basic_string_view rhs ) nssv_noexcept +{ return rhs.compare( lhs ) > 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator<( + basic_string_view lhs, + std::basic_string rhs ) nssv_noexcept +{ return lhs.compare( rhs ) < 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator<( + std::basic_string rhs, + basic_string_view lhs ) nssv_noexcept +{ return rhs.compare( lhs ) > 0; } + +// <= + +template< class CharT, class Traits> +nssv_constexpr bool operator<=( + basic_string_view lhs, + CharT const * rhs ) nssv_noexcept +{ return lhs.compare( rhs ) <= 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator<=( + CharT const * lhs, + basic_string_view rhs ) nssv_noexcept +{ return rhs.compare( lhs ) >= 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator<=( + basic_string_view lhs, + std::basic_string rhs ) nssv_noexcept +{ return lhs.compare( rhs ) <= 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator<=( + std::basic_string rhs, + basic_string_view lhs ) nssv_noexcept +{ return rhs.compare( lhs ) >= 0; } + +// > + +template< class CharT, class Traits> +nssv_constexpr bool operator>( + basic_string_view lhs, + CharT const * rhs ) nssv_noexcept +{ return lhs.compare( rhs ) > 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator>( + CharT const * lhs, + basic_string_view rhs ) nssv_noexcept +{ return rhs.compare( lhs ) < 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator>( + basic_string_view lhs, + std::basic_string rhs ) nssv_noexcept +{ return lhs.compare( rhs ) > 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator>( + std::basic_string rhs, + basic_string_view lhs ) nssv_noexcept +{ return rhs.compare( lhs ) < 0; } + +// >= + +template< class CharT, class Traits> +nssv_constexpr bool operator>=( + basic_string_view lhs, + CharT const * rhs ) nssv_noexcept +{ return lhs.compare( rhs ) >= 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator>=( + CharT const * lhs, + basic_string_view rhs ) nssv_noexcept +{ return rhs.compare( lhs ) <= 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator>=( + basic_string_view lhs, + std::basic_string rhs ) nssv_noexcept +{ return lhs.compare( rhs ) >= 0; } + +template< class CharT, class Traits> +nssv_constexpr bool operator>=( + std::basic_string rhs, + basic_string_view lhs ) nssv_noexcept +{ return rhs.compare( lhs ) <= 0; } + +#else // newer compilers: + +#define nssv_BASIC_STRING_VIEW_I(T,U) typename std::decay< basic_string_view >::type + +#if defined(_MSC_VER) // issue 40 +# define nssv_MSVC_ORDER(x) , int=x +#else +# define nssv_MSVC_ORDER(x) /*, int=x*/ +#endif + +// == + +template< class CharT, class Traits nssv_MSVC_ORDER(1) > +nssv_constexpr bool operator==( + basic_string_view lhs, + nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs ) nssv_noexcept +{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } + +template< class CharT, class Traits nssv_MSVC_ORDER(2) > +nssv_constexpr bool operator==( + nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, + basic_string_view rhs ) nssv_noexcept +{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } + +// != + +template< class CharT, class Traits nssv_MSVC_ORDER(1) > +nssv_constexpr bool operator!= ( + basic_string_view < CharT, Traits > lhs, + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept +{ return !( lhs == rhs ); } + +template< class CharT, class Traits nssv_MSVC_ORDER(2) > +nssv_constexpr bool operator!= ( + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, + basic_string_view < CharT, Traits > rhs ) nssv_noexcept +{ return !( lhs == rhs ); } + +// < + +template< class CharT, class Traits nssv_MSVC_ORDER(1) > +nssv_constexpr bool operator< ( + basic_string_view < CharT, Traits > lhs, + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept +{ return lhs.compare( rhs ) < 0; } + +template< class CharT, class Traits nssv_MSVC_ORDER(2) > +nssv_constexpr bool operator< ( + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, + basic_string_view < CharT, Traits > rhs ) nssv_noexcept +{ return lhs.compare( rhs ) < 0; } + +// <= + +template< class CharT, class Traits nssv_MSVC_ORDER(1) > +nssv_constexpr bool operator<= ( + basic_string_view < CharT, Traits > lhs, + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept +{ return lhs.compare( rhs ) <= 0; } + +template< class CharT, class Traits nssv_MSVC_ORDER(2) > +nssv_constexpr bool operator<= ( + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, + basic_string_view < CharT, Traits > rhs ) nssv_noexcept +{ return lhs.compare( rhs ) <= 0; } + +// > + +template< class CharT, class Traits nssv_MSVC_ORDER(1) > +nssv_constexpr bool operator> ( + basic_string_view < CharT, Traits > lhs, + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept +{ return lhs.compare( rhs ) > 0; } + +template< class CharT, class Traits nssv_MSVC_ORDER(2) > +nssv_constexpr bool operator> ( + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, + basic_string_view < CharT, Traits > rhs ) nssv_noexcept +{ return lhs.compare( rhs ) > 0; } + +// >= + +template< class CharT, class Traits nssv_MSVC_ORDER(1) > +nssv_constexpr bool operator>= ( + basic_string_view < CharT, Traits > lhs, + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept +{ return lhs.compare( rhs ) >= 0; } + +template< class CharT, class Traits nssv_MSVC_ORDER(2) > +nssv_constexpr bool operator>= ( + nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, + basic_string_view < CharT, Traits > rhs ) nssv_noexcept +{ return lhs.compare( rhs ) >= 0; } + +#undef nssv_MSVC_ORDER +#undef nssv_BASIC_STRING_VIEW_I + +#endif // compiler-dependent approach to comparisons + +// 24.4.4 Inserters and extractors: + +#if ! nssv_CONFIG_NO_STREAM_INSERTION + +namespace detail { + +template< class Stream > +void write_padding( Stream & os, std::streamsize n ) +{ + for ( std::streamsize i = 0; i < n; ++i ) + os.rdbuf()->sputc( os.fill() ); +} + +template< class Stream, class View > +Stream & write_to_stream( Stream & os, View const & sv ) +{ + typename Stream::sentry sentry( os ); + + if ( !sentry ) + return os; + + const std::streamsize length = static_cast( sv.length() ); + + // Whether, and how, to pad: + const bool pad = ( length < os.width() ); + const bool left_pad = pad && ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::right; + + if ( left_pad ) + write_padding( os, os.width() - length ); + + // Write span characters: + os.rdbuf()->sputn( sv.begin(), length ); + + if ( pad && !left_pad ) + write_padding( os, os.width() - length ); + + // Reset output stream width: + os.width( 0 ); + + return os; +} + +} // namespace detail + +template< class CharT, class Traits > +std::basic_ostream & +operator<<( + std::basic_ostream& os, + basic_string_view sv ) +{ + return detail::write_to_stream( os, sv ); +} + +#endif // nssv_CONFIG_NO_STREAM_INSERTION + +// Several typedefs for common character types are provided: + +typedef basic_string_view string_view; +typedef basic_string_view wstring_view; +#if nssv_HAVE_WCHAR16_T +typedef basic_string_view u16string_view; +typedef basic_string_view u32string_view; +#endif + +}} // namespace nonstd::sv_lite + +// +// 24.4.6 Suffix for basic_string_view literals: +// + +#if nssv_HAVE_USER_DEFINED_LITERALS + +namespace nonstd { +nssv_inline_ns namespace literals { +nssv_inline_ns namespace string_view_literals { + +#if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS + +nssv_constexpr nonstd::sv_lite::string_view operator "" sv( const char* str, size_t len ) nssv_noexcept // (1) +{ + return nonstd::sv_lite::string_view{ str, len }; +} + +nssv_constexpr nonstd::sv_lite::u16string_view operator "" sv( const char16_t* str, size_t len ) nssv_noexcept // (2) +{ + return nonstd::sv_lite::u16string_view{ str, len }; +} + +nssv_constexpr nonstd::sv_lite::u32string_view operator "" sv( const char32_t* str, size_t len ) nssv_noexcept // (3) +{ + return nonstd::sv_lite::u32string_view{ str, len }; +} + +nssv_constexpr nonstd::sv_lite::wstring_view operator "" sv( const wchar_t* str, size_t len ) nssv_noexcept // (4) +{ + return nonstd::sv_lite::wstring_view{ str, len }; +} + +#endif // nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS + +#if nssv_CONFIG_USR_SV_OPERATOR + +nssv_constexpr nonstd::sv_lite::string_view operator "" _sv( const char* str, size_t len ) nssv_noexcept // (1) +{ + return nonstd::sv_lite::string_view{ str, len }; +} + +nssv_constexpr nonstd::sv_lite::u16string_view operator "" _sv( const char16_t* str, size_t len ) nssv_noexcept // (2) +{ + return nonstd::sv_lite::u16string_view{ str, len }; +} + +nssv_constexpr nonstd::sv_lite::u32string_view operator "" _sv( const char32_t* str, size_t len ) nssv_noexcept // (3) +{ + return nonstd::sv_lite::u32string_view{ str, len }; +} + +nssv_constexpr nonstd::sv_lite::wstring_view operator "" _sv( const wchar_t* str, size_t len ) nssv_noexcept // (4) +{ + return nonstd::sv_lite::wstring_view{ str, len }; +} + +#endif // nssv_CONFIG_USR_SV_OPERATOR + +}}} // namespace nonstd::literals::string_view_literals + +#endif + +// +// Extensions for std::string: +// + +#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS + +namespace nonstd { +namespace sv_lite { + +// Exclude MSVC 14 (19.00): it yields ambiguous to_string(): + +#if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140 + +template< class CharT, class Traits, class Allocator = std::allocator > +std::basic_string +to_string( basic_string_view v, Allocator const & a = Allocator() ) +{ + return std::basic_string( v.begin(), v.end(), a ); +} + +#else + +template< class CharT, class Traits > +std::basic_string +to_string( basic_string_view v ) +{ + return std::basic_string( v.begin(), v.end() ); +} + +template< class CharT, class Traits, class Allocator > +std::basic_string +to_string( basic_string_view v, Allocator const & a ) +{ + return std::basic_string( v.begin(), v.end(), a ); +} + +#endif // nssv_CPP11_OR_GREATER + +template< class CharT, class Traits, class Allocator > +basic_string_view +to_string_view( std::basic_string const & s ) +{ + return basic_string_view( s.data(), s.size() ); +} + +}} // namespace nonstd::sv_lite + +#endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS + +// +// make types and algorithms available in namespace nonstd: +// + +namespace nonstd { + +using sv_lite::basic_string_view; +using sv_lite::string_view; +using sv_lite::wstring_view; + +#if nssv_HAVE_WCHAR16_T +using sv_lite::u16string_view; +#endif +#if nssv_HAVE_WCHAR32_T +using sv_lite::u32string_view; +#endif + +// literal "sv" + +using sv_lite::operator==; +using sv_lite::operator!=; +using sv_lite::operator<; +using sv_lite::operator<=; +using sv_lite::operator>; +using sv_lite::operator>=; + +#if ! nssv_CONFIG_NO_STREAM_INSERTION +using sv_lite::operator<<; +#endif + +#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS +using sv_lite::to_string; +using sv_lite::to_string_view; +#endif + +} // namespace nonstd + +// 24.4.5 Hash support (C++11): + +// Note: The hash value of a string view object is equal to the hash value of +// the corresponding string object. + +#if nssv_HAVE_STD_HASH + +#include + +namespace std { + +template<> +struct hash< nonstd::string_view > +{ +public: + std::size_t operator()( nonstd::string_view v ) const nssv_noexcept + { + return std::hash()( std::string( v.data(), v.size() ) ); + } +}; + +template<> +struct hash< nonstd::wstring_view > +{ +public: + std::size_t operator()( nonstd::wstring_view v ) const nssv_noexcept + { + return std::hash()( std::wstring( v.data(), v.size() ) ); + } +}; + +template<> +struct hash< nonstd::u16string_view > +{ +public: + std::size_t operator()( nonstd::u16string_view v ) const nssv_noexcept + { + return std::hash()( std::u16string( v.data(), v.size() ) ); + } +}; + +template<> +struct hash< nonstd::u32string_view > +{ +public: + std::size_t operator()( nonstd::u32string_view v ) const nssv_noexcept + { + return std::hash()( std::u32string( v.data(), v.size() ) ); + } +}; + +} // namespace std + +#endif // nssv_HAVE_STD_HASH + +nssv_RESTORE_WARNINGS() + +#endif // nssv_HAVE_STD_STRING_VIEW +#endif // NONSTD_SV_LITE_H_INCLUDED +/* end file simdjson/nonstd/string_view.hpp */ +SIMDJSON_POP_DISABLE_WARNINGS + +namespace std { + using string_view = nonstd::string_view; +} +#endif // SIMDJSON_HAS_STRING_VIEW +#undef SIMDJSON_HAS_STRING_VIEW // We are not going to need this macro anymore. + +/// If EXPR is an error, returns it. +#define SIMDJSON_TRY(EXPR) { auto _err = (EXPR); if (_err) { return _err; } } + +// Unless the programmer has already set SIMDJSON_DEVELOPMENT_CHECKS, +// we want to set it under debug builds. We detect a debug build +// under Visual Studio when the _DEBUG macro is set. Under the other +// compilers, we use the fact that they define __OPTIMIZE__ whenever +// they allow optimizations. +// It is possible that this could miss some cases where SIMDJSON_DEVELOPMENT_CHECKS +// is helpful, but the programmer can set the macro SIMDJSON_DEVELOPMENT_CHECKS. +// It could also wrongly set SIMDJSON_DEVELOPMENT_CHECKS (e.g., if the programmer +// sets _DEBUG in a release build under Visual Studio, or if some compiler fails to +// set the __OPTIMIZE__ macro). +#ifndef SIMDJSON_DEVELOPMENT_CHECKS +#ifdef _MSC_VER +// Visual Studio seems to set _DEBUG for debug builds. +#ifdef _DEBUG +#define SIMDJSON_DEVELOPMENT_CHECKS 1 +#endif // _DEBUG +#else // _MSC_VER +// All other compilers appear to set __OPTIMIZE__ to a positive integer +// when the compiler is optimizing. +#ifndef __OPTIMIZE__ +#define SIMDJSON_DEVELOPMENT_CHECKS 1 +#endif // __OPTIMIZE__ +#endif // _MSC_VER +#endif // SIMDJSON_DEVELOPMENT_CHECKS + +// The SIMDJSON_CHECK_EOF macro is a feature flag for the "don't require padding" +// feature. + +#if SIMDJSON_CPLUSPLUS17 +// if we have C++, then fallthrough is a default attribute +# define simdjson_fallthrough [[fallthrough]] +// check if we have __attribute__ support +#elif defined(__has_attribute) +// check if we have the __fallthrough__ attribute +#if __has_attribute(__fallthrough__) +// we are good to go: +# define simdjson_fallthrough __attribute__((__fallthrough__)) +#endif // __has_attribute(__fallthrough__) +#endif // SIMDJSON_CPLUSPLUS17 +// on some systems, we simply do not have support for fallthrough, so use a default: +#ifndef simdjson_fallthrough +# define simdjson_fallthrough do {} while (0) /* fallthrough */ +#endif // simdjson_fallthrough + +#if SIMDJSON_DEVELOPMENT_CHECKS +#define SIMDJSON_DEVELOPMENT_ASSERT(expr) do { assert ((expr)); } while (0) +#else +#define SIMDJSON_DEVELOPMENT_ASSERT(expr) do { } while (0) +#endif + +#ifndef SIMDJSON_UTF8VALIDATION +#define SIMDJSON_UTF8VALIDATION 1 +#endif + +#ifdef __has_include +// How do we detect that a compiler supports vbmi2? +// For sure if the following header is found, we are ok? +#if __has_include() +#define SIMDJSON_COMPILER_SUPPORTS_VBMI2 1 +#endif +#endif + +#ifdef _MSC_VER +#if _MSC_VER >= 1920 +// Visual Studio 2019 and up support VBMI2 under x64 even if the header +// avx512vbmi2intrin.h is not found. +#define SIMDJSON_COMPILER_SUPPORTS_VBMI2 1 +#endif +#endif + +// By default, we allow AVX512. +#ifndef SIMDJSON_AVX512_ALLOWED +#define SIMDJSON_AVX512_ALLOWED 1 +#endif + +#endif // SIMDJSON_COMMON_DEFS_H +/* end file simdjson/common_defs.h */ + +// This provides the public API for simdjson. +// DOM and ondemand are amalgamated separately, in simdjson.h +/* including simdjson/simdjson_version.h: #include "simdjson/simdjson_version.h" */ +/* begin file simdjson/simdjson_version.h */ +// /include/simdjson/simdjson_version.h automatically generated by release.py, +// do not change by hand +#ifndef SIMDJSON_SIMDJSON_VERSION_H +#define SIMDJSON_SIMDJSON_VERSION_H + +/** The version of simdjson being used (major.minor.revision) */ +#define SIMDJSON_VERSION "3.6.3" + +namespace simdjson { +enum { + /** + * The major version (MAJOR.minor.revision) of simdjson being used. + */ + SIMDJSON_VERSION_MAJOR = 3, + /** + * The minor version (major.MINOR.revision) of simdjson being used. + */ + SIMDJSON_VERSION_MINOR = 6, + /** + * The revision (major.minor.REVISION) of simdjson being used. + */ + SIMDJSON_VERSION_REVISION = 3 +}; +} // namespace simdjson + +#endif // SIMDJSON_SIMDJSON_VERSION_H +/* end file simdjson/simdjson_version.h */ + +/* including simdjson/base.h: #include "simdjson/base.h" */ +/* begin file simdjson/base.h */ +/** + * @file Base declarations for all simdjson headers + * @private + */ +#ifndef SIMDJSON_BASE_H +#define SIMDJSON_BASE_H + +/* skipped duplicate #include "simdjson/common_defs.h" */ +/* skipped duplicate #include "simdjson/compiler_check.h" */ +/* including simdjson/error.h: #include "simdjson/error.h" */ +/* begin file simdjson/error.h */ +#ifndef SIMDJSON_ERROR_H +#define SIMDJSON_ERROR_H + +/* skipped duplicate #include "simdjson/base.h" */ + +#include +#include + +namespace simdjson { + +/** + * All possible errors returned by simdjson. These error codes are subject to change + * and not all simdjson kernel returns the same error code given the same input: it is not + * well defined which error a given input should produce. + * + * Only SUCCESS evaluates to false as a Boolean. All other error codes will evaluate + * to true as a Boolean. + */ +enum error_code { + SUCCESS = 0, ///< No error + CAPACITY, ///< This parser can't support a document that big + MEMALLOC, ///< Error allocating memory, most likely out of memory + TAPE_ERROR, ///< Something went wrong, this is a generic error + DEPTH_ERROR, ///< Your document exceeds the user-specified depth limitation + STRING_ERROR, ///< Problem while parsing a string + T_ATOM_ERROR, ///< Problem while parsing an atom starting with the letter 't' + F_ATOM_ERROR, ///< Problem while parsing an atom starting with the letter 'f' + N_ATOM_ERROR, ///< Problem while parsing an atom starting with the letter 'n' + NUMBER_ERROR, ///< Problem while parsing a number + UTF8_ERROR, ///< the input is not valid UTF-8 + UNINITIALIZED, ///< unknown error, or uninitialized document + EMPTY, ///< no structural element found + UNESCAPED_CHARS, ///< found unescaped characters in a string. + UNCLOSED_STRING, ///< missing quote at the end + UNSUPPORTED_ARCHITECTURE, ///< unsupported architecture + INCORRECT_TYPE, ///< JSON element has a different type than user expected + NUMBER_OUT_OF_RANGE, ///< JSON number does not fit in 64 bits + INDEX_OUT_OF_BOUNDS, ///< JSON array index too large + NO_SUCH_FIELD, ///< JSON field not found in object + IO_ERROR, ///< Error reading a file + INVALID_JSON_POINTER, ///< Invalid JSON pointer reference + INVALID_URI_FRAGMENT, ///< Invalid URI fragment + UNEXPECTED_ERROR, ///< indicative of a bug in simdjson + PARSER_IN_USE, ///< parser is already in use. + OUT_OF_ORDER_ITERATION, ///< tried to iterate an array or object out of order (checked when SIMDJSON_DEVELOPMENT_CHECKS=1) + INSUFFICIENT_PADDING, ///< The JSON doesn't have enough padding for simdjson to safely parse it. + INCOMPLETE_ARRAY_OR_OBJECT, ///< The document ends early. + SCALAR_DOCUMENT_AS_VALUE, ///< A scalar document is treated as a value. + OUT_OF_BOUNDS, ///< Attempted to access location outside of document. + TRAILING_CONTENT, ///< Unexpected trailing content in the JSON input + NUM_ERROR_CODES +}; + +/** + * It is the convention throughout the code that the macro SIMDJSON_DEVELOPMENT_CHECKS determines whether + * we check for OUT_OF_ORDER_ITERATION. The logic behind it is that these errors only occurs when the code + * that was written while breaking some simdjson::ondemand requirement. They should not occur in released + * code after these issues were fixed. + */ + +/** + * Get the error message for the given error code. + * + * dom::parser parser; + * dom::element doc; + * auto error = parser.parse("foo",3).get(doc); + * if (error) { printf("Error: %s\n", error_message(error)); } + * + * @return The error message. + */ +inline const char *error_message(error_code error) noexcept; + +/** + * Write the error message to the output stream + */ +inline std::ostream& operator<<(std::ostream& out, error_code error) noexcept; + +/** + * Exception thrown when an exception-supporting simdjson method is called + */ +struct simdjson_error : public std::exception { + /** + * Create an exception from a simdjson error code. + * @param error The error code + */ + simdjson_error(error_code error) noexcept : _error{error} { } + /** The error message */ + const char *what() const noexcept { return error_message(error()); } + /** The error code */ + error_code error() const noexcept { return _error; } +private: + /** The error code that was used */ + error_code _error; +}; + +namespace internal { + +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + * + * This is a base class for implementations that want to add functions to the result type for + * chaining. + * + * Override like: + * + * struct simdjson_result : public internal::simdjson_result_base { + * simdjson_result() noexcept : internal::simdjson_result_base() {} + * simdjson_result(error_code error) noexcept : internal::simdjson_result_base(error) {} + * simdjson_result(T &&value) noexcept : internal::simdjson_result_base(std::forward(value)) {} + * simdjson_result(T &&value, error_code error) noexcept : internal::simdjson_result_base(value, error) {} + * // Your extra methods here + * } + * + * Then any method returning simdjson_result will be chainable with your methods. + */ +template +struct simdjson_result_base : protected std::pair { + + /** + * Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline simdjson_result_base() noexcept; + + /** + * Create a new error result. + */ + simdjson_inline simdjson_result_base(error_code error) noexcept; + + /** + * Create a new successful result. + */ + simdjson_inline simdjson_result_base(T &&value) noexcept; + + /** + * Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline simdjson_result_base(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; + +}; // struct simdjson_result_base + +} // namespace internal + +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + */ +template +struct simdjson_result : public internal::simdjson_result_base { + /** + * @private Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline simdjson_result() noexcept; + /** + * @private Create a new successful result. + */ + simdjson_inline simdjson_result(T &&value) noexcept; + /** + * @private Create a new error result. + */ + simdjson_inline simdjson_result(error_code error_code) noexcept; + /** + * @private Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline simdjson_result(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_warn_unused simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; + +}; // struct simdjson_result + +#if SIMDJSON_EXCEPTIONS + +template +inline std::ostream& operator<<(std::ostream& out, simdjson_result value) { return out << value.value(); } +#endif // SIMDJSON_EXCEPTIONS + +#ifndef SIMDJSON_DISABLE_DEPRECATED_API +/** + * @deprecated This is an alias and will be removed, use error_code instead + */ +using ErrorValues [[deprecated("This is an alias and will be removed, use error_code instead")]] = error_code; + +/** + * @deprecated Error codes should be stored and returned as `error_code`, use `error_message()` instead. + */ +[[deprecated("Error codes should be stored and returned as `error_code`, use `error_message()` instead.")]] +inline const std::string error_message(int error) noexcept; +#endif // SIMDJSON_DISABLE_DEPRECATED_API +} // namespace simdjson + +#endif // SIMDJSON_ERROR_H +/* end file simdjson/error.h */ +/* skipped duplicate #include "simdjson/portability.h" */ + +/** + * @brief The top level simdjson namespace, containing everything the library provides. + */ +namespace simdjson { + +SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS + +/** The maximum document size supported by simdjson. */ +constexpr size_t SIMDJSON_MAXSIZE_BYTES = 0xFFFFFFFF; + +/** + * The amount of padding needed in a buffer to parse JSON. + * + * The input buf should be readable up to buf + SIMDJSON_PADDING + * this is a stopgap; there should be a better description of the + * main loop and its behavior that abstracts over this + * See https://github.com/simdjson/simdjson/issues/174 + */ +constexpr size_t SIMDJSON_PADDING = 64; + +/** + * By default, simdjson supports this many nested objects and arrays. + * + * This is the default for parser::max_depth(). + */ +constexpr size_t DEFAULT_MAX_DEPTH = 1024; + +SIMDJSON_POP_DISABLE_UNUSED_WARNINGS + +class implementation; +struct padded_string; +class padded_string_view; +enum class stage1_mode; + +namespace internal { + +template +class atomic_ptr; +class dom_parser_implementation; +class escape_json_string; +class tape_ref; +struct value128; +enum class tape_type; + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_BASE_H +/* end file simdjson/base.h */ + +/* skipped duplicate #include "simdjson/error.h" */ +/* including simdjson/error-inl.h: #include "simdjson/error-inl.h" */ +/* begin file simdjson/error-inl.h */ +#ifndef SIMDJSON_ERROR_INL_H +#define SIMDJSON_ERROR_INL_H + +/* skipped duplicate #include "simdjson/error.h" */ + +#include + +namespace simdjson { +namespace internal { + // We store the error code so we can validate the error message is associated with the right code + struct error_code_info { + error_code code; + const char* message; // do not use a fancy std::string where a simple C string will do (no alloc, no destructor) + }; + // These MUST match the codes in error_code. We check this constraint in basictests. + extern SIMDJSON_DLLIMPORTEXPORT const error_code_info error_codes[]; +} // namespace internal + + +inline const char *error_message(error_code error) noexcept { + // If you're using error_code, we're trusting you got it from the enum. + return internal::error_codes[int(error)].message; +} + +// deprecated function +#ifndef SIMDJSON_DISABLE_DEPRECATED_API +inline const std::string error_message(int error) noexcept { + if (error < 0 || error >= error_code::NUM_ERROR_CODES) { + return internal::error_codes[UNEXPECTED_ERROR].message; + } + return internal::error_codes[error].message; +} +#endif // SIMDJSON_DISABLE_DEPRECATED_API + +inline std::ostream& operator<<(std::ostream& out, error_code error) noexcept { + return out << error_message(error); +} + +namespace internal { + +// +// internal::simdjson_result_base inline implementation +// + +template +simdjson_inline void simdjson_result_base::tie(T &value, error_code &error) && noexcept { + error = this->second; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +simdjson_warn_unused simdjson_inline error_code simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; +} + +template +simdjson_inline error_code simdjson_result_base::error() const noexcept { + return this->second; +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& simdjson_result_base::value() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return this->first; +} + +template +simdjson_inline T&& simdjson_result_base::value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline T&& simdjson_result_base::take_value() && noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return std::forward(this->first); +} + +template +simdjson_inline simdjson_result_base::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& simdjson_result_base::value_unsafe() const& noexcept { + return this->first; +} + +template +simdjson_inline T&& simdjson_result_base::value_unsafe() && noexcept { + return std::forward(this->first); +} + +template +simdjson_inline simdjson_result_base::simdjson_result_base(T &&value, error_code error) noexcept + : std::pair(std::forward(value), error) {} +template +simdjson_inline simdjson_result_base::simdjson_result_base(error_code error) noexcept + : simdjson_result_base(T{}, error) {} +template +simdjson_inline simdjson_result_base::simdjson_result_base(T &&value) noexcept + : simdjson_result_base(std::forward(value), SUCCESS) {} +template +simdjson_inline simdjson_result_base::simdjson_result_base() noexcept + : simdjson_result_base(T{}, UNINITIALIZED) {} + +} // namespace internal + +/// +/// simdjson_result inline implementation +/// + +template +simdjson_inline void simdjson_result::tie(T &value, error_code &error) && noexcept { + std::forward>(*this).tie(value, error); +} + +template +simdjson_warn_unused simdjson_inline error_code simdjson_result::get(T &value) && noexcept { + return std::forward>(*this).get(value); +} + +template +simdjson_inline error_code simdjson_result::error() const noexcept { + return internal::simdjson_result_base::error(); +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& simdjson_result::value() & noexcept(false) { + return internal::simdjson_result_base::value(); +} + +template +simdjson_inline T&& simdjson_result::value() && noexcept(false) { + return std::forward>(*this).value(); +} + +template +simdjson_inline T&& simdjson_result::take_value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline simdjson_result::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& simdjson_result::value_unsafe() const& noexcept { + return internal::simdjson_result_base::value_unsafe(); +} + +template +simdjson_inline T&& simdjson_result::value_unsafe() && noexcept { + return std::forward>(*this).value_unsafe(); +} + +template +simdjson_inline simdjson_result::simdjson_result(T &&value, error_code error) noexcept + : internal::simdjson_result_base(std::forward(value), error) {} +template +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : internal::simdjson_result_base(error) {} +template +simdjson_inline simdjson_result::simdjson_result(T &&value) noexcept + : internal::simdjson_result_base(std::forward(value)) {} +template +simdjson_inline simdjson_result::simdjson_result() noexcept + : internal::simdjson_result_base() {} + +} // namespace simdjson + +#endif // SIMDJSON_ERROR_INL_H +/* end file simdjson/error-inl.h */ +/* including simdjson/implementation.h: #include "simdjson/implementation.h" */ +/* begin file simdjson/implementation.h */ +#ifndef SIMDJSON_IMPLEMENTATION_H +#define SIMDJSON_IMPLEMENTATION_H + +/* including simdjson/internal/atomic_ptr.h: #include "simdjson/internal/atomic_ptr.h" */ +/* begin file simdjson/internal/atomic_ptr.h */ +#ifndef SIMDJSON_INTERNAL_ATOMIC_PTR_H +#define SIMDJSON_INTERNAL_ATOMIC_PTR_H + +/* skipped duplicate #include "simdjson/base.h" */ +#include + +namespace simdjson { +namespace internal { + +template +class atomic_ptr { +public: + atomic_ptr(T *_ptr) : ptr{_ptr} {} + + operator const T*() const { return ptr.load(); } + const T& operator*() const { return *ptr; } + const T* operator->() const { return ptr.load(); } + + operator T*() { return ptr.load(); } + T& operator*() { return *ptr; } + T* operator->() { return ptr.load(); } + atomic_ptr& operator=(T *_ptr) { ptr = _ptr; return *this; } + +private: + std::atomic ptr; +}; + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_ATOMIC_PTR_H +/* end file simdjson/internal/atomic_ptr.h */ +/* including simdjson/internal/dom_parser_implementation.h: #include "simdjson/internal/dom_parser_implementation.h" */ +/* begin file simdjson/internal/dom_parser_implementation.h */ +#ifndef SIMDJSON_INTERNAL_DOM_PARSER_IMPLEMENTATION_H +#define SIMDJSON_INTERNAL_DOM_PARSER_IMPLEMENTATION_H + +/* skipped duplicate #include "simdjson/base.h" */ +/* skipped duplicate #include "simdjson/error.h" */ +#include + +namespace simdjson { + +namespace dom { +class document; +} // namespace dom + +/** +* This enum is used with the dom_parser_implementation::stage1 function. +* 1) The regular mode expects a fully formed JSON document. +* 2) The streaming_partial mode expects a possibly truncated +* input within a stream on JSON documents. +* 3) The stream_final mode allows us to truncate final +* unterminated strings. It is useful in conjunction with streaming_partial. +*/ +enum class stage1_mode { regular, streaming_partial, streaming_final}; + +/** + * Returns true if mode == streaming_partial or mode == streaming_final + */ +inline bool is_streaming(stage1_mode mode) { + // performance note: it is probably faster to check that mode is different + // from regular than checking that it is either streaming_partial or streaming_final. + return (mode != stage1_mode::regular); + // return (mode == stage1_mode::streaming_partial || mode == stage1_mode::streaming_final); +} + + +namespace internal { + + +/** + * An implementation of simdjson's DOM parser for a particular CPU architecture. + * + * This class is expected to be accessed only by pointer, and never move in memory (though the + * pointer can move). + */ +class dom_parser_implementation { +public: + + /** + * @private For internal implementation use + * + * Run a full JSON parse on a single document (stage1 + stage2). + * + * Guaranteed only to be called when capacity > document length. + * + * Overridden by each implementation. + * + * @param buf The json document to parse. *MUST* be allocated up to len + SIMDJSON_PADDING bytes. + * @param len The length of the json document. + * @return The error code, or SUCCESS if there was no error. + */ + simdjson_warn_unused virtual error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept = 0; + + /** + * @private For internal implementation use + * + * Stage 1 of the document parser. + * + * Guaranteed only to be called when capacity > document length. + * + * Overridden by each implementation. + * + * @param buf The json document to parse. + * @param len The length of the json document. + * @param streaming Whether this is being called by parser::parse_many. + * @return The error code, or SUCCESS if there was no error. + */ + simdjson_warn_unused virtual error_code stage1(const uint8_t *buf, size_t len, stage1_mode streaming) noexcept = 0; + + /** + * @private For internal implementation use + * + * Stage 2 of the document parser. + * + * Called after stage1(). + * + * Overridden by each implementation. + * + * @param doc The document to output to. + * @return The error code, or SUCCESS if there was no error. + */ + simdjson_warn_unused virtual error_code stage2(dom::document &doc) noexcept = 0; + + /** + * @private For internal implementation use + * + * Stage 2 of the document parser for parser::parse_many. + * + * Guaranteed only to be called after stage1(). + * Overridden by each implementation. + * + * @param doc The document to output to. + * @return The error code, SUCCESS if there was no error, or EMPTY if all documents have been parsed. + */ + simdjson_warn_unused virtual error_code stage2_next(dom::document &doc) noexcept = 0; + + /** + * Unescape a valid UTF-8 string from src to dst, stopping at a final unescaped quote. There + * must be an unescaped quote terminating the string. It returns the final output + * position as pointer. In case of error (e.g., the string has bad escaped codes), + * then null_nullptrptr is returned. It is assumed that the output buffer is large + * enough. E.g., if src points at 'joe"', then dst needs to have four free bytes + + * SIMDJSON_PADDING bytes. + * + * Overridden by each implementation. + * + * @param str pointer to the beginning of a valid UTF-8 JSON string, must end with an unescaped quote. + * @param dst pointer to a destination buffer, it must point a region in memory of sufficient size. + * @param allow_replacement whether we allow a replacement character when the UTF-8 contains unmatched surrogate pairs. + * @return end of the of the written region (exclusive) or nullptr in case of error. + */ + simdjson_warn_unused virtual uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept = 0; + + /** + * Unescape a NON-valid UTF-8 string from src to dst, stopping at a final unescaped quote. There + * must be an unescaped quote terminating the string. It returns the final output + * position as pointer. In case of error (e.g., the string has bad escaped codes), + * then null_nullptrptr is returned. It is assumed that the output buffer is large + * enough. E.g., if src points at 'joe"', then dst needs to have four free bytes + + * SIMDJSON_PADDING bytes. + * + * Overridden by each implementation. + * + * @param str pointer to the beginning of a possibly invalid UTF-8 JSON string, must end with an unescaped quote. + * @param dst pointer to a destination buffer, it must point a region in memory of sufficient size. + * @return end of the of the written region (exclusive) or nullptr in case of error. + */ + simdjson_warn_unused virtual uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept = 0; + + /** + * Change the capacity of this parser. + * + * The capacity can never exceed SIMDJSON_MAXSIZE_BYTES (e.g., 4 GB) + * and an CAPACITY error is returned if it is attempted. + * + * Generally used for reallocation. + * + * @param capacity The new capacity. + * @param max_depth The new max_depth. + * @return The error code, or SUCCESS if there was no error. + */ + virtual error_code set_capacity(size_t capacity) noexcept = 0; + + /** + * Change the max depth of this parser. + * + * Generally used for reallocation. + * + * @param capacity The new capacity. + * @param max_depth The new max_depth. + * @return The error code, or SUCCESS if there was no error. + */ + virtual error_code set_max_depth(size_t max_depth) noexcept = 0; + + /** + * Deallocate this parser. + */ + virtual ~dom_parser_implementation() = default; + + /** Number of structural indices passed from stage 1 to stage 2 */ + uint32_t n_structural_indexes{0}; + /** Structural indices passed from stage 1 to stage 2 */ + std::unique_ptr structural_indexes{}; + /** Next structural index to parse */ + uint32_t next_structural_index{0}; + + /** + * The largest document this parser can support without reallocating. + * + * @return Current capacity, in bytes. + */ + simdjson_inline size_t capacity() const noexcept; + + /** + * The maximum level of nested object and arrays supported by this parser. + * + * @return Maximum depth, in bytes. + */ + simdjson_inline size_t max_depth() const noexcept; + + /** + * Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length + * and `max_depth` depth. + * + * @param capacity The new capacity. + * @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH. + * @return The error, if there is one. + */ + simdjson_warn_unused inline error_code allocate(size_t capacity, size_t max_depth) noexcept; + + +protected: + /** + * The maximum document length this parser supports. + * + * Buffers are large enough to handle any document up to this length. + */ + size_t _capacity{0}; + + /** + * The maximum depth (number of nested objects and arrays) supported by this parser. + * + * Defaults to DEFAULT_MAX_DEPTH. + */ + size_t _max_depth{0}; + + // Declaring these so that subclasses can use them to implement their constructors. + simdjson_inline dom_parser_implementation() noexcept; + simdjson_inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; + simdjson_inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; + + simdjson_inline dom_parser_implementation(const dom_parser_implementation &) noexcept = delete; + simdjson_inline dom_parser_implementation &operator=(const dom_parser_implementation &other) noexcept = delete; +}; // class dom_parser_implementation + +simdjson_inline dom_parser_implementation::dom_parser_implementation() noexcept = default; +simdjson_inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; +simdjson_inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; + +simdjson_inline size_t dom_parser_implementation::capacity() const noexcept { + return _capacity; +} + +simdjson_inline size_t dom_parser_implementation::max_depth() const noexcept { + return _max_depth; +} + +simdjson_warn_unused +inline error_code dom_parser_implementation::allocate(size_t capacity, size_t max_depth) noexcept { + if (this->max_depth() != max_depth) { + error_code err = set_max_depth(max_depth); + if (err) { return err; } + } + if (_capacity != capacity) { + error_code err = set_capacity(capacity); + if (err) { return err; } + } + return SUCCESS; +} + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_DOM_PARSER_IMPLEMENTATION_H +/* end file simdjson/internal/dom_parser_implementation.h */ + +#include + +namespace simdjson { + +/** + * Validate the UTF-8 string. + * + * @param buf the string to validate. + * @param len the length of the string in bytes. + * @return true if the string is valid UTF-8. + */ +simdjson_warn_unused bool validate_utf8(const char * buf, size_t len) noexcept; +/** + * Validate the UTF-8 string. + * + * @param sv the string_view to validate. + * @return true if the string is valid UTF-8. + */ +simdjson_inline simdjson_warn_unused bool validate_utf8(const std::string_view sv) noexcept { + return validate_utf8(sv.data(), sv.size()); +} + +/** + * Validate the UTF-8 string. + * + * @param p the string to validate. + * @return true if the string is valid UTF-8. + */ +simdjson_inline simdjson_warn_unused bool validate_utf8(const std::string& s) noexcept { + return validate_utf8(s.data(), s.size()); +} + +/** + * An implementation of simdjson for a particular CPU architecture. + * + * Also used to maintain the currently active implementation. The active implementation is + * automatically initialized on first use to the most advanced implementation supported by the host. + */ +class implementation { +public: + + /** + * The name of this implementation. + * + * const implementation *impl = simdjson::get_active_implementation(); + * cout << "simdjson is optimized for " << impl->name() << "(" << impl->description() << ")" << endl; + * + * @return the name of the implementation, e.g. "haswell", "westmere", "arm64". + */ + virtual const std::string &name() const { return _name; } + + /** + * The description of this implementation. + * + * const implementation *impl = simdjson::get_active_implementation(); + * cout << "simdjson is optimized for " << impl->name() << "(" << impl->description() << ")" << endl; + * + * @return the description of the implementation, e.g. "Intel/AMD AVX2", "Intel/AMD SSE4.2", "ARM NEON". + */ + virtual const std::string &description() const { return _description; } + + /** + * The instruction sets this implementation is compiled against + * and the current CPU match. This function may poll the current CPU/system + * and should therefore not be called too often if performance is a concern. + * + * @return true if the implementation can be safely used on the current system (determined at runtime). + */ + bool supported_by_runtime_system() const; + + /** + * @private For internal implementation use + * + * The instruction sets this implementation is compiled against. + * + * @return a mask of all required `internal::instruction_set::` values. + */ + virtual uint32_t required_instruction_sets() const { return _required_instruction_sets; } + + /** + * @private For internal implementation use + * + * const implementation *impl = simdjson::get_active_implementation(); + * cout << "simdjson is optimized for " << impl->name() << "(" << impl->description() << ")" << endl; + * + * @param capacity The largest document that will be passed to the parser. + * @param max_depth The maximum JSON object/array nesting this parser is expected to handle. + * @param dst The place to put the resulting parser implementation. + * @return the error code, or SUCCESS if there was no error. + */ + virtual error_code create_dom_parser_implementation( + size_t capacity, + size_t max_depth, + std::unique_ptr &dst + ) const noexcept = 0; + + /** + * @private For internal implementation use + * + * Minify the input string assuming that it represents a JSON string, does not parse or validate. + * + * Overridden by each implementation. + * + * @param buf the json document to minify. + * @param len the length of the json document. + * @param dst the buffer to write the minified document to. *MUST* be allocated up to len + SIMDJSON_PADDING bytes. + * @param dst_len the number of bytes written. Output only. + * @return the error code, or SUCCESS if there was no error. + */ + simdjson_warn_unused virtual error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept = 0; + + + /** + * Validate the UTF-8 string. + * + * Overridden by each implementation. + * + * @param buf the string to validate. + * @param len the length of the string in bytes. + * @return true if and only if the string is valid UTF-8. + */ + simdjson_warn_unused virtual bool validate_utf8(const char *buf, size_t len) const noexcept = 0; + +protected: + /** @private Construct an implementation with the given name and description. For subclasses. */ + simdjson_inline implementation( + std::string_view name, + std::string_view description, + uint32_t required_instruction_sets + ) : + _name(name), + _description(description), + _required_instruction_sets(required_instruction_sets) + { + } + virtual ~implementation()=default; + +private: + /** + * The name of this implementation. + */ + const std::string _name; + + /** + * The description of this implementation. + */ + const std::string _description; + + /** + * Instruction sets required for this implementation. + */ + const uint32_t _required_instruction_sets; +}; + +/** @private */ +namespace internal { + +/** + * The list of available implementations compiled into simdjson. + */ +class available_implementation_list { +public: + /** Get the list of available implementations compiled into simdjson */ + simdjson_inline available_implementation_list() {} + /** Number of implementations */ + size_t size() const noexcept; + /** STL const begin() iterator */ + const implementation * const *begin() const noexcept; + /** STL const end() iterator */ + const implementation * const *end() const noexcept; + + /** + * Get the implementation with the given name. + * + * Case sensitive. + * + * const implementation *impl = simdjson::get_available_implementations()["westmere"]; + * if (!impl) { exit(1); } + * if (!imp->supported_by_runtime_system()) { exit(1); } + * simdjson::get_active_implementation() = impl; + * + * @param name the implementation to find, e.g. "westmere", "haswell", "arm64" + * @return the implementation, or nullptr if the parse failed. + */ + const implementation * operator[](const std::string_view &name) const noexcept { + for (const implementation * impl : *this) { + if (impl->name() == name) { return impl; } + } + return nullptr; + } + + /** + * Detect the most advanced implementation supported by the current host. + * + * This is used to initialize the implementation on startup. + * + * const implementation *impl = simdjson::available_implementation::detect_best_supported(); + * simdjson::get_active_implementation() = impl; + * + * @return the most advanced supported implementation for the current host, or an + * implementation that returns UNSUPPORTED_ARCHITECTURE if there is no supported + * implementation. Will never return nullptr. + */ + const implementation *detect_best_supported() const noexcept; +}; + +} // namespace internal + +/** + * The list of available implementations compiled into simdjson. + */ +extern SIMDJSON_DLLIMPORTEXPORT const internal::available_implementation_list& get_available_implementations(); + +/** + * The active implementation. + * + * Automatically initialized on first use to the most advanced implementation supported by this hardware. + */ +extern SIMDJSON_DLLIMPORTEXPORT internal::atomic_ptr& get_active_implementation(); + +} // namespace simdjson + +#endif // SIMDJSON_IMPLEMENTATION_H +/* end file simdjson/implementation.h */ +/* including simdjson/minify.h: #include "simdjson/minify.h" */ +/* begin file simdjson/minify.h */ +#ifndef SIMDJSON_MINIFY_H +#define SIMDJSON_MINIFY_H + +/* skipped duplicate #include "simdjson/base.h" */ +/* including simdjson/padded_string.h: #include "simdjson/padded_string.h" */ +/* begin file simdjson/padded_string.h */ +#ifndef SIMDJSON_PADDED_STRING_H +#define SIMDJSON_PADDED_STRING_H + +/* skipped duplicate #include "simdjson/base.h" */ +/* skipped duplicate #include "simdjson/error.h" */ + +/* skipped duplicate #include "simdjson/error-inl.h" */ + +#include +#include +#include +#include + +namespace simdjson { + +class padded_string_view; + +/** + * String with extra allocation for ease of use with parser::parse() + * + * This is a move-only class, it cannot be copied. + */ +struct padded_string final { + + /** + * Create a new, empty padded string. + */ + explicit inline padded_string() noexcept; + /** + * Create a new padded string buffer. + * + * @param length the size of the string. + */ + explicit inline padded_string(size_t length) noexcept; + /** + * Create a new padded string by copying the given input. + * + * @param data the buffer to copy + * @param length the number of bytes to copy + */ + explicit inline padded_string(const char *data, size_t length) noexcept; + /** + * Create a new padded string by copying the given input. + * + * @param str_ the string to copy + */ + inline padded_string(const std::string & str_ ) noexcept; + /** + * Create a new padded string by copying the given input. + * + * @param sv_ the string to copy + */ + inline padded_string(std::string_view sv_) noexcept; + /** + * Move one padded string into another. + * + * The original padded string will be reduced to zero capacity. + * + * @param o the string to move. + */ + inline padded_string(padded_string &&o) noexcept; + /** + * Move one padded string into another. + * + * The original padded string will be reduced to zero capacity. + * + * @param o the string to move. + */ + inline padded_string &operator=(padded_string &&o) noexcept; + inline void swap(padded_string &o) noexcept; + ~padded_string() noexcept; + + /** + * The length of the string. + * + * Does not include padding. + */ + size_t size() const noexcept; + + /** + * The length of the string. + * + * Does not include padding. + */ + size_t length() const noexcept; + + /** + * The string data. + **/ + const char *data() const noexcept; + const uint8_t *u8data() const noexcept { return static_cast(static_cast(data_ptr));} + + /** + * The string data. + **/ + char *data() noexcept; + + /** + * Create a std::string_view with the same content. + */ + operator std::string_view() const; + + /** + * Create a padded_string_view with the same content. + */ + operator padded_string_view() const noexcept; + + /** + * Load this padded string from a file. + * + * @return IO_ERROR on error. Be mindful that on some 32-bit systems, + * the file size might be limited to 2 GB. + * + * @param path the path to the file. + **/ + inline static simdjson_result load(std::string_view path) noexcept; + +private: + padded_string &operator=(const padded_string &o) = delete; + padded_string(const padded_string &o) = delete; + + size_t viable_size{0}; + char *data_ptr{nullptr}; + +}; // padded_string + +/** + * Send padded_string instance to an output stream. + * + * @param out The output stream. + * @param s The padded_string instance. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, const padded_string& s) { return out << s.data(); } + +#if SIMDJSON_EXCEPTIONS +/** + * Send padded_string instance to an output stream. + * + * @param out The output stream. + * @param s The padded_string instance. + * @throw simdjson_error if the result being printed has an error. If there is an error with the + * underlying output stream, that error will be propagated (simdjson_error will not be + * thrown). + */ +inline std::ostream& operator<<(std::ostream& out, simdjson_result &s) noexcept(false) { return out << s.value(); } +#endif + +} // namespace simdjson + +// This is deliberately outside of simdjson so that people get it without having to use the namespace +inline simdjson::padded_string operator "" _padded(const char *str, size_t len); + +namespace simdjson { +namespace internal { + +// The allocate_padded_buffer function is a low-level function to allocate memory +// with padding so we can read past the "length" bytes safely. It is used by +// the padded_string class automatically. It returns nullptr in case +// of error: the caller should check for a null pointer. +// The length parameter is the maximum size in bytes of the string. +// The caller is responsible to free the memory (e.g., delete[] (...)). +inline char *allocate_padded_buffer(size_t length) noexcept; + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_PADDED_STRING_H +/* end file simdjson/padded_string.h */ +#include +#include +#include + +namespace simdjson { + +/** + * + * Minify the input string assuming that it represents a JSON string, does not parse or validate. + * This function is much faster than parsing a JSON string and then writing a minified version of it. + * However, it does not validate the input. It will merely return an error in simple cases (e.g., if + * there is a string that was never terminated). + * + * + * @param buf the json document to minify. + * @param len the length of the json document. + * @param dst the buffer to write the minified document to. *MUST* be allocated up to len bytes. + * @param dst_len the number of bytes written. Output only. + * @return the error code, or SUCCESS if there was no error. + */ +simdjson_warn_unused error_code minify(const char *buf, size_t len, char *dst, size_t &dst_len) noexcept; + +} // namespace simdjson + +#endif // SIMDJSON_MINIFY_H +/* end file simdjson/minify.h */ +/* skipped duplicate #include "simdjson/padded_string.h" */ +/* including simdjson/padded_string-inl.h: #include "simdjson/padded_string-inl.h" */ +/* begin file simdjson/padded_string-inl.h */ +#ifndef SIMDJSON_PADDED_STRING_INL_H +#define SIMDJSON_PADDED_STRING_INL_H + +/* skipped duplicate #include "simdjson/padded_string.h" */ +/* including simdjson/padded_string_view.h: #include "simdjson/padded_string_view.h" */ +/* begin file simdjson/padded_string_view.h */ +#ifndef SIMDJSON_PADDED_STRING_VIEW_H +#define SIMDJSON_PADDED_STRING_VIEW_H + +/* skipped duplicate #include "simdjson/portability.h" */ +/* skipped duplicate #include "simdjson/base.h" // for SIMDJSON_PADDING */ +/* skipped duplicate #include "simdjson/error.h" */ + +#include +#include +#include +#include + +namespace simdjson { + +/** + * User-provided string that promises it has extra padded bytes at the end for use with parser::parse(). + */ +class padded_string_view : public std::string_view { +private: + size_t _capacity; + +public: + /** Create an empty padded_string_view. */ + inline padded_string_view() noexcept = default; + + /** + * Promise the given buffer has at least SIMDJSON_PADDING extra bytes allocated to it. + * + * @param s The string. + * @param len The length of the string (not including padding). + * @param capacity The allocated length of the string, including padding. + */ + explicit inline padded_string_view(const char* s, size_t len, size_t capacity) noexcept; + /** overload explicit inline padded_string_view(const char* s, size_t len) noexcept */ + explicit inline padded_string_view(const uint8_t* s, size_t len, size_t capacity) noexcept; + + /** + * Promise the given string has at least SIMDJSON_PADDING extra bytes allocated to it. + * + * The capacity of the string will be used to determine its padding. + * + * @param s The string. + */ + explicit inline padded_string_view(const std::string &s) noexcept; + + /** + * Promise the given string_view has at least SIMDJSON_PADDING extra bytes allocated to it. + * + * @param s The string. + * @param capacity The allocated length of the string, including padding. + */ + explicit inline padded_string_view(std::string_view s, size_t capacity) noexcept; + + /** The number of allocated bytes. */ + inline size_t capacity() const noexcept; + + /** + * Remove the UTF-8 Byte Order Mark (BOM) if it exists. + * + * @return whether a BOM was found and removed + */ + inline bool remove_utf8_bom() noexcept; + + /** The amount of padding on the string (capacity() - length()) */ + inline size_t padding() const noexcept; + +}; // padded_string_view + +#if SIMDJSON_EXCEPTIONS +/** + * Send padded_string instance to an output stream. + * + * @param out The output stream. + * @param s The padded_string_view. + * @throw simdjson_error if the result being printed has an error. If there is an error with the + * underlying output stream, that error will be propagated (simdjson_error will not be + * thrown). + */ +inline std::ostream& operator<<(std::ostream& out, simdjson_result &s) noexcept(false); +#endif + +} // namespace simdjson + +#endif // SIMDJSON_PADDED_STRING_VIEW_H +/* end file simdjson/padded_string_view.h */ + +/* skipped duplicate #include "simdjson/error-inl.h" */ +/* including simdjson/padded_string_view-inl.h: #include "simdjson/padded_string_view-inl.h" */ +/* begin file simdjson/padded_string_view-inl.h */ +#ifndef SIMDJSON_PADDED_STRING_VIEW_INL_H +#define SIMDJSON_PADDED_STRING_VIEW_INL_H + +/* skipped duplicate #include "simdjson/padded_string_view.h" */ +/* skipped duplicate #include "simdjson/error-inl.h" */ + +#include /* memcmp */ + +namespace simdjson { + +inline padded_string_view::padded_string_view(const char* s, size_t len, size_t capacity) noexcept + : std::string_view(s, len), _capacity(capacity) +{ +} + +inline padded_string_view::padded_string_view(const uint8_t* s, size_t len, size_t capacity) noexcept + : padded_string_view(reinterpret_cast(s), len, capacity) +{ +} + +inline padded_string_view::padded_string_view(const std::string &s) noexcept + : std::string_view(s), _capacity(s.capacity()) +{ +} + +inline padded_string_view::padded_string_view(std::string_view s, size_t capacity) noexcept + : std::string_view(s), _capacity(capacity) +{ +} + +inline size_t padded_string_view::capacity() const noexcept { return _capacity; } + +inline size_t padded_string_view::padding() const noexcept { return capacity() - length(); } + +inline bool padded_string_view::remove_utf8_bom() noexcept { + if(length() < 3) { return false; } + if (std::memcmp(data(), "\xEF\xBB\xBF", 3) == 0) { + remove_prefix(3); + _capacity -= 3; + return true; + } + return false; +} + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson_result &s) noexcept(false) { return out << s.value(); } +#endif + +} // namespace simdjson + + +#endif // SIMDJSON_PADDED_STRING_VIEW_INL_H +/* end file simdjson/padded_string_view-inl.h */ + +#include + +namespace simdjson { +namespace internal { + +// The allocate_padded_buffer function is a low-level function to allocate memory +// with padding so we can read past the "length" bytes safely. It is used by +// the padded_string class automatically. It returns nullptr in case +// of error: the caller should check for a null pointer. +// The length parameter is the maximum size in bytes of the string. +// The caller is responsible to free the memory (e.g., delete[] (...)). +inline char *allocate_padded_buffer(size_t length) noexcept { + const size_t totalpaddedlength = length + SIMDJSON_PADDING; + if(totalpaddedlength(1UL<<20)) { + return nullptr; + } +#endif + + char *padded_buffer = new (std::nothrow) char[totalpaddedlength]; + if (padded_buffer == nullptr) { + return nullptr; + } + // We write nulls in the padded region to avoid having uninitialized + // content which may trigger warning for some sanitizers + std::memset(padded_buffer + length, 0, totalpaddedlength - length); + return padded_buffer; +} // allocate_padded_buffer() + +} // namespace internal + + +inline padded_string::padded_string() noexcept = default; +inline padded_string::padded_string(size_t length) noexcept + : viable_size(length), data_ptr(internal::allocate_padded_buffer(length)) { +} +inline padded_string::padded_string(const char *data, size_t length) noexcept + : viable_size(length), data_ptr(internal::allocate_padded_buffer(length)) { + if ((data != nullptr) && (data_ptr != nullptr)) { + std::memcpy(data_ptr, data, length); + } +} +// note: do not pass std::string arguments by value +inline padded_string::padded_string(const std::string & str_ ) noexcept + : viable_size(str_.size()), data_ptr(internal::allocate_padded_buffer(str_.size())) { + if (data_ptr != nullptr) { + std::memcpy(data_ptr, str_.data(), str_.size()); + } +} +// note: do pass std::string_view arguments by value +inline padded_string::padded_string(std::string_view sv_) noexcept + : viable_size(sv_.size()), data_ptr(internal::allocate_padded_buffer(sv_.size())) { + if(simdjson_unlikely(!data_ptr)) { + //allocation failed or zero size + viable_size = 0; + return; + } + if (sv_.size()) { + std::memcpy(data_ptr, sv_.data(), sv_.size()); + } +} +inline padded_string::padded_string(padded_string &&o) noexcept + : viable_size(o.viable_size), data_ptr(o.data_ptr) { + o.data_ptr = nullptr; // we take ownership +} + +inline padded_string &padded_string::operator=(padded_string &&o) noexcept { + delete[] data_ptr; + data_ptr = o.data_ptr; + viable_size = o.viable_size; + o.data_ptr = nullptr; // we take ownership + o.viable_size = 0; + return *this; +} + +inline void padded_string::swap(padded_string &o) noexcept { + size_t tmp_viable_size = viable_size; + char *tmp_data_ptr = data_ptr; + viable_size = o.viable_size; + data_ptr = o.data_ptr; + o.data_ptr = tmp_data_ptr; + o.viable_size = tmp_viable_size; +} + +inline padded_string::~padded_string() noexcept { + delete[] data_ptr; +} + +inline size_t padded_string::size() const noexcept { return viable_size; } + +inline size_t padded_string::length() const noexcept { return viable_size; } + +inline const char *padded_string::data() const noexcept { return data_ptr; } + +inline char *padded_string::data() noexcept { return data_ptr; } + +inline padded_string::operator std::string_view() const { return std::string_view(data(), length()); } + +inline padded_string::operator padded_string_view() const noexcept { + return padded_string_view(data(), length(), length() + SIMDJSON_PADDING); +} + +inline simdjson_result padded_string::load(std::string_view filename) noexcept { + // Open the file + SIMDJSON_PUSH_DISABLE_WARNINGS + SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe + std::FILE *fp = std::fopen(filename.data(), "rb"); + SIMDJSON_POP_DISABLE_WARNINGS + + if (fp == nullptr) { + return IO_ERROR; + } + + // Get the file size + int ret; +#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS + ret = _fseeki64(fp, 0, SEEK_END); +#else + ret = std::fseek(fp, 0, SEEK_END); +#endif // _WIN64 + if(ret < 0) { + std::fclose(fp); + return IO_ERROR; + } +#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS + __int64 llen = _ftelli64(fp); + if(llen == -1L) { + std::fclose(fp); + return IO_ERROR; + } +#else + long llen = std::ftell(fp); + if((llen < 0) || (llen == LONG_MAX)) { + std::fclose(fp); + return IO_ERROR; + } +#endif + + // Allocate the padded_string + size_t len = static_cast(llen); + padded_string s(len); + if (s.data() == nullptr) { + std::fclose(fp); + return MEMALLOC; + } + + // Read the padded_string + std::rewind(fp); + size_t bytes_read = std::fread(s.data(), 1, len, fp); + if (std::fclose(fp) != 0 || bytes_read != len) { + return IO_ERROR; + } + + return s; +} + +} // namespace simdjson + +inline simdjson::padded_string operator "" _padded(const char *str, size_t len) { + return simdjson::padded_string(str, len); +} + +#endif // SIMDJSON_PADDED_STRING_INL_H +/* end file simdjson/padded_string-inl.h */ +/* skipped duplicate #include "simdjson/padded_string_view.h" */ +/* skipped duplicate #include "simdjson/padded_string_view-inl.h" */ + +/* including simdjson/dom.h: #include "simdjson/dom.h" */ +/* begin file simdjson/dom.h */ +#ifndef SIMDJSON_DOM_H +#define SIMDJSON_DOM_H + +/* including simdjson/dom/base.h: #include "simdjson/dom/base.h" */ +/* begin file simdjson/dom/base.h */ +#ifndef SIMDJSON_DOM_BASE_H +#define SIMDJSON_DOM_BASE_H + +/* skipped duplicate #include "simdjson/base.h" */ + +namespace simdjson { + +/** + * @brief A DOM API on top of the simdjson parser. + */ +namespace dom { + +/** The default batch size for parser.parse_many() and parser.load_many() */ +static constexpr size_t DEFAULT_BATCH_SIZE = 1000000; +/** + * Some adversary might try to set the batch size to 0 or 1, which might cause problems. + * We set a minimum of 32B since anything else is highly likely to be an error. In practice, + * most users will want a much larger batch size. + * + * All non-negative MINIMAL_BATCH_SIZE values should be 'safe' except that, obviously, no JSON + * document can ever span 0 or 1 byte and that very large values would create memory allocation issues. + */ +static constexpr size_t MINIMAL_BATCH_SIZE = 32; + +/** + * It is wasteful to allocate memory for tiny documents (e.g., 4 bytes). + */ +static constexpr size_t MINIMAL_DOCUMENT_CAPACITY = 32; + +class array; +class document; +class document_stream; +class element; +class key_value_pair; +class object; +class parser; + +#ifdef SIMDJSON_THREADS_ENABLED +struct stage1_worker; +#endif // SIMDJSON_THREADS_ENABLED + +} // namespace dom + +namespace internal { + +template +class string_builder; +class tape_ref; + +} // namespace internal + +} // namespace simdjson + +#endif // SIMDJSON_DOM_BASE_H +/* end file simdjson/dom/base.h */ +/* including simdjson/dom/array.h: #include "simdjson/dom/array.h" */ +/* begin file simdjson/dom/array.h */ +#ifndef SIMDJSON_DOM_ARRAY_H +#define SIMDJSON_DOM_ARRAY_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* including simdjson/internal/tape_ref.h: #include "simdjson/internal/tape_ref.h" */ +/* begin file simdjson/internal/tape_ref.h */ +#ifndef SIMDJSON_INTERNAL_TAPE_REF_H +#define SIMDJSON_INTERNAL_TAPE_REF_H + +/* skipped duplicate #include "simdjson/base.h" */ + +namespace simdjson { +namespace dom { +class document; +} // namespace dom + +namespace internal { + +/** + * A reference to an element on the tape. Internal only. + */ +class tape_ref { +public: + simdjson_inline tape_ref() noexcept; + simdjson_inline tape_ref(const dom::document *doc, size_t json_index) noexcept; + inline size_t after_element() const noexcept; + simdjson_inline tape_type tape_ref_type() const noexcept; + simdjson_inline uint64_t tape_value() const noexcept; + simdjson_inline bool is_double() const noexcept; + simdjson_inline bool is_int64() const noexcept; + simdjson_inline bool is_uint64() const noexcept; + simdjson_inline bool is_false() const noexcept; + simdjson_inline bool is_true() const noexcept; + simdjson_inline bool is_null_on_tape() const noexcept;// different name to avoid clash with is_null. + simdjson_inline uint32_t matching_brace_index() const noexcept; + simdjson_inline uint32_t scope_count() const noexcept; + template + simdjson_inline T next_tape_value() const noexcept; + simdjson_inline uint32_t get_string_length() const noexcept; + simdjson_inline const char * get_c_str() const noexcept; + inline std::string_view get_string_view() const noexcept; + simdjson_inline bool is_document_root() const noexcept; + simdjson_inline bool usable() const noexcept; + + /** The document this element references. */ + const dom::document *doc; + + /** The index of this element on `doc.tape[]` */ + size_t json_index; +}; + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_TAPE_REF_H +/* end file simdjson/internal/tape_ref.h */ + +namespace simdjson { +namespace dom { + +/** + * JSON array. + */ +class array { +public: + /** Create a new, invalid array */ + simdjson_inline array() noexcept; + + class iterator { + public: + using value_type = element; + using difference_type = std::ptrdiff_t; + + /** + * Get the actual value + */ + inline value_type operator*() const noexcept; + /** + * Get the next value. + * + * Part of the std::iterator interface. + */ + inline iterator& operator++() noexcept; + /** + * Get the next value. + * + * Part of the std::iterator interface. + */ + inline iterator operator++(int) noexcept; + /** + * Check if these values come from the same place in the JSON. + * + * Part of the std::iterator interface. + */ + inline bool operator!=(const iterator& other) const noexcept; + inline bool operator==(const iterator& other) const noexcept; + + inline bool operator<(const iterator& other) const noexcept; + inline bool operator<=(const iterator& other) const noexcept; + inline bool operator>=(const iterator& other) const noexcept; + inline bool operator>(const iterator& other) const noexcept; + + iterator() noexcept = default; + iterator(const iterator&) noexcept = default; + iterator& operator=(const iterator&) noexcept = default; + private: + simdjson_inline iterator(const internal::tape_ref &tape) noexcept; + internal::tape_ref tape; + friend class array; + }; + + /** + * Return the first array element. + * + * Part of the std::iterable interface. + */ + inline iterator begin() const noexcept; + /** + * One past the last array element. + * + * Part of the std::iterable interface. + */ + inline iterator end() const noexcept; + /** + * Get the size of the array (number of immediate children). + * It is a saturated value with a maximum of 0xFFFFFF: if the value + * is 0xFFFFFF then the size is 0xFFFFFF or greater. + */ + inline size_t size() const noexcept; + /** + * Get the total number of slots used by this array on the tape. + * + * Note that this is not the same thing as `size()`, which reports the + * number of actual elements within an array (not counting its children). + * + * Since an element can use 1 or 2 slots on the tape, you can only use this + * to figure out the total size of an array (including its children, + * recursively) if you know its structure ahead of time. + **/ + inline size_t number_of_slots() const noexcept; + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard, interpreting the current node + * as the root of its own JSON document. + * + * dom::parser parser; + * array a = parser.parse(R"([ { "foo": { "a": [ 10, 20, 30 ] }} ])"_padded); + * a.at_pointer("/0/foo/a/1") == 20 + * a.at_pointer("0")["foo"]["a"].at(1) == 20 + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(std::string_view json_pointer) const noexcept; + + /** + * Get the value at the given index. This function has linear-time complexity and + * is equivalent to the following: + * + * size_t i=0; + * for (auto element : *this) { + * if (i == index) { return element; } + * i++; + * } + * return INDEX_OUT_OF_BOUNDS; + * + * Avoid calling the at() function repeatedly. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + inline simdjson_result at(size_t index) const noexcept; + +private: + simdjson_inline array(const internal::tape_ref &tape) noexcept; + internal::tape_ref tape; + friend class element; + friend struct simdjson_result; + template + friend class simdjson::internal::string_builder; +}; + + +} // namespace dom + +/** The result of a JSON conversion that may fail. */ +template<> +struct simdjson_result : public internal::simdjson_result_base { +public: + simdjson_inline simdjson_result() noexcept; ///< @private + simdjson_inline simdjson_result(dom::array value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + + inline simdjson_result at_pointer(std::string_view json_pointer) const noexcept; + inline simdjson_result 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); + inline size_t size() const noexcept(false); +#endif // SIMDJSON_EXCEPTIONS +}; + + + +} // namespace simdjson + +#if defined(__cpp_lib_ranges) +#include + +namespace std { +namespace ranges { +template<> +inline constexpr bool enable_view = true; +#if SIMDJSON_EXCEPTIONS +template<> +inline constexpr bool enable_view> = true; +#endif // SIMDJSON_EXCEPTIONS +} // namespace ranges +} // namespace std +#endif // defined(__cpp_lib_ranges) + +#endif // SIMDJSON_DOM_ARRAY_H +/* end file simdjson/dom/array.h */ +/* including simdjson/dom/document_stream.h: #include "simdjson/dom/document_stream.h" */ +/* begin file simdjson/dom/document_stream.h */ +#ifndef SIMDJSON_DOCUMENT_STREAM_H +#define SIMDJSON_DOCUMENT_STREAM_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* including simdjson/dom/parser.h: #include "simdjson/dom/parser.h" */ +/* begin file simdjson/dom/parser.h */ +#ifndef SIMDJSON_DOM_PARSER_H +#define SIMDJSON_DOM_PARSER_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* including simdjson/dom/document.h: #include "simdjson/dom/document.h" */ +/* begin file simdjson/dom/document.h */ +#ifndef SIMDJSON_DOM_DOCUMENT_H +#define SIMDJSON_DOM_DOCUMENT_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ + +#include + +namespace simdjson { +namespace dom { + +/** + * A parsed JSON document. + * + * This class cannot be copied, only moved, to avoid unintended allocations. + */ +class document { +public: + /** + * Create a document container with zero capacity. + * + * The parser will allocate capacity as needed. + */ + document() noexcept = default; + ~document() noexcept = default; + + /** + * Take another document's buffers. + * + * @param other The document to take. Its capacity is zeroed and it is invalidated. + */ + document(document &&other) noexcept = default; + /** @private */ + document(const document &) = delete; // Disallow copying + /** + * Take another document's buffers. + * + * @param other The document to take. Its capacity is zeroed. + */ + document &operator=(document &&other) noexcept = default; + /** @private */ + document &operator=(const document &) = delete; // Disallow copying + + /** + * Get the root element of this document as a JSON array. + */ + element root() const noexcept; + + /** + * @private Dump the raw tape for debugging. + * + * @param os the stream to output to. + * @return false if the tape is likely wrong (e.g., you did not parse a valid JSON). + */ + bool dump_raw_tape(std::ostream &os) const noexcept; + + /** @private Structural values. */ + std::unique_ptr tape{}; + + /** @private String values. + * + * Should be at least byte_capacity. + */ + std::unique_ptr string_buf{}; + /** @private Allocate memory to support + * input JSON documents of up to len bytes. + * + * When calling this function, you lose + * all the data. + * + * The memory allocation is strict: you + * can you use this function to increase + * or lower the amount of allocated memory. + * Passsing zero clears the memory. + */ + error_code allocate(size_t len) noexcept; + /** @private Capacity in bytes, in terms + * of how many bytes of input JSON we can + * support. + */ + size_t capacity() const noexcept; + + +private: + size_t allocated_capacity{0}; + friend class parser; +}; // class document + +} // namespace dom +} // namespace simdjson + +#endif // SIMDJSON_DOM_DOCUMENT_H +/* end file simdjson/dom/document.h */ + +namespace simdjson { + +namespace dom { + +/** + * A persistent document parser. + * + * The parser is designed to be reused, holding the internal buffers necessary to do parsing, + * as well as memory for a single document. The parsed document is overwritten on each parse. + * + * This class cannot be copied, only moved, to avoid unintended allocations. + * + * @note Moving a parser instance may invalidate "dom::element" instances. If you need to + * preserve both the "dom::element" instances and the parser, consider wrapping the parser + * instance in a std::unique_ptr instance: + * + * std::unique_ptr parser(new dom::parser{}); + * auto error = parser->load(f).get(root); + * + * You can then move std::unique_ptr safely. + * + * @note This is not thread safe: one parser cannot produce two documents at the same time! + */ +class parser { +public: + /** + * Create a JSON parser. + * + * The new parser will have zero capacity. + * + * @param max_capacity The maximum document length the parser can automatically handle. The parser + * will allocate more capacity on an as needed basis (when it sees documents too big to handle) + * up to this amount. The parser still starts with zero capacity no matter what this number is: + * to allocate an initial capacity, call allocate() after constructing the parser. + * Defaults to SIMDJSON_MAXSIZE_BYTES (the largest single document simdjson can process). + */ + simdjson_inline explicit parser(size_t max_capacity = SIMDJSON_MAXSIZE_BYTES) noexcept; + /** + * Take another parser's buffers and state. + * + * @param other The parser to take. Its capacity is zeroed. + */ + simdjson_inline parser(parser &&other) noexcept; + parser(const parser &) = delete; ///< @private Disallow copying + /** + * Take another parser's buffers and state. + * + * @param other The parser to take. Its capacity is zeroed. + */ + simdjson_inline parser &operator=(parser &&other) noexcept; + parser &operator=(const parser &) = delete; ///< @private Disallow copying + + /** Deallocate the JSON parser. */ + ~parser()=default; + + /** + * Load a JSON document from a file and return a reference to it. + * + * dom::parser parser; + * const element doc = parser.load("jsonexamples/twitter.json"); + * + * The function is eager: the file's content is loaded in memory inside the parser instance + * and immediately parsed. The file can be deleted after the `parser.load` call. + * + * ### IMPORTANT: Document Lifetime + * + * The JSON document still lives in the parser: this is the most efficient way to parse JSON + * documents because it reuses the same buffers, but you *must* use the document before you + * destroy the parser or call parse() again. + * + * Moving the parser instance is safe, but it invalidates the element instances. You may store + * the parser instance without moving it by wrapping it inside an `unique_ptr` instance like + * so: `std::unique_ptr parser(new dom::parser{});`. + * + * ### Parser Capacity + * + * If the parser's current capacity is less than the file length, it will allocate enough capacity + * to handle it (up to max_capacity). + * + * @param path The path to load. + * @return The document, or an error: + * - IO_ERROR if there was an error opening or reading the file. + * Be mindful that on some 32-bit systems, + * the file size might be limited to 2 GB. + * - MEMALLOC if the parser does not have enough capacity and memory allocation fails. + * - CAPACITY if the parser does not have enough capacity and len > max_capacity. + * - other json errors if parsing fails. You should not rely on these errors to always the same for the + * same document: they may vary under runtime dispatch (so they may vary depending on your system and hardware). + */ + inline simdjson_result load(const std::string &path) & noexcept; + inline simdjson_result load(const std::string &path) && = delete ; + /** + * Parse a JSON document and return a temporary reference to it. + * + * dom::parser parser; + * element doc_root = parser.parse(buf, len); + * + * The function eagerly parses the input: the input can be modified and discarded after + * the `parser.parse(buf, len)` call has completed. + * + * ### IMPORTANT: Document Lifetime + * + * The JSON document still lives in the parser: this is the most efficient way to parse JSON + * documents because it reuses the same buffers, but you *must* use the document before you + * destroy the parser or call parse() again. + * + * Moving the parser instance is safe, but it invalidates the element instances. You may store + * the parser instance without moving it by wrapping it inside an `unique_ptr` instance like + * so: `std::unique_ptr parser(new dom::parser{});`. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * If realloc_if_needed is true (the default), it is assumed that the buffer does *not* have enough padding, + * and it is copied into an enlarged temporary buffer before parsing. Thus the following is safe: + * + * const char *json = R"({"key":"value"})"; + * const size_t json_len = std::strlen(json); + * simdjson::dom::parser parser; + * simdjson::dom::element element = parser.parse(json, json_len); + * + * If you set realloc_if_needed to false (e.g., parser.parse(json, json_len, false)), + * you must provide a buffer with at least SIMDJSON_PADDING extra bytes at the end. + * The benefit of setting realloc_if_needed to false is that you avoid a temporary + * memory allocation and a copy. + * + * The padded bytes may be read. It is not important how you initialize + * these bytes though we recommend a sensible default like null character values or spaces. + * For example, the following low-level code is safe: + * + * const char *json = R"({"key":"value"})"; + * const size_t json_len = std::strlen(json); + * std::unique_ptr padded_json_copy{new char[json_len + SIMDJSON_PADDING]}; + * std::memcpy(padded_json_copy.get(), json, json_len); + * std::memset(padded_json_copy.get() + json_len, '\0', SIMDJSON_PADDING); + * simdjson::dom::parser parser; + * simdjson::dom::element element = parser.parse(padded_json_copy.get(), json_len, false); + * + * ### Parser Capacity + * + * If the parser's current capacity is less than len, it will allocate enough capacity + * to handle it (up to max_capacity). + * + * @param buf The JSON to parse. Must have at least len + SIMDJSON_PADDING allocated bytes, unless + * realloc_if_needed is true. + * @param len The length of the JSON. + * @param realloc_if_needed Whether to reallocate and enlarge the JSON buffer to add padding. + * @return An element pointing at the root of the document, or an error: + * - MEMALLOC if realloc_if_needed is true or the parser does not have enough capacity, + * and memory allocation fails. + * - CAPACITY if the parser does not have enough capacity and len > max_capacity. + * - other json errors if parsing fails. You should not rely on these errors to always the same for the + * same document: they may vary under runtime dispatch (so they may vary depending on your system and hardware). + */ + inline simdjson_result parse(const uint8_t *buf, size_t len, bool realloc_if_needed = true) & noexcept; + inline simdjson_result parse(const uint8_t *buf, size_t len, bool realloc_if_needed = true) && =delete; + /** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */ + simdjson_inline simdjson_result parse(const char *buf, size_t len, bool realloc_if_needed = true) & noexcept; + simdjson_inline simdjson_result parse(const char *buf, size_t len, bool realloc_if_needed = true) && =delete; + /** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */ + simdjson_inline simdjson_result parse(const std::string &s) & noexcept; + simdjson_inline simdjson_result parse(const std::string &s) && =delete; + /** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */ + simdjson_inline simdjson_result parse(const padded_string &s) & noexcept; + simdjson_inline simdjson_result parse(const padded_string &s) && =delete; + /** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */ + simdjson_inline simdjson_result parse(const padded_string_view &v) & noexcept; + simdjson_inline simdjson_result parse(const padded_string_view &v) && =delete; + + /** @private We do not want to allow implicit conversion from C string to std::string. */ + simdjson_inline simdjson_result parse(const char *buf) noexcept = delete; + + /** + * Parse a JSON document into a provide document instance and return a temporary reference to it. + * It is similar to the function `parse` except that instead of parsing into the internal + * `document` instance associated with the parser, it allows the user to provide a document + * instance. + * + * dom::parser parser; + * dom::document doc; + * element doc_root = parser.parse_into_document(doc, buf, len); + * + * The function eagerly parses the input: the input can be modified and discarded after + * the `parser.parse(buf, len)` call has completed. + * + * ### IMPORTANT: Document Lifetime + * + * After the call to parse_into_document, the parser is no longer needed. + * + * The JSON document lives in the document instance: you must keep the document + * instance alive while you navigate through it (i.e., used the returned value from + * parse_into_document). You are encourage to reuse the document instance + * many times with new data to avoid reallocations: + * + * dom::document doc; + * element doc_root1 = parser.parse_into_document(doc, buf1, len); + * //... doc_root1 is a pointer inside doc + * element doc_root2 = parser.parse_into_document(doc, buf1, len); + * //... doc_root2 is a pointer inside doc + * // at this point doc_root1 is no longer safe + * + * Moving the document instance is safe, but it invalidates the element instances. After + * moving a document, you can recover safe access to the document root with its `root()` method. + * + * @param doc The document instance where the parsed data will be stored (on success). + * @param buf The JSON to parse. Must have at least len + SIMDJSON_PADDING allocated bytes, unless + * realloc_if_needed is true. + * @param len The length of the JSON. + * @param realloc_if_needed Whether to reallocate and enlarge the JSON buffer to add padding. + * @return An element pointing at the root of document, or an error: + * - MEMALLOC if realloc_if_needed is true or the parser does not have enough capacity, + * and memory allocation fails. + * - CAPACITY if the parser does not have enough capacity and len > max_capacity. + * - other json errors if parsing fails. You should not rely on these errors to always the same for the + * same document: they may vary under runtime dispatch (so they may vary depending on your system and hardware). + */ + inline simdjson_result parse_into_document(document& doc, const uint8_t *buf, size_t len, bool realloc_if_needed = true) & noexcept; + inline simdjson_result parse_into_document(document& doc, const uint8_t *buf, size_t len, bool realloc_if_needed = true) && =delete; + /** @overload parse_into_document(const uint8_t *buf, size_t len, bool realloc_if_needed) */ + simdjson_inline simdjson_result parse_into_document(document& doc, const char *buf, size_t len, bool realloc_if_needed = true) & noexcept; + simdjson_inline simdjson_result parse_into_document(document& doc, const char *buf, size_t len, bool realloc_if_needed = true) && =delete; + /** @overload parse_into_document(const uint8_t *buf, size_t len, bool realloc_if_needed) */ + simdjson_inline simdjson_result parse_into_document(document& doc, const std::string &s) & noexcept; + simdjson_inline simdjson_result parse_into_document(document& doc, const std::string &s) && =delete; + /** @overload parse_into_document(const uint8_t *buf, size_t len, bool realloc_if_needed) */ + simdjson_inline simdjson_result parse_into_document(document& doc, const padded_string &s) & noexcept; + simdjson_inline simdjson_result parse_into_document(document& doc, const padded_string &s) && =delete; + + /** @private We do not want to allow implicit conversion from C string to std::string. */ + simdjson_inline simdjson_result parse_into_document(document& doc, const char *buf) noexcept = delete; + + /** + * Load a file containing many JSON documents. + * + * dom::parser parser; + * for (const element doc : parser.load_many(path)) { + * cout << std::string(doc["title"]) << endl; + * } + * + * The file is loaded in memory and can be safely deleted after the `parser.load_many(path)` + * function has returned. The memory is held by the `parser` instance. + * + * The function is lazy: it may be that no more than one JSON document at a time is parsed. + * And, possibly, no document many have been parsed when the `parser.load_many(path)` function + * returned. + * + * If there is a UTF-8 BOM, the parser skips it. + * + * ### Format + * + * The file must contain a series of one or more JSON documents, concatenated into a single + * buffer, separated by whitespace. It effectively parses until it has a fully valid document, + * then starts parsing the next document at that point. (It does this with more parallelism and + * lookahead than you might think, though.) + * + * Documents that consist of an object or array may omit the whitespace between them, concatenating + * with no separator. documents that consist of a single primitive (i.e. documents that are not + * arrays or objects) MUST be separated with whitespace. + * + * The documents must not exceed batch_size bytes (by default 1MB) or they will fail to parse. + * Setting batch_size to excessively large or excesively small values may impact negatively the + * performance. + * + * ### Error Handling + * + * All errors are returned during iteration: if there is a global error such as memory allocation, + * it will be yielded as the first result. Iteration always stops after the first error. + * + * 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: + * + * dom::parser parser; + * dom::document_stream docs; + * auto error = parser.load_many(path).get(docs); + * if (error) { cerr << error << endl; exit(1); } + * for (auto doc : docs) { + * std::string_view title; + * if ((error = doc["title"].get(title)) { cerr << error << endl; exit(1); } + * cout << title << endl; + * } + * + * ### Threads + * + * When compiled with SIMDJSON_THREADS_ENABLED, this method will use a single thread under the + * hood to do some lookahead. + * + * ### Parser Capacity + * + * If the parser's current capacity is less than batch_size, it will allocate enough capacity + * to handle it (up to max_capacity). + * + * @param path File name pointing at the concatenated JSON to parse. + * @param batch_size The batch size to use. MUST be larger than the largest document. The sweet + * spot is cache-related: small enough to fit in cache, yet big enough to + * parse as many documents as possible in one tight loop. + * Defaults to 1MB (as simdjson::dom::DEFAULT_BATCH_SIZE), which has been a reasonable sweet + * spot in our tests. + * If you set the batch_size to a value smaller than simdjson::dom::MINIMAL_BATCH_SIZE + * (currently 32B), it will be replaced by simdjson::dom::MINIMAL_BATCH_SIZE. + * @return The stream, or an error. An empty input will yield 0 documents rather than an EMPTY error. Errors: + * - IO_ERROR if there was an error opening or reading the file. + * - MEMALLOC if the parser does not have enough capacity and memory allocation fails. + * - CAPACITY if the parser does not have enough capacity and batch_size > max_capacity. + * - other json errors if parsing fails. You should not rely on these errors to always the same for the + * same document: they may vary under runtime dispatch (so they may vary depending on your system and hardware). + */ + inline simdjson_result load_many(const std::string &path, size_t batch_size = dom::DEFAULT_BATCH_SIZE) noexcept; + + /** + * Parse a buffer containing many JSON documents. + * + * dom::parser parser; + * for (element doc : parser.parse_many(buf, len)) { + * cout << std::string(doc["title"]) << endl; + * } + * + * No copy of the input buffer is made. + * + * The function is lazy: it may be that no more than one JSON document at a time is parsed. + * And, possibly, no document many have been parsed when the `parser.load_many(path)` function + * returned. + * + * The caller is responsabile to ensure that the input string data remains unchanged and is + * not deleted during the loop. In particular, the following is unsafe and will not compile: + * + * auto docs = parser.parse_many("[\"temporary data\"]"_padded); + * // here the string "[\"temporary data\"]" may no longer exist in memory + * // the parser instance may not have even accessed the input yet + * for (element doc : docs) { + * cout << std::string(doc["title"]) << endl; + * } + * + * The following is safe: + * + * auto json = "[\"temporary data\"]"_padded; + * auto docs = parser.parse_many(json); + * for (element doc : docs) { + * cout << std::string(doc["title"]) << endl; + * } + * + * If there is a UTF-8 BOM, the parser skips it. + * + * ### Format + * + * The buffer must contain a series of one or more JSON documents, concatenated into a single + * buffer, separated by whitespace. It effectively parses until it has a fully valid document, + * then starts parsing the next document at that point. (It does this with more parallelism and + * lookahead than you might think, though.) + * + * documents that consist of an object or array may omit the whitespace between them, concatenating + * with no separator. documents that consist of a single primitive (i.e. documents that are not + * arrays or objects) MUST be separated with whitespace. + * + * The documents must not exceed batch_size bytes (by default 1MB) or they will fail to parse. + * Setting batch_size to excessively large or excesively small values may impact negatively the + * performance. + * + * ### Error Handling + * + * All errors are returned during iteration: if there is a global error such as memory allocation, + * it will be yielded as the first result. Iteration always stops after the first error. + * + * 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: + * + * dom::parser parser; + * dom::document_stream docs; + * auto error = parser.load_many(path).get(docs); + * if (error) { cerr << error << endl; exit(1); } + * for (auto doc : docs) { + * std::string_view title; + * if ((error = doc["title"].get(title)) { cerr << error << endl; exit(1); } + * cout << title << endl; + * } + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * ### Threads + * + * When compiled with SIMDJSON_THREADS_ENABLED, this method will use a single thread under the + * hood to do some lookahead. + * + * ### Parser Capacity + * + * If the parser's current capacity is less than batch_size, it will allocate enough capacity + * to handle it (up to max_capacity). + * + * @param buf The concatenated JSON to parse. Must have at least len + SIMDJSON_PADDING allocated bytes. + * @param len The length of the concatenated JSON. + * @param batch_size The batch size to use. MUST be larger than the largest document. The sweet + * spot is cache-related: small enough to fit in cache, yet big enough to + * parse as many documents as possible in one tight loop. + * Defaults to 10MB, which has been a reasonable sweet spot in our tests. + * @return The stream, or an error. An empty input will yield 0 documents rather than an EMPTY error. Errors: + * - MEMALLOC if the parser does not have enough capacity and memory allocation fails + * - CAPACITY if the parser does not have enough capacity and batch_size > max_capacity. + * - other json errors if parsing fails. You should not rely on these errors to always the same for the + * same document: they may vary under runtime dispatch (so they may vary depending on your system and hardware). + */ + inline simdjson_result parse_many(const uint8_t *buf, size_t len, size_t batch_size = dom::DEFAULT_BATCH_SIZE) noexcept; + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result parse_many(const char *buf, size_t len, size_t batch_size = dom::DEFAULT_BATCH_SIZE) noexcept; + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result parse_many(const std::string &s, size_t batch_size = dom::DEFAULT_BATCH_SIZE) noexcept; + inline simdjson_result parse_many(const std::string &&s, size_t batch_size) = delete;// unsafe + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result parse_many(const padded_string &s, size_t batch_size = dom::DEFAULT_BATCH_SIZE) noexcept; + inline simdjson_result parse_many(const padded_string &&s, size_t batch_size) = delete;// unsafe + + /** @private We do not want to allow implicit conversion from C string to std::string. */ + simdjson_result parse_many(const char *buf, size_t batch_size = dom::DEFAULT_BATCH_SIZE) noexcept = delete; + + /** + * Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length + * and `max_depth` depth. + * + * @param capacity The new capacity. + * @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH. + * @return The error, if there is one. + */ + simdjson_warn_unused inline error_code allocate(size_t capacity, size_t max_depth = DEFAULT_MAX_DEPTH) noexcept; + +#ifndef SIMDJSON_DISABLE_DEPRECATED_API + /** + * @private deprecated because it returns bool instead of error_code, which is our standard for + * failures. Use allocate() instead. + * + * Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length + * and `max_depth` depth. + * + * @param capacity The new capacity. + * @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH. + * @return true if successful, false if allocation failed. + */ + [[deprecated("Use allocate() instead.")]] + simdjson_warn_unused inline bool allocate_capacity(size_t capacity, size_t max_depth = DEFAULT_MAX_DEPTH) noexcept; +#endif // SIMDJSON_DISABLE_DEPRECATED_API + /** + * The largest document this parser can support without reallocating. + * + * @return Current capacity, in bytes. + */ + simdjson_inline size_t capacity() const noexcept; + + /** + * The largest document this parser can automatically support. + * + * The parser may reallocate internal buffers as needed up to this amount. + * + * @return Maximum capacity, in bytes. + */ + simdjson_inline size_t max_capacity() const noexcept; + + /** + * The maximum level of nested object and arrays supported by this parser. + * + * @return Maximum depth, in bytes. + */ + simdjson_inline size_t max_depth() const noexcept; + + /** + * Set max_capacity. This is the largest document this parser can automatically support. + * + * The parser may reallocate internal buffers as needed up to this amount as documents are passed + * to it. + * + * Note: To avoid limiting the memory to an absurd value, such as zero or two bytes, + * iff you try to set max_capacity to a value lower than MINIMAL_DOCUMENT_CAPACITY, + * then the maximal capacity is set to MINIMAL_DOCUMENT_CAPACITY. + * + * This call will not allocate or deallocate, even if capacity is currently above max_capacity. + * + * @param max_capacity The new maximum capacity, in bytes. + */ + simdjson_inline void set_max_capacity(size_t max_capacity) noexcept; + +#ifdef SIMDJSON_THREADS_ENABLED + /** + * The parser instance can use threads when they are available to speed up some + * operations. It is enabled by default. Changing this attribute will change the + * behavior of the parser for future operations. + */ + bool threaded{true}; +#endif + /** @private Use the new DOM API instead */ + class Iterator; + /** @private Use simdjson_error instead */ + using InvalidJSON [[deprecated("Use simdjson_error instead")]] = simdjson_error; + + /** @private [for benchmarking access] The implementation to use */ + std::unique_ptr implementation{}; + + /** @private Use `if (parser.parse(...).error())` instead */ + bool valid{false}; + /** @private Use `parser.parse(...).error()` instead */ + error_code error{UNINITIALIZED}; + + /** @private Use `parser.parse(...).value()` instead */ + document doc{}; + + /** @private returns true if the document parsed was valid */ + [[deprecated("Use the result of parser.parse() instead")]] + inline bool is_valid() const noexcept; + + /** + * @private return an error code corresponding to the last parsing attempt, see + * simdjson.h will return UNINITIALIZED if no parsing was attempted + */ + [[deprecated("Use the result of parser.parse() instead")]] + inline int get_error_code() const noexcept; + + /** @private return the string equivalent of "get_error_code" */ + [[deprecated("Use error_message() on the result of parser.parse() instead, or cout << error")]] + inline std::string get_error_message() const noexcept; + + /** @private */ + [[deprecated("Use cout << on the result of parser.parse() instead")]] + inline bool print_json(std::ostream &os) const noexcept; + + /** @private Private and deprecated: use `parser.parse(...).doc.dump_raw_tape()` instead */ + inline bool dump_raw_tape(std::ostream &os) const noexcept; + + +private: + /** + * The maximum document length this parser will automatically support. + * + * The parser will not be automatically allocated above this amount. + */ + size_t _max_capacity; + + /** + * The loaded buffer (reused each time load() is called) + */ + std::unique_ptr loaded_bytes; + + /** Capacity of loaded_bytes buffer. */ + size_t _loaded_bytes_capacity{0}; + + // all nodes are stored on the doc.tape using a 64-bit word. + // + // strings, double and ints are stored as + // a 64-bit word with a pointer to the actual value + // + // + // + // for objects or arrays, store [ or { at the beginning and } and ] at the + // end. For the openings ([ or {), we annotate them with a reference to the + // location on the doc.tape of the end, and for then closings (} and ]), we + // annotate them with a reference to the location of the opening + // + // + + /** + * Ensure we have enough capacity to handle at least desired_capacity bytes, + * and auto-allocate if not. This also allocates memory if needed in the + * internal document. + */ + inline error_code ensure_capacity(size_t desired_capacity) noexcept; + /** + * Ensure we have enough capacity to handle at least desired_capacity bytes, + * and auto-allocate if not. This also allocates memory if needed in the + * provided document. + */ + inline error_code ensure_capacity(document& doc, size_t desired_capacity) noexcept; + + /** Read the file into loaded_bytes */ + inline simdjson_result read_file(const std::string &path) noexcept; + + friend class parser::Iterator; + friend class document_stream; + + +}; // class parser + +} // namespace dom +} // namespace simdjson + +#endif // SIMDJSON_DOM_PARSER_H +/* end file simdjson/dom/parser.h */ + +#ifdef SIMDJSON_THREADS_ENABLED +#include +#include +#include +#endif + +namespace simdjson { +namespace dom { + +#ifdef SIMDJSON_THREADS_ENABLED +/** @private Custom worker class **/ +struct stage1_worker { + stage1_worker() noexcept = default; + stage1_worker(const stage1_worker&) = delete; + stage1_worker(stage1_worker&&) = delete; + stage1_worker operator=(const stage1_worker&) = delete; + ~stage1_worker(); + /** + * We only start the thread when it is needed, not at object construction, this may throw. + * You should only call this once. + **/ + void start_thread(); + /** + * Start a stage 1 job. You should first call 'run', then 'finish'. + * You must call start_thread once before. + */ + void run(document_stream * ds, dom::parser * stage1, size_t next_batch_start); + /** Wait for the run to finish (blocking). You should first call 'run', then 'finish'. **/ + void finish(); + +private: + + /** + * Normally, we would never stop the thread. But we do in the destructor. + * This function is only safe assuming that you are not waiting for results. You + * should have called run, then finish, and be done. + **/ + void stop_thread(); + + std::thread thread{}; + /** These three variables define the work done by the thread. **/ + dom::parser * stage1_thread_parser{}; + size_t _next_batch_start{}; + document_stream * owner{}; + /** + * We have two state variables. This could be streamlined to one variable in the future but + * we use two for clarity. + */ + bool has_work{false}; + bool can_work{true}; + + /** + * We lock using a mutex. + */ + std::mutex locking_mutex{}; + std::condition_variable cond_var{}; +}; +#endif + +/** + * A forward-only stream of documents. + * + * Produced by parser::parse_many. + * + */ +class document_stream { +public: + /** + * Construct an uninitialized document_stream. + * + * ```c++ + * document_stream docs; + * error = parser.parse_many(json).get(docs); + * ``` + */ + simdjson_inline document_stream() noexcept; + /** Move one document_stream to another. */ + simdjson_inline document_stream(document_stream &&other) noexcept = default; + /** Move one document_stream to another. */ + simdjson_inline document_stream &operator=(document_stream &&other) noexcept = default; + + simdjson_inline ~document_stream() noexcept; + /** + * Returns the input size in bytes. + */ + inline size_t size_in_bytes() const noexcept; + /** + * After iterating through the stream, this method + * returns the number of bytes that were not parsed at the end + * of the stream. If truncated_bytes() differs from zero, + * then the input was truncated maybe because incomplete JSON + * documents were found at the end of the stream. You + * may need to process the bytes in the interval [size_in_bytes()-truncated_bytes(), size_in_bytes()). + * + * You should only call truncated_bytes() after streaming through all + * documents, like so: + * + * document_stream stream = parser.parse_many(json,window); + * for(auto doc : stream) { + * // do something with doc + * } + * size_t truncated = stream.truncated_bytes(); + * + */ + inline size_t truncated_bytes() const noexcept; + /** + * An iterator through a forward-only stream of documents. + */ + class iterator { + public: + using value_type = simdjson_result; + using reference = value_type; + + using difference_type = std::ptrdiff_t; + + using iterator_category = std::input_iterator_tag; + + /** + * Default constructor. + */ + simdjson_inline iterator() noexcept; + /** + * Get the current document (or error). + */ + simdjson_inline reference operator*() noexcept; + /** + * Advance to the next document (prefix). + */ + inline iterator& operator++() noexcept; + /** + * Check if we're at the end yet. + * @param other the end iterator to compare to. + */ + simdjson_inline bool operator!=(const iterator &other) const noexcept; + /** + * @private + * + * Gives the current index in the input document in bytes. + * + * document_stream stream = parser.parse_many(json,window); + * for(auto i = stream.begin(); i != stream.end(); ++i) { + * auto doc = *i; + * size_t index = i.current_index(); + * } + * + * This function (current_index()) is experimental and the usage + * may change in future versions of simdjson: we find the API somewhat + * awkward and we would like to offer something friendlier. + */ + simdjson_inline size_t current_index() const noexcept; + /** + * @private + * + * Gives a view of the current document. + * + * document_stream stream = parser.parse_many(json,window); + * for(auto i = stream.begin(); i != stream.end(); ++i) { + * auto doc = *i; + * std::string_view v = i->source(); + * } + * + * The returned string_view instance is simply a map to the (unparsed) + * source string: it may thus include white-space characters and all manner + * of padding. + * + * This function (source()) is experimental and the usage + * may change in future versions of simdjson: we find the API somewhat + * awkward and we would like to offer something friendlier. + */ + simdjson_inline std::string_view source() const noexcept; + + private: + simdjson_inline iterator(document_stream *s, bool finished) noexcept; + /** The document_stream we're iterating through. */ + document_stream* stream; + /** Whether we're finished or not. */ + bool finished; + friend class document_stream; + }; + + /** + * Start iterating the documents in the stream. + */ + simdjson_inline iterator begin() noexcept; + /** + * The end of the stream, for iterator comparison purposes. + */ + simdjson_inline iterator end() noexcept; + +private: + + document_stream &operator=(const document_stream &) = delete; // Disallow copying + document_stream(const document_stream &other) = delete; // Disallow copying + + /** + * Construct a document_stream. Does not allocate or parse anything until the iterator is + * used. + * + * @param parser is a reference to the parser instance used to generate this document_stream + * @param buf is the raw byte buffer we need to process + * @param len is the length of the raw byte buffer in bytes + * @param batch_size is the size of the windows (must be strictly greater or equal to the largest JSON document) + */ + simdjson_inline document_stream( + dom::parser &parser, + const uint8_t *buf, + size_t len, + size_t batch_size + ) noexcept; + + /** + * Parse the first document in the buffer. Used by begin(), to handle allocation and + * initialization. + */ + inline void start() noexcept; + + /** + * Parse the next document found in the buffer previously given to document_stream. + * + * The content should be a valid JSON document encoded as UTF-8. If there is a + * UTF-8 BOM, the parser skips it. + * + * You do NOT need to pre-allocate a parser. This function takes care of + * pre-allocating a capacity defined by the batch_size defined when creating the + * document_stream object. + * + * The function returns simdjson::EMPTY if there is no more data to be parsed. + * + * The function returns simdjson::SUCCESS (as integer = 0) in case of success + * and indicates that the buffer has successfully been parsed to the end. + * Every document it contained has been parsed without error. + * + * The function returns an error code from simdjson/simdjson.h in case of failure + * such as simdjson::CAPACITY, simdjson::MEMALLOC, simdjson::DEPTH_ERROR and so forth; + * the simdjson::error_message function converts these error codes into a string). + * + * You can also check validity by calling parser.is_valid(). The same parser can + * and should be reused for the other documents in the buffer. + */ + inline void next() noexcept; + + /** + * Pass the next batch through stage 1 and return when finished. + * When threads are enabled, this may wait for the stage 1 thread to finish. + */ + inline void load_batch() noexcept; + + /** Get the next document index. */ + inline size_t next_batch_start() const noexcept; + + /** Pass the next batch through stage 1 with the given parser. */ + inline error_code run_stage1(dom::parser &p, size_t batch_start) noexcept; + + dom::parser *parser; + const uint8_t *buf; + size_t len; + size_t batch_size; + /** The error (or lack thereof) from the current document. */ + error_code error; + size_t batch_start{0}; + size_t doc_index{}; +#ifdef SIMDJSON_THREADS_ENABLED + /** Indicates whether we use threads. Note that this needs to be a constant during the execution of the parsing. */ + bool use_thread; + + inline void load_from_stage1_thread() noexcept; + + /** Start a thread to run stage 1 on the next batch. */ + inline void start_stage1_thread() noexcept; + + /** Wait for the stage 1 thread to finish and capture the results. */ + inline void finish_stage1_thread() noexcept; + + /** The error returned from the stage 1 thread. */ + error_code stage1_thread_error{UNINITIALIZED}; + /** The thread used to run stage 1 against the next batch in the background. */ + friend struct stage1_worker; + std::unique_ptr worker{new(std::nothrow) stage1_worker()}; + /** + * The parser used to run stage 1 in the background. Will be swapped + * with the regular parser when finished. + */ + dom::parser stage1_thread_parser{}; +#endif // SIMDJSON_THREADS_ENABLED + + friend class dom::parser; + friend struct simdjson_result; + friend struct internal::simdjson_result_base; + +}; // class document_stream + +} // namespace dom + +template<> +struct simdjson_result : public internal::simdjson_result_base { +public: + simdjson_inline simdjson_result() noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result(dom::document_stream &&value) noexcept; ///< @private + +#if SIMDJSON_EXCEPTIONS + simdjson_inline dom::document_stream::iterator begin() noexcept(false); + simdjson_inline dom::document_stream::iterator end() noexcept(false); +#else // SIMDJSON_EXCEPTIONS +#ifndef SIMDJSON_DISABLE_DEPRECATED_API + [[deprecated("parse_many() and load_many() may return errors. Use document_stream stream; error = parser.parse_many().get(doc); instead.")]] + simdjson_inline dom::document_stream::iterator begin() noexcept; + [[deprecated("parse_many() and load_many() may return errors. Use document_stream stream; error = parser.parse_many().get(doc); instead.")]] + simdjson_inline dom::document_stream::iterator end() noexcept; +#endif // SIMDJSON_DISABLE_DEPRECATED_API +#endif // SIMDJSON_EXCEPTIONS +}; // struct simdjson_result + +} // namespace simdjson + +#endif // SIMDJSON_DOCUMENT_STREAM_H +/* end file simdjson/dom/document_stream.h */ +/* skipped duplicate #include "simdjson/dom/document.h" */ +/* including simdjson/dom/element.h: #include "simdjson/dom/element.h" */ +/* begin file simdjson/dom/element.h */ +#ifndef SIMDJSON_DOM_ELEMENT_H +#define SIMDJSON_DOM_ELEMENT_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* skipped duplicate #include "simdjson/dom/array.h" */ + +namespace simdjson { +namespace dom { + +/** + * The actual concrete type of a JSON element + * This is the type it is most easily cast to with get<>. + */ +enum class element_type { + ARRAY = '[', ///< dom::array + OBJECT = '{', ///< dom::object + INT64 = 'l', ///< int64_t + UINT64 = 'u', ///< uint64_t: any integer that fits in uint64_t but *not* int64_t + DOUBLE = 'd', ///< double: Any number with a "." or "e" that fits in double. + STRING = '"', ///< std::string_view + BOOL = 't', ///< bool + NULL_VALUE = 'n' ///< null +}; + +/** + * A JSON element. + * + * References an element in a JSON document, representing a JSON null, boolean, string, number, + * array or object. + */ +class element { +public: + /** Create a new, invalid element. */ + simdjson_inline element() noexcept; + + /** The type of this element. */ + simdjson_inline element_type type() const noexcept; + + /** + * Cast this element to an array. + * + * @returns An object that can be used to iterate the array, or: + * INCORRECT_TYPE if the JSON element is not an array. + */ + inline simdjson_result get_array() const noexcept; + /** + * Cast this element to an object. + * + * @returns An object that can be used to look up or iterate the object's fields, or: + * INCORRECT_TYPE if the JSON element is not an object. + */ + inline simdjson_result get_object() const noexcept; + /** + * Cast this element to a null-terminated C string. + * + * The string is guaranteed to be valid UTF-8. + * + * The length of the string is given by get_string_length(). Because JSON strings + * may contain null characters, it may be incorrect to use strlen to determine the + * string length. + * + * It is possible to get a single string_view instance which represents both the string + * content and its length: see get_string(). + * + * @returns A pointer to a null-terminated UTF-8 string. This string is stored in the parser and will + * be invalidated the next time it parses a document or when it is destroyed. + * Returns INCORRECT_TYPE if the JSON element is not a string. + */ + inline simdjson_result get_c_str() const noexcept; + /** + * Gives the length in bytes of the string. + * + * It is possible to get a single string_view instance which represents both the string + * content and its length: see get_string(). + * + * @returns A string length in bytes. + * Returns INCORRECT_TYPE if the JSON element is not a string. + */ + inline simdjson_result get_string_length() const noexcept; + /** + * Cast this element to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next time it + * parses a document or when it is destroyed. + * Returns INCORRECT_TYPE if the JSON element is not a string. + */ + inline simdjson_result get_string() const noexcept; + /** + * Cast this element to a signed integer. + * + * @returns A signed 64-bit integer. + * Returns INCORRECT_TYPE if the JSON element is not an integer, or NUMBER_OUT_OF_RANGE + * if it is negative. + */ + inline simdjson_result get_int64() const noexcept; + /** + * Cast this element to an unsigned integer. + * + * @returns An unsigned 64-bit integer. + * Returns INCORRECT_TYPE if the JSON element is not an integer, or NUMBER_OUT_OF_RANGE + * if it is too large. + */ + inline simdjson_result get_uint64() const noexcept; + /** + * Cast this element to a double floating-point. + * + * @returns A double value. + * Returns INCORRECT_TYPE if the JSON element is not a number. + */ + inline simdjson_result get_double() const noexcept; + /** + * Cast this element to a bool. + * + * @returns A bool value. + * Returns INCORRECT_TYPE if the JSON element is not a boolean. + */ + inline simdjson_result get_bool() const noexcept; + + /** + * Whether this element is a json array. + * + * Equivalent to is(). + */ + inline bool is_array() const noexcept; + /** + * Whether this element is a json object. + * + * Equivalent to is(). + */ + inline bool is_object() const noexcept; + /** + * Whether this element is a json string. + * + * Equivalent to is() or is(). + */ + inline bool is_string() const noexcept; + /** + * Whether this element is a json number that fits in a signed 64-bit integer. + * + * Equivalent to is(). + */ + inline bool is_int64() const noexcept; + /** + * Whether this element is a json number that fits in an unsigned 64-bit integer. + * + * Equivalent to is(). + */ + inline bool is_uint64() const noexcept; + /** + * Whether this element is a json number that fits in a double. + * + * Equivalent to is(). + */ + inline bool is_double() const noexcept; + + /** + * Whether this element is a json number. + * + * Both integers and floating points will return true. + */ + inline bool is_number() const noexcept; + + /** + * Whether this element is a json `true` or `false`. + * + * Equivalent to is(). + */ + inline bool is_bool() const noexcept; + /** + * Whether this element is a json `null`. + */ + inline bool is_null() const noexcept; + + /** + * Tell whether the value can be cast to provided type (T). + * + * Supported types: + * - Boolean: bool + * - Number: double, uint64_t, int64_t + * - String: std::string_view, const char * + * - Array: dom::array + * - Object: dom::object + * + * @tparam T bool, double, uint64_t, int64_t, std::string_view, const char *, dom::array, dom::object + */ + template + simdjson_inline bool is() const noexcept; + + /** + * Get the value as the provided type (T). + * + * Supported types: + * - Boolean: bool + * - Number: double, uint64_t, int64_t + * - String: std::string_view, const char * + * - Array: dom::array + * - Object: dom::object + * + * You may use get_double(), get_bool(), get_uint64(), get_int64(), + * get_object(), get_array() or get_string() instead. + * + * @tparam T bool, double, uint64_t, int64_t, std::string_view, const char *, dom::array, dom::object + * + * @returns The value cast to the given type, or: + * INCORRECT_TYPE if the value cannot be cast to the given type. + */ + + template + inline simdjson_result get() const noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are Boolean (bool), numbers (double, uint64_t, int64_t), " + "strings (std::string_view, const char *), arrays (dom::array) and objects (dom::object). " + "We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + "get_object(), get_array() or get_string() instead of the get template."); + } + + /** + * Get the value as the provided type (T). + * + * Supported types: + * - Boolean: bool + * - Number: double, uint64_t, int64_t + * - String: std::string_view, const char * + * - Array: dom::array + * - Object: dom::object + * + * @tparam T bool, double, uint64_t, int64_t, std::string_view, const char *, dom::array, dom::object + * + * @param value The variable to set to the value. May not be set if there is an error. + * + * @returns The error that occurred, or SUCCESS if there was no error. + */ + template + simdjson_warn_unused simdjson_inline error_code get(T &value) const noexcept; + + /** + * Get the value as the provided type (T), setting error if it's not the given type. + * + * Supported types: + * - Boolean: bool + * - Number: double, uint64_t, int64_t + * - String: std::string_view, const char * + * - Array: dom::array + * - Object: dom::object + * + * @tparam T bool, double, uint64_t, int64_t, std::string_view, const char *, dom::array, dom::object + * + * @param value The variable to set to the given type. value is undefined if there is an error. + * @param error The variable to store the error. error is set to error_code::SUCCEED if there is an error. + */ + template + inline void tie(T &value, error_code &error) && noexcept; + +#if SIMDJSON_EXCEPTIONS + /** + * Read this element as a boolean. + * + * @return The boolean value + * @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not a boolean. + */ + inline operator bool() const noexcept(false); + + /** + * Read this element as a null-terminated UTF-8 string. + * + * Be mindful that JSON allows strings to contain null characters. + * + * Does *not* convert other types to a string; requires that the JSON type of the element was + * an actual string. + * + * @return The string value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not a string. + */ + inline explicit operator const char*() const noexcept(false); + + /** + * Read this element as a null-terminated UTF-8 string. + * + * Does *not* convert other types to a string; requires that the JSON type of the element was + * an actual string. + * + * @return The string value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not a string. + */ + inline operator std::string_view() const noexcept(false); + + /** + * Read this element as an unsigned integer. + * + * @return The integer value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not an integer + * @exception simdjson_error(NUMBER_OUT_OF_RANGE) if the integer doesn't fit in 64 bits or is negative + */ + inline operator uint64_t() const noexcept(false); + /** + * Read this element as an signed integer. + * + * @return The integer value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not an integer + * @exception simdjson_error(NUMBER_OUT_OF_RANGE) if the integer doesn't fit in 64 bits + */ + inline operator int64_t() const noexcept(false); + /** + * Read this element as an double. + * + * @return The double value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not a number + * @exception simdjson_error(NUMBER_OUT_OF_RANGE) if the integer doesn't fit in 64 bits or is negative + */ + inline operator double() const noexcept(false); + /** + * Read this element as a JSON array. + * + * @return The JSON array. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not an array + */ + inline operator array() const noexcept(false); + /** + * Read this element as a JSON object (key/value pairs). + * + * @return The JSON object. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not an object + */ + inline operator object() const noexcept(false); + + /** + * Iterate over each element in this array. + * + * @return The beginning of the iteration. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not an array + */ + inline dom::array::iterator begin() const noexcept(false); + + /** + * Iterate over each element in this array. + * + * @return The end of the iteration. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not an array + */ + inline dom::array::iterator end() const noexcept(false); +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the value associated with the given key. + * + * The key will be matched against **unescaped** JSON: + * + * dom::parser parser; + * int64_t(parser.parse(R"({ "a\n": 1 })"_padded)["a\n"]) == 1 + * parser.parse(R"({ "a\n": 1 })"_padded)["a\\n"].get_uint64().error() == NO_SUCH_FIELD + * + * @return The value associated with this field, or: + * - NO_SUCH_FIELD if the field does not exist in the object + * - INCORRECT_TYPE if this is not an object + */ + inline simdjson_result operator[](std::string_view key) const noexcept; + + /** + * Get the value associated with the given key. + * + * The key will be matched against **unescaped** JSON: + * + * dom::parser parser; + * int64_t(parser.parse(R"({ "a\n": 1 })"_padded)["a\n"]) == 1 + * parser.parse(R"({ "a\n": 1 })"_padded)["a\\n"].get_uint64().error() == NO_SUCH_FIELD + * + * @return The value associated with this field, or: + * - NO_SUCH_FIELD if the field does not exist in the object + * - INCORRECT_TYPE if this is not an object + */ + inline simdjson_result operator[](const char *key) const noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard. + * + * dom::parser parser; + * element doc = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded); + * doc.at_pointer("/foo/a/1") == 20 + * doc.at_pointer("/foo")["a"].at(1) == 20 + * doc.at_pointer("")["foo"]["a"].at(1) == 20 + * + * It is allowed for a key to be the empty string: + * + * dom::parser parser; + * object obj = parser.parse(R"({ "": { "a": [ 10, 20, 30 ] }})"_padded); + * obj.at_pointer("//a/1") == 20 + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(const std::string_view json_pointer) const noexcept; + +#ifndef SIMDJSON_DISABLE_DEPRECATED_API + /** + * + * Version 0.4 of simdjson used an incorrect interpretation of the JSON Pointer standard + * and allowed the following : + * + * dom::parser parser; + * element doc = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded); + * doc.at("foo/a/1") == 20 + * + * Though it is intuitive, it is not compliant with RFC 6901 + * https://tools.ietf.org/html/rfc6901 + * + * For standard compliance, use the at_pointer function instead. + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + [[deprecated("For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]] + inline simdjson_result at(const std::string_view json_pointer) const noexcept; +#endif // SIMDJSON_DISABLE_DEPRECATED_API + + /** + * Get the value at the given index. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + inline simdjson_result at(size_t index) const noexcept; + + /** + * Get the value associated with the given key. + * + * The key will be matched against **unescaped** JSON: + * + * dom::parser parser; + * int64_t(parser.parse(R"({ "a\n": 1 })"_padded)["a\n"]) == 1 + * parser.parse(R"({ "a\n": 1 })"_padded)["a\\n"].get_uint64().error() == NO_SUCH_FIELD + * + * @return The value associated with this field, or: + * - NO_SUCH_FIELD if the field does not exist in the object + */ + inline simdjson_result at_key(std::string_view key) const noexcept; + + /** + * Get the value associated with the given key in a case-insensitive manner. + * + * Note: The key will be matched against **unescaped** JSON. + * + * @return The value associated with this field, or: + * - NO_SUCH_FIELD if the field does not exist in the object + */ + inline simdjson_result at_key_case_insensitive(std::string_view key) const noexcept; + + /** + * operator< defines a total order for element allowing to use them in + * ordered C++ STL containers + * + * @return TRUE if the key appears before the other one in the tape + */ + inline bool operator<(const element &other) const noexcept; + + /** + * operator== allows to verify if two element values reference the + * same JSON item + * + * @return TRUE if the two values references the same JSON element + */ + inline bool operator==(const element &other) const noexcept; + + /** @private for debugging. Prints out the root element. */ + inline bool dump_raw_tape(std::ostream &out) const noexcept; + +private: + simdjson_inline element(const internal::tape_ref &tape) noexcept; + internal::tape_ref tape; + friend class document; + friend class object; + friend class array; + friend struct simdjson_result; + template + friend class simdjson::internal::string_builder; + +}; + +} // namespace dom + +/** The result of a JSON navigation that may fail. */ +template<> +struct simdjson_result : public internal::simdjson_result_base { +public: + simdjson_inline simdjson_result() noexcept; ///< @private + simdjson_inline simdjson_result(dom::element &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + + simdjson_inline simdjson_result type() const noexcept; + template + simdjson_inline bool is() const noexcept; + template + simdjson_inline simdjson_result get() const noexcept; + template + simdjson_warn_unused simdjson_inline error_code get(T &value) const noexcept; + + simdjson_inline simdjson_result get_array() const noexcept; + simdjson_inline simdjson_result get_object() const noexcept; + simdjson_inline simdjson_result get_c_str() const noexcept; + simdjson_inline simdjson_result get_string_length() const noexcept; + simdjson_inline simdjson_result get_string() const noexcept; + simdjson_inline simdjson_result get_int64() const noexcept; + simdjson_inline simdjson_result get_uint64() const noexcept; + simdjson_inline simdjson_result get_double() const noexcept; + simdjson_inline simdjson_result get_bool() const noexcept; + + simdjson_inline bool is_array() const noexcept; + simdjson_inline bool is_object() const noexcept; + simdjson_inline bool is_string() const noexcept; + simdjson_inline bool is_int64() const noexcept; + simdjson_inline bool is_uint64() const noexcept; + simdjson_inline bool is_double() const noexcept; + simdjson_inline bool is_number() const noexcept; + simdjson_inline bool is_bool() const noexcept; + simdjson_inline bool is_null() const noexcept; + + simdjson_inline simdjson_result operator[](std::string_view key) const noexcept; + simdjson_inline simdjson_result operator[](const char *key) const noexcept; + simdjson_inline simdjson_result at_pointer(const std::string_view json_pointer) const noexcept; + [[deprecated("For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]] + simdjson_inline simdjson_result at(const std::string_view json_pointer) const noexcept; + simdjson_inline simdjson_result at(size_t index) const noexcept; + simdjson_inline simdjson_result at_key(std::string_view key) const noexcept; + simdjson_inline simdjson_result at_key_case_insensitive(std::string_view key) const noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator bool() const noexcept(false); + simdjson_inline explicit operator const char*() const noexcept(false); + simdjson_inline operator std::string_view() const noexcept(false); + simdjson_inline operator uint64_t() const noexcept(false); + simdjson_inline operator int64_t() const noexcept(false); + simdjson_inline operator double() const noexcept(false); + simdjson_inline operator dom::array() const noexcept(false); + simdjson_inline operator dom::object() const noexcept(false); + + simdjson_inline dom::array::iterator begin() const noexcept(false); + simdjson_inline dom::array::iterator end() const noexcept(false); +#endif // SIMDJSON_EXCEPTIONS +}; + +} // namespace simdjson + +#endif // SIMDJSON_DOM_DOCUMENT_H +/* end file simdjson/dom/element.h */ +/* including simdjson/dom/object.h: #include "simdjson/dom/object.h" */ +/* begin file simdjson/dom/object.h */ +#ifndef SIMDJSON_DOM_OBJECT_H +#define SIMDJSON_DOM_OBJECT_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* skipped duplicate #include "simdjson/dom/element.h" */ +/* skipped duplicate #include "simdjson/internal/tape_ref.h" */ + +namespace simdjson { +namespace dom { + +/** + * JSON object. + */ +class object { +public: + /** Create a new, invalid object */ + simdjson_inline object() noexcept; + + class iterator { + public: + using value_type = key_value_pair; + using difference_type = std::ptrdiff_t; + + /** + * Get the actual key/value pair + */ + inline const value_type operator*() const noexcept; + /** + * Get the next key/value pair. + * + * Part of the std::iterator interface. + * + */ + inline iterator& operator++() noexcept; + /** + * Get the next key/value pair. + * + * Part of the std::iterator interface. + * + */ + inline iterator operator++(int) noexcept; + /** + * Check if these values come from the same place in the JSON. + * + * Part of the std::iterator interface. + */ + inline bool operator!=(const iterator& other) const noexcept; + inline bool operator==(const iterator& other) const noexcept; + + inline bool operator<(const iterator& other) const noexcept; + inline bool operator<=(const iterator& other) const noexcept; + inline bool operator>=(const iterator& other) const noexcept; + inline bool operator>(const iterator& other) const noexcept; + /** + * Get the key of this key/value pair. + */ + inline std::string_view key() const noexcept; + /** + * Get the length (in bytes) of the key in this key/value pair. + * You should expect this function to be faster than key().size(). + */ + inline uint32_t key_length() const noexcept; + /** + * Returns true if the key in this key/value pair is equal + * to the provided string_view. + */ + inline bool key_equals(std::string_view o) const noexcept; + /** + * Returns true if the key in this key/value pair is equal + * to the provided string_view in a case-insensitive manner. + * Case comparisons may only be handled correctly for ASCII strings. + */ + inline bool key_equals_case_insensitive(std::string_view o) const noexcept; + /** + * Get the key of this key/value pair. + */ + inline const char *key_c_str() const noexcept; + /** + * Get the value of this key/value pair. + */ + inline element value() const noexcept; + + iterator() noexcept = default; + iterator(const iterator&) noexcept = default; + iterator& operator=(const iterator&) noexcept = default; + private: + simdjson_inline iterator(const internal::tape_ref &tape) noexcept; + + internal::tape_ref tape; + + friend class object; + }; + + /** + * Return the first key/value pair. + * + * Part of the std::iterable interface. + */ + inline iterator begin() const noexcept; + /** + * One past the last key/value pair. + * + * Part of the std::iterable interface. + */ + inline iterator end() const noexcept; + /** + * Get the size of the object (number of keys). + * It is a saturated value with a maximum of 0xFFFFFF: if the value + * is 0xFFFFFF then the size is 0xFFFFFF or greater. + */ + inline size_t size() const noexcept; + /** + * Get the value associated with the given key. + * + * The key will be matched against **unescaped** JSON: + * + * dom::parser parser; + * int64_t(parser.parse(R"({ "a\n": 1 })"_padded)["a\n"]) == 1 + * parser.parse(R"({ "a\n": 1 })"_padded)["a\\n"].get_uint64().error() == NO_SUCH_FIELD + * + * This function has linear-time complexity: the keys are checked one by one. + * + * @return The value associated with this field, or: + * - NO_SUCH_FIELD if the field does not exist in the object + * - INCORRECT_TYPE if this is not an object + */ + inline simdjson_result operator[](std::string_view key) const noexcept; + + /** + * Get the value associated with the given key. + * + * The key will be matched against **unescaped** JSON: + * + * dom::parser parser; + * int64_t(parser.parse(R"({ "a\n": 1 })"_padded)["a\n"]) == 1 + * parser.parse(R"({ "a\n": 1 })"_padded)["a\\n"].get_uint64().error() == NO_SUCH_FIELD + * + * This function has linear-time complexity: the keys are checked one by one. + * + * @return The value associated with this field, or: + * - NO_SUCH_FIELD if the field does not exist in the object + * - INCORRECT_TYPE if this is not an object + */ + inline simdjson_result operator[](const char *key) const noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard, interpreting the current node + * as the root of its own JSON document. + * + * dom::parser parser; + * object obj = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded); + * obj.at_pointer("/foo/a/1") == 20 + * obj.at_pointer("/foo")["a"].at(1) == 20 + * + * It is allowed for a key to be the empty string: + * + * dom::parser parser; + * object obj = parser.parse(R"({ "": { "a": [ 10, 20, 30 ] }})"_padded); + * obj.at_pointer("//a/1") == 20 + * obj.at_pointer("/")["a"].at(1) == 20 + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(std::string_view json_pointer) const noexcept; + + /** + * Get the value associated with the given key. + * + * The key will be matched against **unescaped** JSON: + * + * dom::parser parser; + * int64_t(parser.parse(R"({ "a\n": 1 })"_padded)["a\n"]) == 1 + * parser.parse(R"({ "a\n": 1 })"_padded)["a\\n"].get_uint64().error() == NO_SUCH_FIELD + * + * This function has linear-time complexity: the keys are checked one by one. + * + * @return The value associated with this field, or: + * - NO_SUCH_FIELD if the field does not exist in the object + */ + inline simdjson_result at_key(std::string_view key) const noexcept; + + /** + * Get the value associated with the given key in a case-insensitive manner. + * It is only guaranteed to work over ASCII inputs. + * + * Note: The key will be matched against **unescaped** JSON. + * + * This function has linear-time complexity: the keys are checked one by one. + * + * @return The value associated with this field, or: + * - NO_SUCH_FIELD if the field does not exist in the object + */ + inline simdjson_result at_key_case_insensitive(std::string_view key) const noexcept; + +private: + simdjson_inline object(const internal::tape_ref &tape) noexcept; + + internal::tape_ref tape; + + friend class element; + friend struct simdjson_result; + template + friend class simdjson::internal::string_builder; +}; + +/** + * Key/value pair in an object. + */ +class key_value_pair { +public: + /** key in the key-value pair **/ + std::string_view key; + /** value in the key-value pair **/ + element value; + +private: + simdjson_inline key_value_pair(std::string_view _key, element _value) noexcept; + friend class object; +}; + +} // namespace dom + +/** The result of a JSON conversion that may fail. */ +template<> +struct simdjson_result : public internal::simdjson_result_base { +public: + simdjson_inline simdjson_result() noexcept; ///< @private + simdjson_inline simdjson_result(dom::object value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + + inline simdjson_result operator[](std::string_view key) const noexcept; + inline simdjson_result operator[](const char *key) const noexcept; + inline simdjson_result at_pointer(std::string_view json_pointer) const noexcept; + inline simdjson_result at_key(std::string_view key) const noexcept; + inline simdjson_result at_key_case_insensitive(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); + inline size_t size() const noexcept(false); +#endif // SIMDJSON_EXCEPTIONS +}; + +} // namespace simdjson + +#if defined(__cpp_lib_ranges) +#include + +namespace std { +namespace ranges { +template<> +inline constexpr bool enable_view = true; +#if SIMDJSON_EXCEPTIONS +template<> +inline constexpr bool enable_view> = true; +#endif // SIMDJSON_EXCEPTIONS +} // namespace ranges +} // namespace std +#endif // defined(__cpp_lib_ranges) + +#endif // SIMDJSON_DOM_OBJECT_H +/* end file simdjson/dom/object.h */ +/* skipped duplicate #include "simdjson/dom/parser.h" */ +/* including simdjson/dom/serialization.h: #include "simdjson/dom/serialization.h" */ +/* begin file simdjson/dom/serialization.h */ +#ifndef SIMDJSON_SERIALIZATION_H +#define SIMDJSON_SERIALIZATION_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* skipped duplicate #include "simdjson/dom/element.h" */ +/* skipped duplicate #include "simdjson/dom/object.h" */ + +#include + +namespace simdjson { + +/** + * The string_builder template and mini_formatter class + * are not part of our public API and are subject to change + * at any time! + */ +namespace internal { + +template +class base_formatter { +public: + /** Add a comma **/ + simdjson_inline void comma(); + /** Start an array, prints [ **/ + simdjson_inline void start_array(); + /** End an array, prints ] **/ + simdjson_inline void end_array(); + /** Start an array, prints { **/ + simdjson_inline void start_object(); + /** Start an array, prints } **/ + simdjson_inline void end_object(); + /** Prints a true **/ + simdjson_inline void true_atom(); + /** Prints a false **/ + simdjson_inline void false_atom(); + /** Prints a null **/ + simdjson_inline void null_atom(); + /** Prints a number **/ + simdjson_inline void number(int64_t x); + /** Prints a number **/ + simdjson_inline void number(uint64_t x); + /** Prints a number **/ + simdjson_inline void number(double x); + /** Prints a key (string + colon) **/ + simdjson_inline void key(std::string_view unescaped); + /** Prints a string. The string is escaped as needed. **/ + simdjson_inline void string(std::string_view unescaped); + /** Clears out the content. **/ + simdjson_inline void clear(); + /** + * Get access to the buffer, it is owned by the instance, but + * the user can make a copy. + **/ + simdjson_inline std::string_view str() const; + + /** Prints one character **/ + simdjson_inline void one_char(char c); + + simdjson_inline void call_print_newline() { + this->print_newline(); + } + + simdjson_inline void call_print_indents(size_t depth) { + this->print_indents(depth); + } + + simdjson_inline void call_print_space() { + this->print_space(); + } + +protected: + // implementation details (subject to change) + /** Backing buffer **/ + std::vector buffer{}; // not ideal! +}; + + +/** + * @private This is the class that we expect to use with the string_builder + * template. It tries to produce a compact version of the JSON element + * as quickly as possible. + */ +class mini_formatter : public base_formatter { +public: + simdjson_inline void print_newline(); + + simdjson_inline void print_indents(size_t depth); + + simdjson_inline void print_space(); +}; + +class pretty_formatter : public base_formatter { +public: + simdjson_inline void print_newline(); + + simdjson_inline void print_indents(size_t depth); + + simdjson_inline void print_space(); + +protected: + int indent_step = 4; +}; + +/** + * @private The string_builder template allows us to construct + * a string from a document element. It is parametrized + * by a "formatter" which handles the details. Thus + * the string_builder template could support both minification + * and prettification, and various other tradeoffs. + */ +template +class string_builder { +public: + /** Construct an initially empty builder, would print the empty string **/ + string_builder() = default; + /** Append an element to the builder (to be printed) **/ + inline void append(simdjson::dom::element value); + /** Append an array to the builder (to be printed) **/ + inline void append(simdjson::dom::array value); + /** Append an object to the builder (to be printed) **/ + inline void append(simdjson::dom::object value); + /** Reset the builder (so that it would print the empty string) **/ + simdjson_inline void clear(); + /** + * Get access to the string. The string_view is owned by the builder + * and it is invalid to use it after the string_builder has been + * destroyed. + * However you can make a copy of the string_view on memory that you + * own. + */ + simdjson_inline std::string_view str() const; + /** Append a key_value_pair to the builder (to be printed) **/ + simdjson_inline void append(simdjson::dom::key_value_pair value); +private: + formatter format{}; +}; + +} // internal + +namespace dom { + +/** + * Print JSON to an output stream. + * + * @param out The output stream. + * @param value The element. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::dom::element value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +/** + * Print JSON to an output stream. + * + * @param out The output stream. + * @param value The array. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::dom::array value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +/** + * Print JSON to an output stream. + * + * @param out The output stream. + * @param value The object. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::dom::object value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +} // namespace dom + +/** + * Converts JSON to a string. + * + * dom::parser parser; + * element doc = parser.parse(" [ 1 , 2 , 3 ] "_padded); + * cout << to_string(doc) << endl; // prints [1,2,3] + * + */ +template +std::string to_string(T x) { + // in C++, to_string is standard: http://www.cplusplus.com/reference/string/to_string/ + // Currently minify and to_string are identical but in the future, they may + // differ. + simdjson::internal::string_builder<> sb; + sb.append(x); + std::string_view answer = sb.str(); + return std::string(answer.data(), answer.size()); +} +#if SIMDJSON_EXCEPTIONS +template +std::string to_string(simdjson_result x) { + if (x.error()) { throw simdjson_error(x.error()); } + return to_string(x.value()); +} +#endif + +/** + * Minifies a JSON element or document, printing the smallest possible valid JSON. + * + * dom::parser parser; + * element doc = parser.parse(" [ 1 , 2 , 3 ] "_padded); + * cout << minify(doc) << endl; // prints [1,2,3] + * + */ +template +std::string minify(T x) { + return to_string(x); +} + +#if SIMDJSON_EXCEPTIONS +template +std::string minify(simdjson_result x) { + if (x.error()) { throw simdjson_error(x.error()); } + return to_string(x.value()); +} +#endif + +/** + * Prettifies a JSON element or document, printing the valid JSON with indentation. + * + * dom::parser parser; + * element doc = parser.parse(" [ 1 , 2 , 3 ] "_padded); + * + * // Prints: + * // { + * // [ + * // 1, + * // 2, + * // 3 + * // ] + * // } + * cout << prettify(doc) << endl; + * + */ +template +std::string prettify(T x) { + simdjson::internal::string_builder sb; + sb.append(x); + std::string_view answer = sb.str(); + return std::string(answer.data(), answer.size()); +} + +#if SIMDJSON_EXCEPTIONS +template +std::string prettify(simdjson_result x) { + if (x.error()) { throw simdjson_error(x.error()); } + return to_string(x.value()); +} +#endif + +} // namespace simdjson + + +#endif +/* end file simdjson/dom/serialization.h */ + +// Deprecated API +/* including simdjson/dom/jsonparser.h: #include "simdjson/dom/jsonparser.h" */ +/* begin file simdjson/dom/jsonparser.h */ +// TODO Remove this -- deprecated API and files + +#ifndef SIMDJSON_DOM_JSONPARSER_H +#define SIMDJSON_DOM_JSONPARSER_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* skipped duplicate #include "simdjson/dom/parser.h" */ +/* skipped duplicate #include "simdjson/dom/element.h" */ + +/* including simdjson/dom/parser-inl.h: #include "simdjson/dom/parser-inl.h" */ +/* begin file simdjson/dom/parser-inl.h */ +#ifndef SIMDJSON_PARSER_INL_H +#define SIMDJSON_PARSER_INL_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* skipped duplicate #include "simdjson/dom/document_stream.h" */ +/* skipped duplicate #include "simdjson/implementation.h" */ +/* skipped duplicate #include "simdjson/internal/dom_parser_implementation.h" */ + +/* skipped duplicate #include "simdjson/error-inl.h" */ +/* skipped duplicate #include "simdjson/padded_string-inl.h" */ +/* including simdjson/dom/document_stream-inl.h: #include "simdjson/dom/document_stream-inl.h" */ +/* begin file simdjson/dom/document_stream-inl.h */ +#ifndef SIMDJSON_DOCUMENT_STREAM_INL_H +#define SIMDJSON_DOCUMENT_STREAM_INL_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* skipped duplicate #include "simdjson/dom/document_stream.h" */ +/* including simdjson/dom/element-inl.h: #include "simdjson/dom/element-inl.h" */ +/* begin file simdjson/dom/element-inl.h */ +#ifndef SIMDJSON_ELEMENT_INL_H +#define SIMDJSON_ELEMENT_INL_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* skipped duplicate #include "simdjson/dom/element.h" */ +/* skipped duplicate #include "simdjson/dom/document.h" */ +/* skipped duplicate #include "simdjson/dom/object.h" */ +/* including simdjson/internal/tape_type.h: #include "simdjson/internal/tape_type.h" */ +/* begin file simdjson/internal/tape_type.h */ +#ifndef SIMDJSON_INTERNAL_TAPE_TYPE_H +#define SIMDJSON_INTERNAL_TAPE_TYPE_H + +namespace simdjson { +namespace internal { + +/** + * The possible types in the tape. + */ +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' +}; // enum class tape_type + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_TAPE_TYPE_H +/* end file simdjson/internal/tape_type.h */ + +/* including simdjson/dom/object-inl.h: #include "simdjson/dom/object-inl.h" */ +/* begin file simdjson/dom/object-inl.h */ +#ifndef SIMDJSON_OBJECT_INL_H +#define SIMDJSON_OBJECT_INL_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* skipped duplicate #include "simdjson/dom/object.h" */ +/* skipped duplicate #include "simdjson/dom/document.h" */ + +/* skipped duplicate #include "simdjson/dom/element-inl.h" */ +/* skipped duplicate #include "simdjson/error-inl.h" */ + +#include + +namespace simdjson { + +// +// simdjson_result inline implementation +// +simdjson_inline simdjson_result::simdjson_result() noexcept + : internal::simdjson_result_base() {} +simdjson_inline simdjson_result::simdjson_result(dom::object value) noexcept + : internal::simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : internal::simdjson_result_base(error) {} + +inline simdjson_result simdjson_result::operator[](std::string_view key) const noexcept { + if (error()) { return error(); } + return first[key]; +} +inline simdjson_result simdjson_result::operator[](const char *key) const noexcept { + if (error()) { return error(); } + return first[key]; +} +inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) const noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} +inline simdjson_result simdjson_result::at_key(std::string_view key) const noexcept { + if (error()) { return error(); } + return first.at_key(key); +} +inline simdjson_result simdjson_result::at_key_case_insensitive(std::string_view key) const noexcept { + if (error()) { return error(); } + return first.at_key_case_insensitive(key); +} + +#if SIMDJSON_EXCEPTIONS + +inline dom::object::iterator simdjson_result::begin() const noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first.begin(); +} +inline dom::object::iterator simdjson_result::end() const noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first.end(); +} +inline size_t simdjson_result::size() const noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first.size(); +} + +#endif // SIMDJSON_EXCEPTIONS + +namespace dom { + +// +// object inline implementation +// +simdjson_inline object::object() noexcept : tape{} {} +simdjson_inline object::object(const internal::tape_ref &_tape) noexcept : tape{_tape} { } +inline object::iterator object::begin() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + return internal::tape_ref(tape.doc, tape.json_index + 1); +} +inline object::iterator object::end() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + return internal::tape_ref(tape.doc, tape.after_element() - 1); +} +inline size_t object::size() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + return tape.scope_count(); +} + +inline simdjson_result object::operator[](std::string_view key) const noexcept { + return at_key(key); +} +inline simdjson_result object::operator[](const char *key) const noexcept { + return at_key(key); +} +inline simdjson_result object::at_pointer(std::string_view json_pointer) const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + if(json_pointer.empty()) { // an empty string means that we return the current node + return element(this->tape); // copy the current node + } else if(json_pointer[0] != '/') { // otherwise there is an error + return INVALID_JSON_POINTER; + } + json_pointer = json_pointer.substr(1); + size_t slash = json_pointer.find('/'); + std::string_view key = json_pointer.substr(0, slash); + // Grab the child with the given key + simdjson_result child; + + // If there is an escape character in the key, unescape it and then get the child. + size_t escape = key.find('~'); + if (escape != std::string_view::npos) { + // Unescape the key + std::string unescaped(key); + do { + switch (unescaped[escape+1]) { + case '0': + unescaped.replace(escape, 2, "~"); + break; + case '1': + unescaped.replace(escape, 2, "/"); + break; + default: + return INVALID_JSON_POINTER; // "Unexpected ~ escape character in JSON pointer"); + } + escape = unescaped.find('~', escape+1); + } while (escape != std::string::npos); + child = at_key(unescaped); + } else { + child = at_key(key); + } + if(child.error()) { + return child; // we do not continue if there was an error + } + // If there is a /, we have to recurse and look up more of the path + if (slash != std::string_view::npos) { + child = child.at_pointer(json_pointer.substr(slash)); + } + return child; +} + +inline simdjson_result object::at_key(std::string_view key) const noexcept { + iterator end_field = end(); + for (iterator field = begin(); field != end_field; ++field) { + if (field.key_equals(key)) { + return field.value(); + } + } + return NO_SUCH_FIELD; +} +// 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 object::at_key_case_insensitive(std::string_view key) const noexcept { + iterator end_field = end(); + for (iterator field = begin(); field != end_field; ++field) { + if (field.key_equals_case_insensitive(key)) { + return field.value(); + } + } + return NO_SUCH_FIELD; +} + +// +// object::iterator inline implementation +// +simdjson_inline object::iterator::iterator(const internal::tape_ref &_tape) noexcept : tape{_tape} { } +inline const key_value_pair object::iterator::operator*() const noexcept { + return key_value_pair(key(), value()); +} +inline bool object::iterator::operator!=(const object::iterator& other) const noexcept { + return tape.json_index != other.tape.json_index; +} +inline bool object::iterator::operator==(const object::iterator& other) const noexcept { + return tape.json_index == other.tape.json_index; +} +inline bool object::iterator::operator<(const object::iterator& other) const noexcept { + return tape.json_index < other.tape.json_index; +} +inline bool object::iterator::operator<=(const object::iterator& other) const noexcept { + return tape.json_index <= other.tape.json_index; +} +inline bool object::iterator::operator>=(const object::iterator& other) const noexcept { + return tape.json_index >= other.tape.json_index; +} +inline bool object::iterator::operator>(const object::iterator& other) const noexcept { + return tape.json_index > other.tape.json_index; +} +inline object::iterator& object::iterator::operator++() noexcept { + tape.json_index++; + tape.json_index = tape.after_element(); + return *this; +} +inline object::iterator object::iterator::operator++(int) noexcept { + object::iterator out = *this; + ++*this; + return out; +} +inline std::string_view object::iterator::key() const noexcept { + return tape.get_string_view(); +} +inline uint32_t object::iterator::key_length() const noexcept { + return tape.get_string_length(); +} +inline const char* object::iterator::key_c_str() const noexcept { + return reinterpret_cast(&tape.doc->string_buf[size_t(tape.tape_value()) + sizeof(uint32_t)]); +} +inline element object::iterator::value() const noexcept { + return element(internal::tape_ref(tape.doc, tape.json_index + 1)); +} + +/** + * Design notes: + * Instead of constructing a string_view and then comparing it with a + * user-provided strings, it is probably more performant to have dedicated + * functions taking as a parameter the string we want to compare against + * and return true when they are equal. That avoids the creation of a temporary + * std::string_view. Though it is possible for the compiler to avoid entirely + * any overhead due to string_view, relying too much on compiler magic is + * problematic: compiler magic sometimes fail, and then what do you do? + * Also, enticing users to rely on high-performance function is probably better + * on the long run. + */ + +inline bool object::iterator::key_equals(std::string_view o) const noexcept { + // We use the fact that the key length can be computed quickly + // without access to the string buffer. + const uint32_t len = key_length(); + if(o.size() == len) { + // We avoid construction of a temporary string_view instance. + return (memcmp(o.data(), key_c_str(), len) == 0); + } + return false; +} + +inline bool object::iterator::key_equals_case_insensitive(std::string_view o) const noexcept { + // We use the fact that the key length can be computed quickly + // without access to the string buffer. + const uint32_t len = key_length(); + if(o.size() == len) { + // See For case-insensitive string comparisons, avoid char-by-char functions + // https://lemire.me/blog/2020/04/30/for-case-insensitive-string-comparisons-avoid-char-by-char-functions/ + // Note that it might be worth rolling our own strncasecmp function, with vectorization. + return (simdjson_strncasecmp(o.data(), key_c_str(), len) == 0); + } + return false; +} +// +// key_value_pair inline implementation +// +inline key_value_pair::key_value_pair(std::string_view _key, element _value) noexcept : + key(_key), value(_value) {} + +} // namespace dom + +} // namespace simdjson + +#if defined(__cpp_lib_ranges) +static_assert(std::ranges::view); +static_assert(std::ranges::sized_range); +#if SIMDJSON_EXCEPTIONS +static_assert(std::ranges::view>); +static_assert(std::ranges::sized_range>); +#endif // SIMDJSON_EXCEPTIONS +#endif // defined(__cpp_lib_ranges) + +#endif // SIMDJSON_OBJECT_INL_H +/* end file simdjson/dom/object-inl.h */ +/* skipped duplicate #include "simdjson/error-inl.h" */ + +#include +#include + +namespace simdjson { + +// +// simdjson_result inline implementation +// +simdjson_inline simdjson_result::simdjson_result() noexcept + : internal::simdjson_result_base() {} +simdjson_inline simdjson_result::simdjson_result(dom::element &&value) noexcept + : internal::simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : internal::simdjson_result_base(error) {} +inline simdjson_result simdjson_result::type() const noexcept { + if (error()) { return error(); } + return first.type(); +} + +template +simdjson_inline bool simdjson_result::is() const noexcept { + return !error() && first.is(); +} +template +simdjson_inline simdjson_result simdjson_result::get() const noexcept { + if (error()) { return error(); } + return first.get(); +} +template +simdjson_warn_unused simdjson_inline error_code simdjson_result::get(T &value) const noexcept { + if (error()) { return error(); } + return first.get(value); +} + +simdjson_inline simdjson_result simdjson_result::get_array() const noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() const noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_c_str() const noexcept { + if (error()) { return error(); } + return first.get_c_str(); +} +simdjson_inline simdjson_result simdjson_result::get_string_length() const noexcept { + if (error()) { return error(); } + return first.get_string_length(); +} +simdjson_inline simdjson_result simdjson_result::get_string() const noexcept { + if (error()) { return error(); } + return first.get_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() const noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() const noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_double() const noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() const noexcept { + if (error()) { return error(); } + return first.get_bool(); +} + +simdjson_inline bool simdjson_result::is_array() const noexcept { + return !error() && first.is_array(); +} +simdjson_inline bool simdjson_result::is_object() const noexcept { + return !error() && first.is_object(); +} +simdjson_inline bool simdjson_result::is_string() const noexcept { + return !error() && first.is_string(); +} +simdjson_inline bool simdjson_result::is_int64() const noexcept { + return !error() && first.is_int64(); +} +simdjson_inline bool simdjson_result::is_uint64() const noexcept { + return !error() && first.is_uint64(); +} +simdjson_inline bool simdjson_result::is_double() const noexcept { + return !error() && first.is_double(); +} +simdjson_inline bool simdjson_result::is_number() const noexcept { + return !error() && first.is_number(); +} +simdjson_inline bool simdjson_result::is_bool() const noexcept { + return !error() && first.is_bool(); +} + +simdjson_inline bool simdjson_result::is_null() const noexcept { + return !error() && first.is_null(); +} + +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) const noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) const noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::at_pointer(const std::string_view json_pointer) const noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} +#ifndef SIMDJSON_DISABLE_DEPRECATED_API +[[deprecated("For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]] +simdjson_inline simdjson_result simdjson_result::at(const std::string_view json_pointer) const noexcept { +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_DEPRECATED_WARNING + if (error()) { return error(); } + return first.at(json_pointer); +SIMDJSON_POP_DISABLE_WARNINGS +} +#endif // SIMDJSON_DISABLE_DEPRECATED_API +simdjson_inline simdjson_result simdjson_result::at(size_t index) const noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline simdjson_result simdjson_result::at_key(std::string_view key) const noexcept { + if (error()) { return error(); } + return first.at_key(key); +} +simdjson_inline simdjson_result simdjson_result::at_key_case_insensitive(std::string_view key) const noexcept { + if (error()) { return error(); } + return first.at_key_case_insensitive(key); +} + +#if SIMDJSON_EXCEPTIONS + +simdjson_inline simdjson_result::operator bool() const noexcept(false) { + return get(); +} +simdjson_inline simdjson_result::operator const char *() const noexcept(false) { + return get(); +} +simdjson_inline simdjson_result::operator std::string_view() const noexcept(false) { + return get(); +} +simdjson_inline simdjson_result::operator uint64_t() const noexcept(false) { + return get(); +} +simdjson_inline simdjson_result::operator int64_t() const noexcept(false) { + return get(); +} +simdjson_inline simdjson_result::operator double() const noexcept(false) { + return get(); +} +simdjson_inline simdjson_result::operator dom::array() const noexcept(false) { + return get(); +} +simdjson_inline simdjson_result::operator dom::object() const noexcept(false) { + return get(); +} + +simdjson_inline dom::array::iterator simdjson_result::begin() const noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first.begin(); +} +simdjson_inline dom::array::iterator simdjson_result::end() const noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first.end(); +} + +#endif // SIMDJSON_EXCEPTIONS + +namespace dom { + +// +// element inline implementation +// +simdjson_inline element::element() noexcept : tape{} {} +simdjson_inline element::element(const internal::tape_ref &_tape) noexcept : tape{_tape} { } + +inline element_type element::type() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + auto tape_type = tape.tape_ref_type(); + return tape_type == internal::tape_type::FALSE_VALUE ? element_type::BOOL : static_cast(tape_type); +} + +inline simdjson_result element::get_bool() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + if(tape.is_true()) { + return true; + } else if(tape.is_false()) { + return false; + } + return INCORRECT_TYPE; +} +inline simdjson_result element::get_c_str() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + switch (tape.tape_ref_type()) { + case internal::tape_type::STRING: { + return tape.get_c_str(); + } + default: + return INCORRECT_TYPE; + } +} +inline simdjson_result element::get_string_length() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + switch (tape.tape_ref_type()) { + case internal::tape_type::STRING: { + return tape.get_string_length(); + } + default: + return INCORRECT_TYPE; + } +} +inline simdjson_result element::get_string() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + switch (tape.tape_ref_type()) { + case internal::tape_type::STRING: + return tape.get_string_view(); + default: + return INCORRECT_TYPE; + } +} +inline simdjson_result element::get_uint64() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + if(simdjson_unlikely(!tape.is_uint64())) { // branch rarely taken + if(tape.is_int64()) { + int64_t result = tape.next_tape_value(); + if (result < 0) { + return NUMBER_OUT_OF_RANGE; + } + return uint64_t(result); + } + return INCORRECT_TYPE; + } + return tape.next_tape_value(); +} +inline simdjson_result element::get_int64() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + if(simdjson_unlikely(!tape.is_int64())) { // branch rarely taken + if(tape.is_uint64()) { + uint64_t result = tape.next_tape_value(); + // Wrapping max in parens to handle Windows issue: https://stackoverflow.com/questions/11544073/how-do-i-deal-with-the-max-macro-in-windows-h-colliding-with-max-in-std + if (result > uint64_t((std::numeric_limits::max)())) { + return NUMBER_OUT_OF_RANGE; + } + return static_cast(result); + } + return INCORRECT_TYPE; + } + return tape.next_tape_value(); +} +inline simdjson_result element::get_double() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + // Performance considerations: + // 1. Querying tape_ref_type() implies doing a shift, it is fast to just do a straight + // comparison. + // 2. Using a switch-case relies on the compiler guessing what kind of code generation + // we want... But the compiler cannot know that we expect the type to be "double" + // most of the time. + // We can expect get to refer to a double type almost all the time. + // It is important to craft the code accordingly so that the compiler can use this + // information. (This could also be solved with profile-guided optimization.) + if(simdjson_unlikely(!tape.is_double())) { // branch rarely taken + if(tape.is_uint64()) { + return double(tape.next_tape_value()); + } else if(tape.is_int64()) { + return double(tape.next_tape_value()); + } + return INCORRECT_TYPE; + } + // this is common: + return tape.next_tape_value(); +} +inline simdjson_result element::get_array() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + switch (tape.tape_ref_type()) { + case internal::tape_type::START_ARRAY: + return array(tape); + default: + return INCORRECT_TYPE; + } +} +inline simdjson_result element::get_object() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + switch (tape.tape_ref_type()) { + case internal::tape_type::START_OBJECT: + return object(tape); + default: + return INCORRECT_TYPE; + } +} + +template +simdjson_warn_unused simdjson_inline error_code element::get(T &value) const noexcept { + return get().get(value); +} +// An element-specific version prevents recursion with simdjson_result::get(value) +template<> +simdjson_warn_unused simdjson_inline error_code element::get(element &value) const noexcept { + value = element(tape); + return SUCCESS; +} +template +inline void element::tie(T &value, error_code &error) && noexcept { + error = get(value); +} + +template +simdjson_inline bool element::is() const noexcept { + auto result = get(); + return !result.error(); +} + +template<> inline simdjson_result element::get() const noexcept { return get_array(); } +template<> inline simdjson_result element::get() const noexcept { return get_object(); } +template<> inline simdjson_result element::get() const noexcept { return get_c_str(); } +template<> inline simdjson_result element::get() const noexcept { return get_string(); } +template<> inline simdjson_result element::get() const noexcept { return get_int64(); } +template<> inline simdjson_result element::get() const noexcept { return get_uint64(); } +template<> inline simdjson_result element::get() const noexcept { return get_double(); } +template<> inline simdjson_result element::get() const noexcept { return get_bool(); } + +inline bool element::is_array() const noexcept { return is(); } +inline bool element::is_object() const noexcept { return is(); } +inline bool element::is_string() const noexcept { return is(); } +inline bool element::is_int64() const noexcept { return is(); } +inline bool element::is_uint64() const noexcept { return is(); } +inline bool element::is_double() const noexcept { return is(); } +inline bool element::is_bool() const noexcept { return is(); } +inline bool element::is_number() const noexcept { return is_int64() || is_uint64() || is_double(); } + +inline bool element::is_null() const noexcept { + return tape.is_null_on_tape(); +} + +#if SIMDJSON_EXCEPTIONS + +inline element::operator bool() const noexcept(false) { return get(); } +inline element::operator const char*() const noexcept(false) { return get(); } +inline element::operator std::string_view() const noexcept(false) { return get(); } +inline element::operator uint64_t() const noexcept(false) { return get(); } +inline element::operator int64_t() const noexcept(false) { return get(); } +inline element::operator double() const noexcept(false) { return get(); } +inline element::operator array() const noexcept(false) { return get(); } +inline element::operator object() const noexcept(false) { return get(); } + +inline array::iterator element::begin() const noexcept(false) { + return get().begin(); +} +inline array::iterator element::end() const noexcept(false) { + return get().end(); +} + +#endif // SIMDJSON_EXCEPTIONS + +inline simdjson_result element::operator[](std::string_view key) const noexcept { + return at_key(key); +} +inline simdjson_result element::operator[](const char *key) const noexcept { + return at_key(key); +} + +inline simdjson_result element::at_pointer(std::string_view json_pointer) const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + switch (tape.tape_ref_type()) { + case internal::tape_type::START_OBJECT: + return object(tape).at_pointer(json_pointer); + case internal::tape_type::START_ARRAY: + return array(tape).at_pointer(json_pointer); + default: { + if(!json_pointer.empty()) { // a non-empty string is invalid on an atom + return INVALID_JSON_POINTER; + } + // an empty string means that we return the current node + dom::element copy(*this); + return simdjson_result(std::move(copy)); + } + } +} +#ifndef SIMDJSON_DISABLE_DEPRECATED_API +[[deprecated("For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]] +inline simdjson_result element::at(std::string_view json_pointer) const noexcept { + // version 0.4 of simdjson allowed non-compliant pointers + auto std_pointer = (json_pointer.empty() ? "" : "/") + std::string(json_pointer.begin(), json_pointer.end()); + return at_pointer(std_pointer); +} +#endif // SIMDJSON_DISABLE_DEPRECATED_API + +inline simdjson_result element::at(size_t index) const noexcept { + return get().at(index); +} +inline simdjson_result element::at_key(std::string_view key) const noexcept { + return get().at_key(key); +} +inline simdjson_result element::at_key_case_insensitive(std::string_view key) const noexcept { + return get().at_key_case_insensitive(key); +} +inline bool element::operator<(const element &other) const noexcept { + return tape.json_index < other.tape.json_index; +} +inline bool element::operator==(const element &other) const noexcept { + return tape.json_index == other.tape.json_index; +} + +inline bool element::dump_raw_tape(std::ostream &out) const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + return tape.doc->dump_raw_tape(out); +} + + +inline std::ostream& operator<<(std::ostream& out, element_type type) { + switch (type) { + case element_type::ARRAY: + return out << "array"; + case element_type::OBJECT: + return out << "object"; + case element_type::INT64: + return out << "int64_t"; + case element_type::UINT64: + return out << "uint64_t"; + case element_type::DOUBLE: + return out << "double"; + case element_type::STRING: + return out << "string"; + case element_type::BOOL: + return out << "bool"; + case element_type::NULL_VALUE: + return out << "null"; + default: + return out << "unexpected content!!!"; // abort() usage is forbidden in the library + } +} + +} // namespace dom + +} // namespace simdjson + +#endif // SIMDJSON_ELEMENT_INL_H +/* end file simdjson/dom/element-inl.h */ +/* skipped duplicate #include "simdjson/dom/parser-inl.h" */ +/* skipped duplicate #include "simdjson/error-inl.h" */ +/* skipped duplicate #include "simdjson/internal/dom_parser_implementation.h" */ + +namespace simdjson { +namespace dom { + +#ifdef SIMDJSON_THREADS_ENABLED + +inline void stage1_worker::finish() { + // After calling "run" someone would call finish() to wait + // for the end of the processing. + // This function will wait until either the thread has done + // the processing or, else, the destructor has been called. + std::unique_lock lock(locking_mutex); + cond_var.wait(lock, [this]{return has_work == false;}); +} + +inline stage1_worker::~stage1_worker() { + // The thread may never outlive the stage1_worker instance + // and will always be stopped/joined before the stage1_worker + // instance is gone. + stop_thread(); +} + +inline void stage1_worker::start_thread() { + std::unique_lock lock(locking_mutex); + if(thread.joinable()) { + return; // This should never happen but we never want to create more than one thread. + } + thread = std::thread([this]{ + while(true) { + std::unique_lock thread_lock(locking_mutex); + // We wait for either "run" or "stop_thread" to be called. + cond_var.wait(thread_lock, [this]{return has_work || !can_work;}); + // If, for some reason, the stop_thread() method was called (i.e., the + // destructor of stage1_worker is called, then we want to immediately destroy + // the thread (and not do any more processing). + if(!can_work) { + break; + } + this->owner->stage1_thread_error = this->owner->run_stage1(*this->stage1_thread_parser, + this->_next_batch_start); + this->has_work = false; + // The condition variable call should be moved after thread_lock.unlock() for performance + // reasons but thread sanitizers may report it as a data race if we do. + // See https://stackoverflow.com/questions/35775501/c-should-condition-variable-be-notified-under-lock + cond_var.notify_one(); // will notify "finish" + thread_lock.unlock(); + } + } + ); +} + + +inline void stage1_worker::stop_thread() { + std::unique_lock lock(locking_mutex); + // We have to make sure that all locks can be released. + can_work = false; + has_work = false; + cond_var.notify_all(); + lock.unlock(); + if(thread.joinable()) { + thread.join(); + } +} + +inline void stage1_worker::run(document_stream * ds, dom::parser * stage1, size_t next_batch_start) { + std::unique_lock lock(locking_mutex); + owner = ds; + _next_batch_start = next_batch_start; + stage1_thread_parser = stage1; + has_work = true; + // The condition variable call should be moved after thread_lock.unlock() for performance + // reasons but thread sanitizers may report it as a data race if we do. + // See https://stackoverflow.com/questions/35775501/c-should-condition-variable-be-notified-under-lock + cond_var.notify_one(); // will notify the thread lock that we have work + lock.unlock(); +} +#endif + +simdjson_inline document_stream::document_stream( + dom::parser &_parser, + const uint8_t *_buf, + size_t _len, + size_t _batch_size +) noexcept + : parser{&_parser}, + buf{_buf}, + len{_len}, + batch_size{_batch_size <= MINIMAL_BATCH_SIZE ? MINIMAL_BATCH_SIZE : _batch_size}, + error{SUCCESS} +#ifdef SIMDJSON_THREADS_ENABLED + , use_thread(_parser.threaded) // we need to make a copy because _parser.threaded can change +#endif +{ +#ifdef SIMDJSON_THREADS_ENABLED + if(worker.get() == nullptr) { + error = MEMALLOC; + } +#endif +} + +simdjson_inline document_stream::document_stream() noexcept + : parser{nullptr}, + buf{nullptr}, + len{0}, + batch_size{0}, + error{UNINITIALIZED} +#ifdef SIMDJSON_THREADS_ENABLED + , use_thread(false) +#endif +{ +} + +simdjson_inline document_stream::~document_stream() noexcept { +#ifdef SIMDJSON_THREADS_ENABLED + worker.reset(); +#endif +} + +simdjson_inline document_stream::iterator::iterator() noexcept + : stream{nullptr}, finished{true} { +} + +simdjson_inline document_stream::iterator document_stream::begin() noexcept { + start(); + // If there are no documents, we're finished. + return iterator(this, error == EMPTY); +} + +simdjson_inline document_stream::iterator document_stream::end() noexcept { + return iterator(this, true); +} + +simdjson_inline document_stream::iterator::iterator(document_stream* _stream, bool is_end) noexcept + : stream{_stream}, finished{is_end} { +} + +simdjson_inline document_stream::iterator::reference document_stream::iterator::operator*() noexcept { + // Note that in case of error, we do not yet mark + // the iterator as "finished": this detection is done + // in the operator++ function since it is possible + // to call operator++ repeatedly while omitting + // calls to operator*. + if (stream->error) { return stream->error; } + return stream->parser->doc.root(); +} + +simdjson_inline document_stream::iterator& document_stream::iterator::operator++() noexcept { + // If there is an error, then we want the iterator + // to be finished, no matter what. (E.g., we do not + // keep generating documents with errors, or go beyond + // a document with errors.) + // + // Users do not have to call "operator*()" when they use operator++, + // so we need to end the stream in the operator++ function. + // + // Note that setting finished = true is essential otherwise + // we would enter an infinite loop. + if (stream->error) { finished = true; } + // Note that stream->error() is guarded against error conditions + // (it will immediately return if stream->error casts to false). + // In effect, this next function does nothing when (stream->error) + // is true (hence the risk of an infinite loop). + stream->next(); + // If that was the last document, we're finished. + // It is the only type of error we do not want to appear + // in operator*. + if (stream->error == EMPTY) { finished = true; } + // If we had any other kind of error (not EMPTY) then we want + // to pass it along to the operator* and we cannot mark the result + // as "finished" just yet. + return *this; +} + +simdjson_inline bool document_stream::iterator::operator!=(const document_stream::iterator &other) const noexcept { + return finished != other.finished; +} + +inline void document_stream::start() noexcept { + if (error) { return; } + error = parser->ensure_capacity(batch_size); + if (error) { return; } + // Always run the first stage 1 parse immediately + batch_start = 0; + error = run_stage1(*parser, batch_start); + while(error == EMPTY) { + // In exceptional cases, we may start with an empty block + batch_start = next_batch_start(); + if (batch_start >= len) { return; } + error = run_stage1(*parser, batch_start); + } + if (error) { return; } +#ifdef SIMDJSON_THREADS_ENABLED + if (use_thread && next_batch_start() < len) { + // Kick off the first thread if needed + error = stage1_thread_parser.ensure_capacity(batch_size); + if (error) { return; } + worker->start_thread(); + start_stage1_thread(); + if (error) { return; } + } +#endif // SIMDJSON_THREADS_ENABLED + next(); +} + +simdjson_inline size_t document_stream::iterator::current_index() const noexcept { + return stream->doc_index; +} + +simdjson_inline std::string_view document_stream::iterator::source() const noexcept { + const char* start = reinterpret_cast(stream->buf) + current_index(); + bool object_or_array = ((*start == '[') || (*start == '{')); + if(object_or_array) { + size_t next_doc_index = stream->batch_start + stream->parser->implementation->structural_indexes[stream->parser->implementation->next_structural_index - 1]; + return std::string_view(start, next_doc_index - current_index() + 1); + } else { + size_t next_doc_index = stream->batch_start + stream->parser->implementation->structural_indexes[stream->parser->implementation->next_structural_index]; + return std::string_view(reinterpret_cast(stream->buf) + current_index(), next_doc_index - current_index() - 1); + } +} + + +inline void document_stream::next() noexcept { + // We always exit at once, once in an error condition. + if (error) { return; } + + // Load the next document from the batch + doc_index = batch_start + parser->implementation->structural_indexes[parser->implementation->next_structural_index]; + error = parser->implementation->stage2_next(parser->doc); + // If that was the last document in the batch, load another batch (if available) + while (error == EMPTY) { + batch_start = next_batch_start(); + if (batch_start >= len) { break; } + +#ifdef SIMDJSON_THREADS_ENABLED + if(use_thread) { + load_from_stage1_thread(); + } else { + error = run_stage1(*parser, batch_start); + } +#else + error = run_stage1(*parser, batch_start); +#endif + if (error) { continue; } // If the error was EMPTY, we may want to load another batch. + // Run stage 2 on the first document in the batch + doc_index = batch_start + parser->implementation->structural_indexes[parser->implementation->next_structural_index]; + error = parser->implementation->stage2_next(parser->doc); + } +} +inline size_t document_stream::size_in_bytes() const noexcept { + return len; +} + +inline size_t document_stream::truncated_bytes() const noexcept { + if(error == CAPACITY) { return len - batch_start; } + return parser->implementation->structural_indexes[parser->implementation->n_structural_indexes] - parser->implementation->structural_indexes[parser->implementation->n_structural_indexes + 1]; +} + +inline size_t document_stream::next_batch_start() const noexcept { + return batch_start + parser->implementation->structural_indexes[parser->implementation->n_structural_indexes]; +} + +inline error_code document_stream::run_stage1(dom::parser &p, size_t _batch_start) noexcept { + size_t remaining = len - _batch_start; + if (remaining <= batch_size) { + return p.implementation->stage1(&buf[_batch_start], remaining, stage1_mode::streaming_final); + } else { + return p.implementation->stage1(&buf[_batch_start], batch_size, stage1_mode::streaming_partial); + } +} + +#ifdef SIMDJSON_THREADS_ENABLED + +inline void document_stream::load_from_stage1_thread() noexcept { + worker->finish(); + // Swap to the parser that was loaded up in the thread. Make sure the parser has + // enough memory to swap to, as well. + std::swap(*parser, stage1_thread_parser); + error = stage1_thread_error; + if (error) { return; } + + // If there's anything left, start the stage 1 thread! + if (next_batch_start() < len) { + start_stage1_thread(); + } +} + +inline void document_stream::start_stage1_thread() noexcept { + // we call the thread on a lambda that will update + // this->stage1_thread_error + // there is only one thread that may write to this value + // TODO this is NOT exception-safe. + this->stage1_thread_error = UNINITIALIZED; // In case something goes wrong, make sure it's an error + size_t _next_batch_start = this->next_batch_start(); + + worker->run(this, & this->stage1_thread_parser, _next_batch_start); +} + +#endif // SIMDJSON_THREADS_ENABLED + +} // namespace dom + +simdjson_inline simdjson_result::simdjson_result() noexcept + : simdjson_result_base() { +} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : simdjson_result_base(error) { +} +simdjson_inline simdjson_result::simdjson_result(dom::document_stream &&value) noexcept + : simdjson_result_base(std::forward(value)) { +} + +#if SIMDJSON_EXCEPTIONS +simdjson_inline dom::document_stream::iterator simdjson_result::begin() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first.begin(); +} +simdjson_inline dom::document_stream::iterator simdjson_result::end() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first.end(); +} +#else // SIMDJSON_EXCEPTIONS +#ifndef SIMDJSON_DISABLE_DEPRECATED_API +simdjson_inline dom::document_stream::iterator simdjson_result::begin() noexcept { + first.error = error(); + return first.begin(); +} +simdjson_inline dom::document_stream::iterator simdjson_result::end() noexcept { + first.error = error(); + return first.end(); +} +#endif // SIMDJSON_DISABLE_DEPRECATED_API +#endif // SIMDJSON_EXCEPTIONS + +} // namespace simdjson +#endif // SIMDJSON_DOCUMENT_STREAM_INL_H +/* end file simdjson/dom/document_stream-inl.h */ +/* skipped duplicate #include "simdjson/dom/element-inl.h" */ + +#include +#include /* memcmp */ + +namespace simdjson { +namespace dom { + +// +// parser inline implementation +// +simdjson_inline parser::parser(size_t max_capacity) noexcept + : _max_capacity{max_capacity}, + loaded_bytes(nullptr) { +} +simdjson_inline parser::parser(parser &&other) noexcept = default; +simdjson_inline parser &parser::operator=(parser &&other) noexcept = default; + +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(error); } + +inline bool parser::dump_raw_tape(std::ostream &os) const noexcept { + return valid ? doc.dump_raw_tape(os) : false; +} + +inline simdjson_result parser::read_file(const std::string &path) noexcept { + // Open the file + SIMDJSON_PUSH_DISABLE_WARNINGS + SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe + std::FILE *fp = std::fopen(path.c_str(), "rb"); + SIMDJSON_POP_DISABLE_WARNINGS + + if (fp == nullptr) { + return IO_ERROR; + } + + // Get the file size + int ret; +#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS + ret = _fseeki64(fp, 0, SEEK_END); +#else + ret = std::fseek(fp, 0, SEEK_END); +#endif // _WIN64 + if(ret < 0) { + std::fclose(fp); + return IO_ERROR; + } +#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS + __int64 len = _ftelli64(fp); + if(len == -1L) { + std::fclose(fp); + return IO_ERROR; + } +#else + long len = std::ftell(fp); + if((len < 0) || (len == LONG_MAX)) { + std::fclose(fp); + return IO_ERROR; + } +#endif + + // Make sure we have enough capacity to load the file + if (_loaded_bytes_capacity < size_t(len)) { + loaded_bytes.reset( internal::allocate_padded_buffer(len) ); + if (!loaded_bytes) { + std::fclose(fp); + return MEMALLOC; + } + _loaded_bytes_capacity = len; + } + + // Read the string + std::rewind(fp); + size_t bytes_read = std::fread(loaded_bytes.get(), 1, len, fp); + if (std::fclose(fp) != 0 || bytes_read != size_t(len)) { + return IO_ERROR; + } + + return bytes_read; +} + +inline simdjson_result parser::load(const std::string &path) & noexcept { + size_t len; + auto _error = read_file(path).get(len); + if (_error) { return _error; } + return parse(loaded_bytes.get(), len, false); +} + +inline simdjson_result parser::load_many(const std::string &path, size_t batch_size) noexcept { + size_t len; + auto _error = read_file(path).get(len); + if (_error) { return _error; } + if(batch_size < MINIMAL_BATCH_SIZE) { batch_size = MINIMAL_BATCH_SIZE; } + return document_stream(*this, reinterpret_cast(loaded_bytes.get()), len, batch_size); +} + +inline simdjson_result parser::parse_into_document(document& provided_doc, const uint8_t *buf, size_t len, bool realloc_if_needed) & noexcept { + // Important: we need to ensure that document has enough capacity. + // Important: It is possible that provided_doc is actually the internal 'doc' within the parser!!! + error_code _error = ensure_capacity(provided_doc, len); + if (_error) { return _error; } + if (realloc_if_needed) { + // Make sure we have enough capacity to copy len bytes + if (!loaded_bytes || _loaded_bytes_capacity < len) { + loaded_bytes.reset( internal::allocate_padded_buffer(len) ); + if (!loaded_bytes) { + return MEMALLOC; + } + _loaded_bytes_capacity = len; + } + std::memcpy(static_cast(loaded_bytes.get()), buf, len); + buf = reinterpret_cast(loaded_bytes.get()); + } + + if((len >= 3) && (std::memcmp(buf, "\xEF\xBB\xBF", 3) == 0)) { + buf += 3; + len -= 3; + } + _error = implementation->parse(buf, len, provided_doc); + + if (_error) { return _error; } + + return provided_doc.root(); +} + +simdjson_inline simdjson_result parser::parse_into_document(document& provided_doc, const char *buf, size_t len, bool realloc_if_needed) & noexcept { + return parse_into_document(provided_doc, reinterpret_cast(buf), len, realloc_if_needed); +} +simdjson_inline simdjson_result parser::parse_into_document(document& provided_doc, const std::string &s) & noexcept { + return parse_into_document(provided_doc, s.data(), s.length(), s.capacity() - s.length() < SIMDJSON_PADDING); +} +simdjson_inline simdjson_result parser::parse_into_document(document& provided_doc, const padded_string &s) & noexcept { + return parse_into_document(provided_doc, s.data(), s.length(), false); +} + + +inline simdjson_result parser::parse(const uint8_t *buf, size_t len, bool realloc_if_needed) & noexcept { + return parse_into_document(doc, buf, len, realloc_if_needed); +} + +simdjson_inline simdjson_result parser::parse(const char *buf, size_t len, bool realloc_if_needed) & noexcept { + return parse(reinterpret_cast(buf), len, realloc_if_needed); +} +simdjson_inline simdjson_result parser::parse(const std::string &s) & noexcept { + return parse(s.data(), s.length(), s.capacity() - s.length() < SIMDJSON_PADDING); +} +simdjson_inline simdjson_result parser::parse(const padded_string &s) & noexcept { + return parse(s.data(), s.length(), false); +} +simdjson_inline simdjson_result parser::parse(const padded_string_view &v) & noexcept { + return parse(v.data(), v.length(), false); +} + +inline simdjson_result parser::parse_many(const uint8_t *buf, size_t len, size_t batch_size) noexcept { + if(batch_size < MINIMAL_BATCH_SIZE) { batch_size = MINIMAL_BATCH_SIZE; } + if((len >= 3) && (std::memcmp(buf, "\xEF\xBB\xBF", 3) == 0)) { + buf += 3; + len -= 3; + } + return document_stream(*this, buf, len, batch_size); +} +inline simdjson_result parser::parse_many(const char *buf, size_t len, size_t batch_size) noexcept { + return parse_many(reinterpret_cast(buf), len, batch_size); +} +inline simdjson_result parser::parse_many(const std::string &s, size_t batch_size) noexcept { + return parse_many(s.data(), s.length(), batch_size); +} +inline simdjson_result parser::parse_many(const padded_string &s, size_t batch_size) noexcept { + return parse_many(s.data(), s.length(), batch_size); +} + +simdjson_inline size_t parser::capacity() const noexcept { + return implementation ? implementation->capacity() : 0; +} +simdjson_inline size_t parser::max_capacity() const noexcept { + return _max_capacity; +} +simdjson_inline size_t parser::max_depth() const noexcept { + return implementation ? implementation->max_depth() : DEFAULT_MAX_DEPTH; +} + +simdjson_warn_unused +inline error_code parser::allocate(size_t capacity, size_t max_depth) noexcept { + // + // Reallocate implementation if needed + // + error_code err; + if (implementation) { + err = implementation->allocate(capacity, max_depth); + } else { + err = simdjson::get_active_implementation()->create_dom_parser_implementation(capacity, max_depth, implementation); + } + if (err) { return err; } + return SUCCESS; +} + +#ifndef SIMDJSON_DISABLE_DEPRECATED_API +simdjson_warn_unused +inline bool parser::allocate_capacity(size_t capacity, size_t max_depth) noexcept { + return !allocate(capacity, max_depth); +} +#endif // SIMDJSON_DISABLE_DEPRECATED_API + +inline error_code parser::ensure_capacity(size_t desired_capacity) noexcept { + return ensure_capacity(doc, desired_capacity); +} + + +inline error_code parser::ensure_capacity(document& target_document, size_t desired_capacity) noexcept { + // 1. It is wasteful to allocate a document and a parser for documents spanning less than MINIMAL_DOCUMENT_CAPACITY bytes. + // 2. If we allow desired_capacity = 0 then it is possible to exit this function with implementation == nullptr. + if(desired_capacity < MINIMAL_DOCUMENT_CAPACITY) { desired_capacity = MINIMAL_DOCUMENT_CAPACITY; } + // If we don't have enough capacity, (try to) automatically bump it. + // If the document needs allocation, do it too. + // Both in one if statement to minimize unlikely branching. + // + // Note: we must make sure that this function is called if capacity() == 0. We do so because we + // ensure that desired_capacity > 0. + if (simdjson_unlikely(capacity() < desired_capacity || target_document.capacity() < desired_capacity)) { + if (desired_capacity > max_capacity()) { + return error = CAPACITY; + } + error_code err1 = target_document.capacity() < desired_capacity ? target_document.allocate(desired_capacity) : SUCCESS; + error_code err2 = capacity() < desired_capacity ? allocate(desired_capacity, max_depth()) : SUCCESS; + if(err1 != SUCCESS) { return error = err1; } + if(err2 != SUCCESS) { return error = err2; } + } + return SUCCESS; +} + +simdjson_inline void parser::set_max_capacity(size_t max_capacity) noexcept { + if(max_capacity > MINIMAL_DOCUMENT_CAPACITY) { + _max_capacity = max_capacity; + } else { + _max_capacity = MINIMAL_DOCUMENT_CAPACITY; + } +} + +} // namespace dom +} // namespace simdjson + +#endif // SIMDJSON_PARSER_INL_H +/* end file simdjson/dom/parser-inl.h */ + +namespace simdjson { + +// +// C API (json_parse and build_parsed_json) declarations +// + +#ifndef SIMDJSON_DISABLE_DEPRECATED_API +[[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 + // anticipation of making the error code ephemeral. + // Here we put the code back into the parser, until we've removed this method. + parser.valid = code == SUCCESS; + parser.error = code; + return code; +} +[[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 + // anticipation of making the error code ephemeral. + // Here we put the code back into the parser, until we've removed this method. + parser.valid = code == SUCCESS; + parser.error = code; + return code; +} +[[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 + // anticipation of making the error code ephemeral. + // Here we put the code back into the parser, until we've removed this method. + parser.valid = code == SUCCESS; + parser.error = code; + return code; +} +[[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 + // anticipation of making the error code ephemeral. + // Here we put the code back into the parser, until we've removed this method. + parser.valid = code == SUCCESS; + parser.error = code; + return code; +} + +[[deprecated("Use parser.parse() instead")]] +simdjson_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 + // anticipation of making the error code ephemeral. + // Here we put the code back into the parser, until we've removed this method. + parser.valid = code == SUCCESS; + parser.error = code; + return parser; +} +[[deprecated("Use parser.parse() instead")]] +simdjson_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 + // anticipation of making the error code ephemeral. + // Here we put the code back into the parser, until we've removed this method. + parser.valid = code == SUCCESS; + parser.error = code; + return parser; +} +[[deprecated("Use parser.parse() instead")]] +simdjson_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 + // anticipation of making the error code ephemeral. + // Here we put the code back into the parser, until we've removed this method. + parser.valid = code == SUCCESS; + parser.error = code; + return parser; +} +[[deprecated("Use parser.parse() instead")]] +simdjson_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 + // anticipation of making the error code ephemeral. + // Here we put the code back into the parser, until we've removed this method. + parser.valid = code == SUCCESS; + parser.error = code; + return parser; +} +#endif // SIMDJSON_DISABLE_DEPRECATED_API + +/** @private We do not want to allow implicit conversion from C string to std::string. */ +int json_parse(const char *buf, dom::parser &parser) noexcept = delete; +/** @private We do not want to allow implicit conversion from C string to std::string. */ +dom::parser build_parsed_json(const char *buf) noexcept = delete; + +} // namespace simdjson + +#endif // SIMDJSON_DOM_JSONPARSER_H +/* end file simdjson/dom/jsonparser.h */ +/* including simdjson/dom/parsedjson.h: #include "simdjson/dom/parsedjson.h" */ +/* begin file simdjson/dom/parsedjson.h */ +// TODO Remove this -- deprecated API and files + +#ifndef SIMDJSON_DOM_PARSEDJSON_H +#define SIMDJSON_DOM_PARSEDJSON_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ + +namespace simdjson { + +/** + * @deprecated Use `dom::parser` instead. + */ +using ParsedJson [[deprecated("Use dom::parser instead")]] = dom::parser; + +} // namespace simdjson + +#endif // SIMDJSON_DOM_PARSEDJSON_H +/* end file simdjson/dom/parsedjson.h */ +/* including simdjson/dom/parsedjson_iterator.h: #include "simdjson/dom/parsedjson_iterator.h" */ +/* begin file simdjson/dom/parsedjson_iterator.h */ +// TODO Remove this -- deprecated API and files + +#ifndef SIMDJSON_DOM_PARSEDJSON_ITERATOR_H +#define SIMDJSON_DOM_PARSEDJSON_ITERATOR_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* skipped duplicate #include "simdjson/dom/parser.h" */ + +#ifndef SIMDJSON_DISABLE_DEPRECATED_API + +namespace simdjson { +/** @private **/ +class [[deprecated("Use the new DOM navigation API instead (see doc/basics.md)")]] dom::parser::Iterator { +public: + inline Iterator(const dom::parser &parser) noexcept(false); + inline Iterator(const Iterator &o) noexcept; + inline ~Iterator() noexcept; + + inline Iterator& operator=(const Iterator&) = delete; + + inline bool is_ok() const; + + // useful for debugging purposes + inline size_t get_tape_location() const; + + // useful for debugging purposes + inline size_t get_tape_length() const; + + // returns the current depth (start at 1 with 0 reserved for the fictitious + // root node) + inline size_t get_depth() const; + + // A scope is a series of nodes at the same depth, typically it is either an + // object ({) or an array ([). The root node has type 'r'. + inline uint8_t get_scope_type() const; + + // move forward in document order + inline bool move_forward(); + + // retrieve the character code of what we're looking at: + // [{"slutfn are the possibilities + inline uint8_t get_type() const { + return current_type; // short functions should be inlined! + } + + // get the int64_t value at this node; valid only if get_type is "l" + inline int64_t get_integer() const; + + // get the value as uint64; valid only if if get_type is "u" + inline uint64_t get_unsigned_integer() const; + + // get the string value at this node (NULL ended); valid only if get_type is " + // note that tabs, and line endings are escaped in the returned value (see + // print_with_escapes) return value is valid UTF-8, it may contain NULL chars + // within the string: get_string_length determines the true string length. + inline const char *get_string() const; + + // return the length of the string in bytes + inline uint32_t get_string_length() const; + + // get the double value at this node; valid only if + // get_type() is "d" + inline double get_double() const; + + inline bool is_object_or_array() const { return is_object() || is_array(); } + + inline bool is_object() const { return get_type() == '{'; } + + inline bool is_array() const { return get_type() == '['; } + + inline bool is_string() const { return get_type() == '"'; } + + // Returns true if the current type of the node is an signed integer. + // You can get its value with `get_integer()`. + inline bool is_integer() const { return get_type() == 'l'; } + + // Returns true if the current type of the node is an unsigned integer. + // You can get its value with `get_unsigned_integer()`. + // + // NOTE: + // Only a large value, which is out of range of a 64-bit signed integer, is + // represented internally as an unsigned node. On the other hand, a typical + // positive integer, such as 1, 42, or 1000000, is as a signed node. + // Be aware this function returns false for a signed node. + inline bool is_unsigned_integer() const { return get_type() == 'u'; } + // Returns true if the current type of the node is a double floating-point number. + inline bool is_double() const { return get_type() == 'd'; } + // Returns true if the current type of the node is a number (integer or floating-point). + inline bool is_number() const { + return is_integer() || is_unsigned_integer() || is_double(); + } + // Returns true if the current type of the node is a bool with true value. + inline bool is_true() const { return get_type() == 't'; } + // Returns true if the current type of the node is a bool with false value. + inline bool is_false() const { return get_type() == 'f'; } + // Returns true if the current type of the node is null. + inline bool is_null() const { return get_type() == 'n'; } + // Returns true if the type byte represents an object of an array + static bool is_object_or_array(uint8_t type) { + return ((type == '[') || (type == '{')); + } + + // when at {, go one level deep, looking for a given key + // if successful, we are left pointing at the value, + // if not, we are still pointing at the object ({) + // (in case of repeated keys, this only finds the first one). + // We seek the key using C's strcmp so if your JSON strings contain + // NULL chars, this would trigger a false positive: if you expect that + // to be the case, take extra precautions. + // Furthermore, we do the comparison character-by-character + // without taking into account Unicode equivalence. + inline bool move_to_key(const char *key); + + // as above, but case insensitive lookup (strcmpi instead of strcmp) + inline bool move_to_key_insensitive(const char *key); + + // when at {, go one level deep, looking for a given key + // if successful, we are left pointing at the value, + // if not, we are still pointing at the object ({) + // (in case of repeated keys, this only finds the first one). + // The string we search for can contain NULL values. + // Furthermore, we do the comparison character-by-character + // without taking into account Unicode equivalence. + inline bool move_to_key(const char *key, uint32_t length); + + // when at a key location within an object, this moves to the accompanying + // value (located next to it). This is equivalent but much faster than + // calling "next()". + inline void move_to_value(); + + // when at [, go one level deep, and advance to the given index. + // if successful, we are left pointing at the value, + // if not, we are still pointing at the array ([) + inline bool move_to_index(uint32_t index); + + // Moves the iterator to the value corresponding to the json pointer. + // Always search from the root of the document. + // if successful, we are left pointing at the value, + // if not, we are still pointing the same value we were pointing before the + // call. The json pointer follows the rfc6901 standard's syntax: + // https://tools.ietf.org/html/rfc6901 However, the standard says "If a + // referenced member name is not unique in an object, the member that is + // referenced is undefined, and evaluation fails". Here we just return the + // first corresponding value. The length parameter is the length of the + // jsonpointer string ('pointer'). + inline bool move_to(const char *pointer, uint32_t length); + + // Moves the iterator to the value corresponding to the json pointer. + // Always search from the root of the document. + // if successful, we are left pointing at the value, + // if not, we are still pointing the same value we were pointing before the + // call. The json pointer implementation follows the rfc6901 standard's + // syntax: https://tools.ietf.org/html/rfc6901 However, the standard says + // "If a referenced member name is not unique in an object, the member that + // is referenced is undefined, and evaluation fails". Here we just return + // the first corresponding value. + inline bool move_to(const std::string &pointer); + + private: + // Almost the same as move_to(), except it searches from the current + // position. The pointer's syntax is identical, though that case is not + // handled by the rfc6901 standard. The '/' is still required at the + // beginning. However, contrary to move_to(), the URI Fragment Identifier + // Representation is not supported here. Also, in case of failure, we are + // left pointing at the closest value it could reach. For these reasons it + // is private. It exists because it is used by move_to(). + inline bool relative_move_to(const char *pointer, uint32_t length); + + public: + // throughout return true if we can do the navigation, false + // otherwise + + // Within a given scope (series of nodes at the same depth within either an + // array or an object), we move forward. + // Thus, given [true, null, {"a":1}, [1,2]], we would visit true, null, { + // and [. At the object ({) or at the array ([), you can issue a "down" to + // visit their content. valid if we're not at the end of a scope (returns + // true). + inline bool next(); + + // Within a given scope (series of nodes at the same depth within either an + // array or an object), we move backward. + // Thus, given [true, null, {"a":1}, [1,2]], we would visit ], }, null, true + // when starting at the end of the scope. At the object ({) or at the array + // ([), you can issue a "down" to visit their content. + // Performance warning: This function is implemented by starting again + // from the beginning of the scope and scanning forward. You should expect + // it to be relatively slow. + inline bool prev(); + + // Moves back to either the containing array or object (type { or [) from + // within a contained scope. + // Valid unless we are at the first level of the document + inline bool up(); + + // Valid if we're at a [ or { and it starts a non-empty scope; moves us to + // start of that deeper scope if it not empty. Thus, given [true, null, + // {"a":1}, [1,2]], if we are at the { node, we would move to the "a" node. + inline bool down(); + + // move us to the start of our current scope, + // a scope is a series of nodes at the same level + inline void to_start_scope(); + + inline void rewind(); + + + + // print the node we are currently pointing at + inline bool print(std::ostream &os, bool escape_strings = true) const; + + private: + const document &doc; + size_t max_depth{}; + size_t depth{}; + size_t location{}; // our current location on a tape + size_t tape_length{}; + uint8_t current_type{}; + uint64_t current_val{}; + typedef struct { + size_t start_of_scope; + uint8_t scope_type; + } scopeindex_t; + + scopeindex_t *depth_index{}; +}; + +} // namespace simdjson +#endif // SIMDJSON_DISABLE_DEPRECATED_API + +#endif // SIMDJSON_DOM_PARSEDJSON_ITERATOR_H +/* end file simdjson/dom/parsedjson_iterator.h */ + +// Inline functions +/* including simdjson/dom/array-inl.h: #include "simdjson/dom/array-inl.h" */ +/* begin file simdjson/dom/array-inl.h */ +#ifndef SIMDJSON_ARRAY_INL_H +#define SIMDJSON_ARRAY_INL_H + +#include + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* skipped duplicate #include "simdjson/dom/array.h" */ +/* skipped duplicate #include "simdjson/dom/element.h" */ +/* skipped duplicate #include "simdjson/error-inl.h" */ +/* including simdjson/internal/tape_ref-inl.h: #include "simdjson/internal/tape_ref-inl.h" */ +/* begin file simdjson/internal/tape_ref-inl.h */ +#ifndef SIMDJSON_TAPE_REF_INL_H +#define SIMDJSON_TAPE_REF_INL_H + +/* skipped duplicate #include "simdjson/dom/document.h" */ +/* skipped duplicate #include "simdjson/internal/tape_ref.h" */ +/* skipped duplicate #include "simdjson/internal/tape_type.h" */ + +#include + +namespace simdjson { +namespace internal { + +constexpr const uint64_t JSON_VALUE_MASK = 0x00FFFFFFFFFFFFFF; +constexpr const uint32_t JSON_COUNT_MASK = 0xFFFFFF; + +// +// tape_ref inline implementation +// +simdjson_inline tape_ref::tape_ref() noexcept : doc{nullptr}, json_index{0} {} +simdjson_inline tape_ref::tape_ref(const dom::document *_doc, size_t _json_index) noexcept : doc{_doc}, json_index{_json_index} {} + + +simdjson_inline bool tape_ref::is_document_root() const noexcept { + return json_index == 1; // should we ever change the structure of the tape, this should get updated. +} +simdjson_inline bool tape_ref::usable() const noexcept { + return doc != nullptr; // when the document pointer is null, this tape_ref is uninitialized (should not be accessed). +} +// Some value types have a specific on-tape word value. It can be faster +// to check the type by doing a word-to-word comparison instead of extracting the +// most significant 8 bits. + +simdjson_inline bool tape_ref::is_double() const noexcept { + constexpr uint64_t tape_double = uint64_t(tape_type::DOUBLE)<<56; + return doc->tape[json_index] == tape_double; +} +simdjson_inline bool tape_ref::is_int64() const noexcept { + constexpr uint64_t tape_int64 = uint64_t(tape_type::INT64)<<56; + return doc->tape[json_index] == tape_int64; +} +simdjson_inline bool tape_ref::is_uint64() const noexcept { + constexpr uint64_t tape_uint64 = uint64_t(tape_type::UINT64)<<56; + return doc->tape[json_index] == tape_uint64; +} +simdjson_inline bool tape_ref::is_false() const noexcept { + constexpr uint64_t tape_false = uint64_t(tape_type::FALSE_VALUE)<<56; + return doc->tape[json_index] == tape_false; +} +simdjson_inline bool tape_ref::is_true() const noexcept { + constexpr uint64_t tape_true = uint64_t(tape_type::TRUE_VALUE)<<56; + return doc->tape[json_index] == tape_true; +} +simdjson_inline bool tape_ref::is_null_on_tape() const noexcept { + constexpr uint64_t tape_null = uint64_t(tape_type::NULL_VALUE)<<56; + return doc->tape[json_index] == tape_null; +} + +inline size_t tape_ref::after_element() const noexcept { + switch (tape_ref_type()) { + case tape_type::START_ARRAY: + case tape_type::START_OBJECT: + return matching_brace_index(); + case tape_type::UINT64: + case tape_type::INT64: + case tape_type::DOUBLE: + return json_index + 2; + default: + return json_index + 1; + } +} +simdjson_inline tape_type tape_ref::tape_ref_type() const noexcept { + return static_cast(doc->tape[json_index] >> 56); +} +simdjson_inline uint64_t internal::tape_ref::tape_value() const noexcept { + return doc->tape[json_index] & internal::JSON_VALUE_MASK; +} +simdjson_inline uint32_t internal::tape_ref::matching_brace_index() const noexcept { + return uint32_t(doc->tape[json_index]); +} +simdjson_inline uint32_t internal::tape_ref::scope_count() const noexcept { + return uint32_t((doc->tape[json_index] >> 32) & internal::JSON_COUNT_MASK); +} + +template +simdjson_inline T tape_ref::next_tape_value() const noexcept { + static_assert(sizeof(T) == sizeof(uint64_t), "next_tape_value() template parameter must be 64-bit"); + // Though the following is tempting... + // return *reinterpret_cast(&doc->tape[json_index + 1]); + // It is not generally safe. It is safer, and often faster to rely + // on memcpy. Yes, it is uglier, but it is also encapsulated. + T x; + std::memcpy(&x,&doc->tape[json_index + 1],sizeof(uint64_t)); + return x; +} + +simdjson_inline uint32_t internal::tape_ref::get_string_length() const noexcept { + size_t string_buf_index = size_t(tape_value()); + uint32_t len; + std::memcpy(&len, &doc->string_buf[string_buf_index], sizeof(len)); + return len; +} + +simdjson_inline const char * internal::tape_ref::get_c_str() const noexcept { + size_t string_buf_index = size_t(tape_value()); + return reinterpret_cast(&doc->string_buf[string_buf_index + sizeof(uint32_t)]); +} + +inline std::string_view internal::tape_ref::get_string_view() const noexcept { + return std::string_view( + get_c_str(), + get_string_length() + ); +} + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_TAPE_REF_INL_H +/* end file simdjson/internal/tape_ref-inl.h */ + +#include + +namespace simdjson { + +// +// simdjson_result inline implementation +// +simdjson_inline simdjson_result::simdjson_result() noexcept + : internal::simdjson_result_base() {} +simdjson_inline simdjson_result::simdjson_result(dom::array value) noexcept + : internal::simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : internal::simdjson_result_base(error) {} + +#if SIMDJSON_EXCEPTIONS + +inline dom::array::iterator simdjson_result::begin() const noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first.begin(); +} +inline dom::array::iterator simdjson_result::end() const noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first.end(); +} +inline size_t simdjson_result::size() const noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first.size(); +} + +#endif // SIMDJSON_EXCEPTIONS + +inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) const noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} +inline simdjson_result simdjson_result::at(size_t index) const noexcept { + if (error()) { return error(); } + return first.at(index); +} + +namespace dom { + +// +// array inline implementation +// +simdjson_inline array::array() noexcept : tape{} {} +simdjson_inline array::array(const internal::tape_ref &_tape) noexcept : tape{_tape} {} +inline array::iterator array::begin() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + return internal::tape_ref(tape.doc, tape.json_index + 1); +} +inline array::iterator array::end() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + return internal::tape_ref(tape.doc, tape.after_element() - 1); +} +inline size_t array::size() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + return tape.scope_count(); +} +inline size_t array::number_of_slots() const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + return tape.matching_brace_index() - tape.json_index; +} +inline simdjson_result array::at_pointer(std::string_view json_pointer) const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + if(json_pointer.empty()) { // an empty string means that we return the current node + return element(this->tape); // copy the current node + } else if(json_pointer[0] != '/') { // otherwise there is an error + return INVALID_JSON_POINTER; + } + json_pointer = json_pointer.substr(1); + // - 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; } + + // Read the array index + size_t array_index = 0; + size_t i; + for (i = 0; i < json_pointer.length() && json_pointer[i] != '/'; i++) { + uint8_t digit = uint8_t(json_pointer[i] - '0'); + // Check for non-digit in array index. If it's there, we're trying to get a field in an object + if (digit > 9) { return INCORRECT_TYPE; } + array_index = array_index*10 + digit; + } + + // 0 followed by other digits is invalid + if (i > 1 && json_pointer[0] == '0') { return INVALID_JSON_POINTER; } // "JSON pointer array index has other characters after 0" + + // Empty string is invalid; so is a "/" with no digits before it + if (i == 0) { return INVALID_JSON_POINTER; } // "Empty string in JSON pointer array index" + + // Get the child + auto child = array(tape).at(array_index); + // If there is an error, it ends here + if(child.error()) { + return child; + } + // If there is a /, we're not done yet, call recursively. + if (i < json_pointer.length()) { + child = child.at_pointer(json_pointer.substr(i)); + } + return child; +} + +inline simdjson_result array::at(size_t index) const noexcept { + SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 + size_t i=0; + for (auto element : *this) { + if (i == index) { return element; } + i++; + } + return INDEX_OUT_OF_BOUNDS; +} + +// +// array::iterator inline implementation +// +simdjson_inline array::iterator::iterator(const internal::tape_ref &_tape) noexcept : tape{_tape} { } +inline element array::iterator::operator*() const noexcept { + return element(tape); +} +inline array::iterator& array::iterator::operator++() noexcept { + tape.json_index = tape.after_element(); + return *this; +} +inline array::iterator array::iterator::operator++(int) noexcept { + array::iterator out = *this; + ++*this; + return out; +} +inline bool array::iterator::operator!=(const array::iterator& other) const noexcept { + return tape.json_index != other.tape.json_index; +} +inline bool array::iterator::operator==(const array::iterator& other) const noexcept { + return tape.json_index == other.tape.json_index; +} +inline bool array::iterator::operator<(const array::iterator& other) const noexcept { + return tape.json_index < other.tape.json_index; +} +inline bool array::iterator::operator<=(const array::iterator& other) const noexcept { + return tape.json_index <= other.tape.json_index; +} +inline bool array::iterator::operator>=(const array::iterator& other) const noexcept { + return tape.json_index >= other.tape.json_index; +} +inline bool array::iterator::operator>(const array::iterator& other) const noexcept { + return tape.json_index > other.tape.json_index; +} + +} // namespace dom + + +} // namespace simdjson + +/* skipped duplicate #include "simdjson/dom/element-inl.h" */ + +#if defined(__cpp_lib_ranges) +static_assert(std::ranges::view); +static_assert(std::ranges::sized_range); +#if SIMDJSON_EXCEPTIONS +static_assert(std::ranges::view>); +static_assert(std::ranges::sized_range>); +#endif // SIMDJSON_EXCEPTIONS +#endif // defined(__cpp_lib_ranges) + +#endif // SIMDJSON_ARRAY_INL_H +/* end file simdjson/dom/array-inl.h */ +/* skipped duplicate #include "simdjson/dom/document_stream-inl.h" */ +/* including simdjson/dom/document-inl.h: #include "simdjson/dom/document-inl.h" */ +/* begin file simdjson/dom/document-inl.h */ +#ifndef SIMDJSON_DOCUMENT_INL_H +#define SIMDJSON_DOCUMENT_INL_H + +// Inline implementations go in here. + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* skipped duplicate #include "simdjson/dom/document.h" */ +/* skipped duplicate #include "simdjson/dom/element-inl.h" */ +/* skipped duplicate #include "simdjson/internal/tape_ref-inl.h" */ +/* including simdjson/internal/jsonformatutils.h: #include "simdjson/internal/jsonformatutils.h" */ +/* begin file simdjson/internal/jsonformatutils.h */ +#ifndef SIMDJSON_INTERNAL_JSONFORMATUTILS_H +#define SIMDJSON_INTERNAL_JSONFORMATUTILS_H + +/* skipped duplicate #include "simdjson/base.h" */ +#include +#include +#include + +namespace simdjson { +namespace internal { + +inline std::ostream& operator<<(std::ostream& out, const escape_json_string &str); + +class escape_json_string { +public: + escape_json_string(std::string_view _str) noexcept : str{_str} {} + operator std::string() const noexcept { std::stringstream s; s << *this; return s.str(); } +private: + std::string_view str; + friend std::ostream& operator<<(std::ostream& out, const escape_json_string &unescaped); +}; + +inline std::ostream& operator<<(std::ostream& out, const escape_json_string &unescaped) { + for (size_t i=0; i(unescaped.str[i]) <= 0x1F) { + // TODO can this be done once at the beginning, or will it mess up << char? + std::ios::fmtflags f(out.flags()); + out << "\\u" << std::hex << std::setw(4) << std::setfill('0') << int(unescaped.str[i]); + out.flags(f); + } else { + out << unescaped.str[i]; + } + } + } + return out; +} + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_JSONFORMATUTILS_H +/* end file simdjson/internal/jsonformatutils.h */ + +#include + +namespace simdjson { +namespace dom { + +// +// document inline implementation +// +inline element document::root() const noexcept { + return element(internal::tape_ref(this, 1)); +} +simdjson_warn_unused +inline size_t document::capacity() const noexcept { + return allocated_capacity; +} + +simdjson_warn_unused +inline error_code document::allocate(size_t capacity) noexcept { + if (capacity == 0) { + string_buf.reset(); + tape.reset(); + allocated_capacity = 0; + return SUCCESS; + } + + // a pathological input like "[[[[..." would generate capacity tape elements, so + // need a capacity of at least capacity + 1, but it is also possible to do + // worse with "[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" + //where capacity + 1 tape elements are + // generated, see issue https://github.com/simdjson/simdjson/issues/345 + size_t tape_capacity = SIMDJSON_ROUNDUP_N(capacity + 3, 64); + // a document with only zero-length strings... could have capacity/3 string + // and we would need capacity/3 * 5 bytes on the string buffer + size_t string_capacity = SIMDJSON_ROUNDUP_N(5 * capacity / 3 + SIMDJSON_PADDING, 64); + string_buf.reset( new (std::nothrow) uint8_t[string_capacity]); + tape.reset(new (std::nothrow) uint64_t[tape_capacity]); + if(!(string_buf && tape)) { + allocated_capacity = 0; + string_buf.reset(); + tape.reset(); + return MEMALLOC; + } + // Technically the allocated_capacity might be larger than capacity + // so the next line is pessimistic. + allocated_capacity = capacity; + return SUCCESS; +} + +inline bool document::dump_raw_tape(std::ostream &os) const noexcept { + uint32_t string_length; + size_t tape_idx = 0; + uint64_t tape_val = tape[tape_idx]; + uint8_t type = uint8_t(tape_val >> 56); + os << tape_idx << " : " << type; + tape_idx++; + size_t how_many = 0; + if (type == 'r') { + how_many = size_t(tape_val & internal::JSON_VALUE_MASK); + } else { + // Error: no starting root node? + return false; + } + os << "\t// pointing to " << how_many << " (right after last node)\n"; + uint64_t payload; + for (; tape_idx < how_many; tape_idx++) { + os << tape_idx << " : "; + tape_val = tape[tape_idx]; + payload = tape_val & internal::JSON_VALUE_MASK; + type = uint8_t(tape_val >> 56); + switch (type) { + case '"': // we have a string + os << "string \""; + std::memcpy(&string_length, string_buf.get() + payload, sizeof(uint32_t)); + os << internal::escape_json_string(std::string_view( + reinterpret_cast(string_buf.get() + payload + sizeof(uint32_t)), + string_length + )); + os << '"'; + os << '\n'; + break; + case 'l': // we have a long int + if (tape_idx + 1 >= how_many) { + return false; + } + os << "integer " << static_cast(tape[++tape_idx]) << "\n"; + break; + case 'u': // we have a long uint + if (tape_idx + 1 >= how_many) { + return false; + } + os << "unsigned integer " << tape[++tape_idx] << "\n"; + break; + case 'd': // we have a double + os << "float "; + if (tape_idx + 1 >= how_many) { + return false; + } + double answer; + std::memcpy(&answer, &tape[++tape_idx], sizeof(answer)); + os << answer << '\n'; + break; + case 'n': // we have a null + os << "null\n"; + break; + case 't': // we have a true + os << "true\n"; + break; + case 'f': // we have a false + os << "false\n"; + break; + case '{': // we have an object + os << "{\t// pointing to next tape location " << uint32_t(payload) + << " (first node after the scope), " + << " saturated count " + << ((payload >> 32) & internal::JSON_COUNT_MASK)<< "\n"; + break; case '}': // we end an object + os << "}\t// pointing to previous tape location " << uint32_t(payload) + << " (start of the scope)\n"; + break; + case '[': // we start an array + os << "[\t// pointing to next tape location " << uint32_t(payload) + << " (first node after the scope), " + << " saturated count " + << ((payload >> 32) & internal::JSON_COUNT_MASK)<< "\n"; + break; + case ']': // we end an array + os << "]\t// pointing to previous tape location " << uint32_t(payload) + << " (start of the scope)\n"; + break; + case 'r': // we start and end with the root node + // should we be hitting the root node? + return false; + default: + return false; + } + } + tape_val = tape[tape_idx]; + payload = tape_val & internal::JSON_VALUE_MASK; + type = uint8_t(tape_val >> 56); + os << tape_idx << " : " << type << "\t// pointing to " << payload + << " (start root)\n"; + return true; +} + +} // namespace dom +} // namespace simdjson + +#endif // SIMDJSON_DOCUMENT_INL_H +/* end file simdjson/dom/document-inl.h */ +/* skipped duplicate #include "simdjson/dom/element-inl.h" */ +/* skipped duplicate #include "simdjson/dom/object-inl.h" */ +/* including simdjson/dom/parsedjson_iterator-inl.h: #include "simdjson/dom/parsedjson_iterator-inl.h" */ +/* begin file simdjson/dom/parsedjson_iterator-inl.h */ +#ifndef SIMDJSON_PARSEDJSON_ITERATOR_INL_H +#define SIMDJSON_PARSEDJSON_ITERATOR_INL_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* skipped duplicate #include "simdjson/dom/parsedjson_iterator.h" */ +/* skipped duplicate #include "simdjson/internal/jsonformatutils.h" */ + +/* skipped duplicate #include "simdjson/dom/parser-inl.h" */ +/* skipped duplicate #include "simdjson/internal/tape_ref-inl.h" */ + +#include +#include +#include +#include + +#ifndef SIMDJSON_DISABLE_DEPRECATED_API + +namespace simdjson { + +// VS2017 reports deprecated warnings when you define a deprecated class's methods. +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_DEPRECATED_WARNING + +// Because of template weirdness, the actual class definition is inline in the document class +simdjson_warn_unused bool dom::parser::Iterator::is_ok() const { + return location < tape_length; +} + +// useful for debugging purposes +size_t dom::parser::Iterator::get_tape_location() const { + return location; +} + +// useful for debugging purposes +size_t dom::parser::Iterator::get_tape_length() const { + return tape_length; +} + +// returns the current depth (start at 1 with 0 reserved for the fictitious root +// node) +size_t dom::parser::Iterator::get_depth() const { + return depth; +} + +// A scope is a series of nodes at the same depth, typically it is either an +// object ({) or an array ([). The root node has type 'r'. +uint8_t dom::parser::Iterator::get_scope_type() const { + return depth_index[depth].scope_type; +} + +bool dom::parser::Iterator::move_forward() { + if (location + 1 >= tape_length) { + return false; // we are at the end! + } + + if ((current_type == '[') || (current_type == '{')) { + // We are entering a new scope + depth++; + assert(depth < max_depth); + depth_index[depth].start_of_scope = location; + depth_index[depth].scope_type = current_type; + } else if ((current_type == ']') || (current_type == '}')) { + // Leaving a scope. + depth--; + } else if (is_number()) { + // these types use 2 locations on the tape, not just one. + location += 1; + } + + location += 1; + current_val = doc.tape[location]; + current_type = uint8_t(current_val >> 56); + return true; +} + +void dom::parser::Iterator::move_to_value() { + // assume that we are on a key, so move by 1. + location += 1; + current_val = doc.tape[location]; + current_type = uint8_t(current_val >> 56); +} + +bool dom::parser::Iterator::move_to_key(const char *key) { + if (down()) { + do { + const bool right_key = (strcmp(get_string(), key) == 0); + move_to_value(); + if (right_key) { + return true; + } + } while (next()); + up(); + } + return false; +} + +bool dom::parser::Iterator::move_to_key_insensitive( + const char *key) { + if (down()) { + do { + const bool right_key = (simdjson_strcasecmp(get_string(), key) == 0); + move_to_value(); + if (right_key) { + return true; + } + } while (next()); + up(); + } + return false; +} + +bool dom::parser::Iterator::move_to_key(const char *key, + uint32_t length) { + if (down()) { + do { + bool right_key = ((get_string_length() == length) && + (memcmp(get_string(), key, length) == 0)); + move_to_value(); + if (right_key) { + return true; + } + } while (next()); + up(); + } + return false; +} + +bool dom::parser::Iterator::move_to_index(uint32_t index) { + if (down()) { + uint32_t i = 0; + for (; i < index; i++) { + if (!next()) { + break; + } + } + if (i == index) { + return true; + } + up(); + } + return false; +} + +bool dom::parser::Iterator::prev() { + size_t target_location = location; + to_start_scope(); + size_t npos = location; + if (target_location == npos) { + return false; // we were already at the start + } + size_t oldnpos; + // we have that npos < target_location here + do { + oldnpos = npos; + if ((current_type == '[') || (current_type == '{')) { + // we need to jump + npos = uint32_t(current_val); + } else { + npos = npos + ((current_type == 'd' || current_type == 'l') ? 2 : 1); + } + } while (npos < target_location); + location = oldnpos; + current_val = doc.tape[location]; + current_type = uint8_t(current_val >> 56); + return true; +} + +bool dom::parser::Iterator::up() { + if (depth == 1) { + return false; // don't allow moving back to root + } + to_start_scope(); + // next we just move to the previous value + depth--; + location -= 1; + current_val = doc.tape[location]; + current_type = uint8_t(current_val >> 56); + return true; +} + +bool dom::parser::Iterator::down() { + if (location + 1 >= tape_length) { + return false; + } + if ((current_type == '[') || (current_type == '{')) { + size_t npos = uint32_t(current_val); + if (npos == location + 2) { + return false; // we have an empty scope + } + depth++; + assert(depth < max_depth); + location = location + 1; + depth_index[depth].start_of_scope = location; + depth_index[depth].scope_type = current_type; + current_val = doc.tape[location]; + current_type = uint8_t(current_val >> 56); + return true; + } + return false; +} + +void dom::parser::Iterator::to_start_scope() { + location = depth_index[depth].start_of_scope; + current_val = doc.tape[location]; + current_type = uint8_t(current_val >> 56); +} + +inline void dom::parser::Iterator::rewind() { + while (up()) + ; +} + + +bool dom::parser::Iterator::next() { + size_t npos; + if ((current_type == '[') || (current_type == '{')) { + // we need to jump + npos = uint32_t(current_val); + } else { + npos = location + (is_number() ? 2 : 1); + } + uint64_t next_val = doc.tape[npos]; + uint8_t next_type = uint8_t(next_val >> 56); + if ((next_type == ']') || (next_type == '}')) { + return false; // we reached the end of the scope + } + location = npos; + current_val = next_val; + current_type = next_type; + return true; +} +dom::parser::Iterator::Iterator(const dom::parser &pj) noexcept(false) + : doc(pj.doc) +{ +#if SIMDJSON_EXCEPTIONS + if (!pj.valid) { throw simdjson_error(pj.error); } +#else + if (!pj.valid) { return; } // abort() usage is forbidden in the library +#endif + + max_depth = pj.max_depth(); + depth_index = new scopeindex_t[max_depth + 1]; + depth_index[0].start_of_scope = location; + current_val = doc.tape[location++]; + current_type = uint8_t(current_val >> 56); + depth_index[0].scope_type = current_type; + tape_length = size_t(current_val & internal::JSON_VALUE_MASK); + if (location < tape_length) { + // If we make it here, then depth_capacity must >=2, but the compiler + // may not know this. + current_val = doc.tape[location]; + current_type = uint8_t(current_val >> 56); + depth++; + assert(depth < max_depth); + depth_index[depth].start_of_scope = location; + depth_index[depth].scope_type = current_type; + } +} +dom::parser::Iterator::Iterator( + const dom::parser::Iterator &o) noexcept + : doc(o.doc), + max_depth(o.depth), + depth(o.depth), + location(o.location), + tape_length(o.tape_length), + current_type(o.current_type), + current_val(o.current_val) +{ + depth_index = new scopeindex_t[max_depth+1]; + std::memcpy(depth_index, o.depth_index, (depth + 1) * sizeof(depth_index[0])); +} + +dom::parser::Iterator::~Iterator() noexcept { + if (depth_index) { delete[] depth_index; } +} + +bool dom::parser::Iterator::print(std::ostream &os, bool escape_strings) const { + if (!is_ok()) { + return false; + } + switch (current_type) { + case '"': // we have a string + os << '"'; + if (escape_strings) { + os << internal::escape_json_string(std::string_view(get_string(), get_string_length())); + } else { + // was: os << get_string();, but given that we can include null chars, we + // have to do something crazier: + std::copy(get_string(), get_string() + get_string_length(), std::ostream_iterator(os)); + } + os << '"'; + break; + case 'l': // we have a long int + os << get_integer(); + break; + case 'u': + os << get_unsigned_integer(); + break; + case 'd': + os << get_double(); + break; + case 'n': // we have a null + os << "null"; + break; + case 't': // we have a true + os << "true"; + break; + case 'f': // we have a false + os << "false"; + break; + case '{': // we have an object + case '}': // we end an object + case '[': // we start an array + case ']': // we end an array + os << char(current_type); + break; + default: + return false; + } + return true; +} + +bool dom::parser::Iterator::move_to(const char *pointer, + uint32_t length) { + char *new_pointer = nullptr; + if (pointer[0] == '#') { + // Converting fragment representation to string representation + new_pointer = new char[length]; + uint32_t new_length = 0; + for (uint32_t i = 1; i < length; i++) { + if (pointer[i] == '%' && pointer[i + 1] == 'x') { +#if __cpp_exceptions + try { +#endif + int fragment = + std::stoi(std::string(&pointer[i + 2], 2), nullptr, 16); + if (fragment == '\\' || fragment == '"' || (fragment <= 0x1F)) { + // escaping the character + new_pointer[new_length] = '\\'; + new_length++; + } + new_pointer[new_length] = char(fragment); + i += 3; +#if __cpp_exceptions + } catch (std::invalid_argument &) { + delete[] new_pointer; + return false; // the fragment is invalid + } +#endif + } else { + new_pointer[new_length] = pointer[i]; + } + new_length++; + } + length = new_length; + pointer = new_pointer; + } + + // saving the current state + size_t depth_s = depth; + size_t location_s = location; + uint8_t current_type_s = current_type; + uint64_t current_val_s = current_val; + + rewind(); // The json pointer is used from the root of the document. + + bool found = relative_move_to(pointer, length); + delete[] new_pointer; + + if (!found) { + // since the pointer has found nothing, we get back to the original + // position. + depth = depth_s; + location = location_s; + current_type = current_type_s; + current_val = current_val_s; + } + + return found; +} + +inline bool dom::parser::Iterator::move_to(const std::string &pointer) { + return move_to(pointer.c_str(), uint32_t(pointer.length())); +} + +inline int64_t dom::parser::Iterator::get_integer() const { + if (location + 1 >= tape_length) { + return 0; // default value in case of error + } + return static_cast(doc.tape[location + 1]); +} + +inline uint64_t dom::parser::Iterator::get_unsigned_integer() const { + if (location + 1 >= tape_length) { + return 0; // default value in case of error + } + return doc.tape[location + 1]; +} + +inline const char * dom::parser::Iterator::get_string() const { + return reinterpret_cast( + doc.string_buf.get() + (current_val & internal::JSON_VALUE_MASK) + sizeof(uint32_t)); +} + +inline uint32_t dom::parser::Iterator::get_string_length() const { + uint32_t answer; + std::memcpy(&answer, + reinterpret_cast(doc.string_buf.get() + + (current_val & internal::JSON_VALUE_MASK)), + sizeof(uint32_t)); + return answer; +} + +inline double dom::parser::Iterator::get_double() const { + if (location + 1 >= tape_length) { + return std::numeric_limits::quiet_NaN(); // default value in + // case of error + } + double answer; + std::memcpy(&answer, &doc.tape[location + 1], sizeof(answer)); + return answer; +} + +bool dom::parser::Iterator::relative_move_to(const char *pointer, + uint32_t length) { + if (length == 0) { + // returns the whole document + return true; + } + + if (pointer[0] != '/') { + // '/' must be the first character + return false; + } + + // finding the key in an object or the index in an array + std::string key_or_index; + uint32_t offset = 1; + + // checking for the "-" case + if (is_array() && pointer[1] == '-') { + if (length != 2) { + // the pointer must be exactly "/-" + // there can't be anything more after '-' as an index + return false; + } + key_or_index = '-'; + offset = length; // will skip the loop coming right after + } + + // We either transform the first reference token to a valid json key + // or we make sure it is a valid index in an array. + for (; offset < length; offset++) { + if (pointer[offset] == '/') { + // beginning of the next key or index + break; + } + if (is_array() && (pointer[offset] < '0' || pointer[offset] > '9')) { + // the index of an array must be an integer + // we also make sure std::stoi won't discard whitespaces later + return false; + } + if (pointer[offset] == '~') { + // "~1" represents "/" + if (pointer[offset + 1] == '1') { + key_or_index += '/'; + offset++; + continue; + } + // "~0" represents "~" + if (pointer[offset + 1] == '0') { + key_or_index += '~'; + offset++; + continue; + } + } + if (pointer[offset] == '\\') { + if (pointer[offset + 1] == '\\' || pointer[offset + 1] == '"' || + (pointer[offset + 1] <= 0x1F)) { + key_or_index += pointer[offset + 1]; + offset++; + continue; + } + return false; // invalid escaped character + } + if (pointer[offset] == '\"') { + // unescaped quote character. this is an invalid case. + // lets do nothing and assume most pointers will be valid. + // it won't find any corresponding json key anyway. + // return false; + } + key_or_index += pointer[offset]; + } + + bool found = false; + if (is_object()) { + if (move_to_key(key_or_index.c_str(), uint32_t(key_or_index.length()))) { + found = relative_move_to(pointer + offset, length - offset); + } + } else if (is_array()) { + if (key_or_index == "-") { // handling "-" case first + if (down()) { + while (next()) + ; // moving to the end of the array + // moving to the nonexistent value right after... + size_t npos; + if ((current_type == '[') || (current_type == '{')) { + // we need to jump + npos = uint32_t(current_val); + } else { + npos = + location + ((current_type == 'd' || current_type == 'l') ? 2 : 1); + } + location = npos; + current_val = doc.tape[npos]; + current_type = uint8_t(current_val >> 56); + return true; // how could it fail ? + } + } else { // regular numeric index + // The index can't have a leading '0' + if (key_or_index[0] == '0' && key_or_index.length() > 1) { + return false; + } + // it cannot be empty + if (key_or_index.length() == 0) { + return false; + } + // we already checked the index contains only valid digits + uint32_t index = std::stoi(key_or_index); + if (move_to_index(index)) { + found = relative_move_to(pointer + offset, length - offset); + } + } + } + + return found; +} + +SIMDJSON_POP_DISABLE_WARNINGS +} // namespace simdjson + +#endif // SIMDJSON_DISABLE_DEPRECATED_API + + +#endif // SIMDJSON_PARSEDJSON_ITERATOR_INL_H +/* end file simdjson/dom/parsedjson_iterator-inl.h */ +/* skipped duplicate #include "simdjson/dom/parser-inl.h" */ +/* skipped duplicate #include "simdjson/internal/tape_ref-inl.h" */ +/* including simdjson/dom/serialization-inl.h: #include "simdjson/dom/serialization-inl.h" */ +/* begin file simdjson/dom/serialization-inl.h */ + +#ifndef SIMDJSON_SERIALIZATION_INL_H +#define SIMDJSON_SERIALIZATION_INL_H + +/* skipped duplicate #include "simdjson/dom/base.h" */ +/* skipped duplicate #include "simdjson/dom/serialization.h" */ +/* skipped duplicate #include "simdjson/dom/parser.h" */ +/* skipped duplicate #include "simdjson/internal/tape_type.h" */ + +/* skipped duplicate #include "simdjson/dom/array-inl.h" */ +/* skipped duplicate #include "simdjson/dom/object-inl.h" */ +/* skipped duplicate #include "simdjson/internal/tape_ref-inl.h" */ + +#include + +namespace simdjson { +namespace dom { +inline bool parser::print_json(std::ostream &os) const noexcept { + if (!valid) { return false; } + simdjson::internal::string_builder<> sb; + sb.append(doc.root()); + std::string_view answer = sb.str(); + os << answer; + return true; +} + +inline std::ostream& operator<<(std::ostream& out, simdjson::dom::element value) { + simdjson::internal::string_builder<> sb; + sb.append(value); + return (out << sb.str()); +} +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#endif +inline std::ostream& operator<<(std::ostream& out, simdjson::dom::array value) { + simdjson::internal::string_builder<> sb; + sb.append(value); + return (out << sb.str()); +} +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#endif +inline std::ostream& operator<<(std::ostream& out, simdjson::dom::object value) { + simdjson::internal::string_builder<> sb; + sb.append(value); + return (out << sb.str()); +} +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#endif + +} // namespace dom + +/*** + * Number utility functions + **/ +namespace { +/**@private + * Escape sequence like \b or \u0001 + * We expect that most compilers will use 8 bytes for this data structure. + **/ +struct escape_sequence { + uint8_t length; + const char string[7]; // technically, we only ever need 6 characters, we pad to 8 +}; +/**@private + * This converts a signed integer into a character sequence. + * The caller is responsible for providing enough memory (at least + * 20 characters.) + * Though various runtime libraries provide itoa functions, + * it is not part of the C++ standard. The C++17 standard + * adds the to_chars functions which would do as well, but + * we want to support C++11. + */ +static char *fast_itoa(char *output, int64_t value) noexcept { + // This is a standard implementation of itoa. + char buffer[20]; + uint64_t value_positive; + // In general, negating a signed integer is unsafe. + if(value < 0) { + *output++ = '-'; + // Doing value_positive = -value; while avoiding + // undefined behavior warnings. + // It assumes two complement's which is universal at this + // point in time. + std::memcpy(&value_positive, &value, sizeof(value)); + value_positive = (~value_positive) + 1; // this is a negation + } else { + value_positive = value; + } + // We work solely with value_positive. It *might* be easier + // for an optimizing compiler to deal with an unsigned variable + // as far as performance goes. + const char *const end_buffer = buffer + 20; + char *write_pointer = buffer + 19; + // A faster approach is possible if we expect large integers: + // unroll the loop (work in 100s, 1000s) and use some kind of + // memoization. + while(value_positive >= 10) { + *write_pointer-- = char('0' + (value_positive % 10)); + value_positive /= 10; + } + *write_pointer = char('0' + value_positive); + size_t len = end_buffer - write_pointer; + std::memcpy(output, write_pointer, len); + return output + len; +} +/**@private + * This converts an unsigned integer into a character sequence. + * The caller is responsible for providing enough memory (at least + * 19 characters.) + * Though various runtime libraries provide itoa functions, + * it is not part of the C++ standard. The C++17 standard + * adds the to_chars functions which would do as well, but + * we want to support C++11. + */ +static char *fast_itoa(char *output, uint64_t value) noexcept { + // This is a standard implementation of itoa. + char buffer[20]; + const char *const end_buffer = buffer + 20; + char *write_pointer = buffer + 19; + // A faster approach is possible if we expect large integers: + // unroll the loop (work in 100s, 1000s) and use some kind of + // memoization. + while(value >= 10) { + *write_pointer-- = char('0' + (value % 10)); + value /= 10; + }; + *write_pointer = char('0' + value); + size_t len = end_buffer - write_pointer; + std::memcpy(output, write_pointer, len); + return output + len; +} + + +} // anonymous namespace +namespace internal { + +/*** + * Minifier/formatter code. + **/ + +template +simdjson_inline void base_formatter::number(uint64_t x) { + char number_buffer[24]; + char *newp = fast_itoa(number_buffer, x); + buffer.insert(buffer.end(), number_buffer, newp); +} + +template +simdjson_inline void base_formatter::number(int64_t x) { + char number_buffer[24]; + char *newp = fast_itoa(number_buffer, x); + buffer.insert(buffer.end(), number_buffer, newp); +} + +template +simdjson_inline void base_formatter::number(double x) { + char number_buffer[24]; + // Currently, passing the nullptr to the second argument is + // safe because our implementation does not check the second + // argument. + char *newp = internal::to_chars(number_buffer, nullptr, x); + buffer.insert(buffer.end(), number_buffer, newp); +} + +template +simdjson_inline void base_formatter::start_array() { one_char('['); } + + +template +simdjson_inline void base_formatter::end_array() { one_char(']'); } + +template +simdjson_inline void base_formatter::start_object() { one_char('{'); } + +template +simdjson_inline void base_formatter::end_object() { one_char('}'); } + +template +simdjson_inline void base_formatter::comma() { one_char(','); } + +template +simdjson_inline void base_formatter::true_atom() { + const char * s = "true"; + buffer.insert(buffer.end(), s, s + 4); +} + +template +simdjson_inline void base_formatter::false_atom() { + const char * s = "false"; + buffer.insert(buffer.end(), s, s + 5); +} + +template +simdjson_inline void base_formatter::null_atom() { + const char * s = "null"; + buffer.insert(buffer.end(), s, s + 4); +} + +template +simdjson_inline void base_formatter::one_char(char c) { buffer.push_back(c); } + +template +simdjson_inline void base_formatter::key(std::string_view unescaped) { + string(unescaped); + one_char(':'); +} + +template +simdjson_inline void base_formatter::string(std::string_view unescaped) { + one_char('\"'); + size_t i = 0; + // Fast path for the case where we have no control character, no ", and no backslash. + // This should include most keys. + // + // We would like to use 'bool' but some compilers take offense to bitwise operation + // with bool types. + constexpr static char needs_escaping[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + for(;i + 8 <= unescaped.length(); i += 8) { + // Poor's man vectorization. This could get much faster if we used SIMD. + // + // It is not the case that replacing '|' with '||' would be neutral performance-wise. + if(needs_escaping[uint8_t(unescaped[i])] | needs_escaping[uint8_t(unescaped[i+1])] + | needs_escaping[uint8_t(unescaped[i+2])] | needs_escaping[uint8_t(unescaped[i+3])] + | needs_escaping[uint8_t(unescaped[i+4])] | needs_escaping[uint8_t(unescaped[i+5])] + | needs_escaping[uint8_t(unescaped[i+6])] | needs_escaping[uint8_t(unescaped[i+7])] + ) { break; } + } + for(;i < unescaped.length(); i++) { + if(needs_escaping[uint8_t(unescaped[i])]) { break; } + } + // The following is also possible and omits a 256-byte table, but it is slower: + // for (; (i < unescaped.length()) && (uint8_t(unescaped[i]) > 0x1F) + // && (unescaped[i] != '\"') && (unescaped[i] != '\\'); i++) {} + + // At least for long strings, the following should be fast. We could + // do better by integrating the checks and the insertion. + buffer.insert(buffer.end(), unescaped.data(), unescaped.data() + i); + // We caught a control character if we enter this loop (slow). + // Note that we are do not restart from the beginning, but rather we continue + // from the point where we encountered something that requires escaping. + for (; i < unescaped.length(); i++) { + switch (unescaped[i]) { + case '\"': + { + const char * s = "\\\""; + buffer.insert(buffer.end(), s, s + 2); + } + break; + case '\\': + { + const char * s = "\\\\"; + buffer.insert(buffer.end(), s, s + 2); + } + break; + default: + if (uint8_t(unescaped[i]) <= 0x1F) { + // If packed, this uses 8 * 32 bytes. + // Note that we expect most compilers to embed this code in the data + // section. + constexpr static escape_sequence escaped[32] = { + {6, "\\u0000"}, {6, "\\u0001"}, {6, "\\u0002"}, {6, "\\u0003"}, + {6, "\\u0004"}, {6, "\\u0005"}, {6, "\\u0006"}, {6, "\\u0007"}, + {2, "\\b"}, {2, "\\t"}, {2, "\\n"}, {6, "\\u000b"}, + {2, "\\f"}, {2, "\\r"}, {6, "\\u000e"}, {6, "\\u000f"}, + {6, "\\u0010"}, {6, "\\u0011"}, {6, "\\u0012"}, {6, "\\u0013"}, + {6, "\\u0014"}, {6, "\\u0015"}, {6, "\\u0016"}, {6, "\\u0017"}, + {6, "\\u0018"}, {6, "\\u0019"}, {6, "\\u001a"}, {6, "\\u001b"}, + {6, "\\u001c"}, {6, "\\u001d"}, {6, "\\u001e"}, {6, "\\u001f"}}; + auto u = escaped[uint8_t(unescaped[i])]; + buffer.insert(buffer.end(), u.string, u.string + u.length); + } else { + one_char(unescaped[i]); + } + } // switch + } // for + one_char('\"'); +} + + +template +inline void base_formatter::clear() { + buffer.clear(); +} + +template +simdjson_inline std::string_view base_formatter::str() const { + return std::string_view(buffer.data(), buffer.size()); +} + +simdjson_inline void mini_formatter::print_newline() { + return; +} + +simdjson_inline void mini_formatter::print_indents(size_t depth) { + (void)depth; + return; +} + +simdjson_inline void mini_formatter::print_space() { + return; +} + +simdjson_inline void pretty_formatter::print_newline() { + one_char('\n'); +} + +simdjson_inline void pretty_formatter::print_indents(size_t depth) { + if(this->indent_step <= 0) { + return; + } + for(size_t i = 0; i < this->indent_step * depth; i++) { + one_char(' '); + } +} + +simdjson_inline void pretty_formatter::print_space() { + one_char(' '); +} + +/*** + * String building code. + **/ + +template +inline void string_builder::append(simdjson::dom::element value) { + // using tape_type = simdjson::internal::tape_type; + size_t depth = 0; + constexpr size_t MAX_DEPTH = 16; + bool is_object[MAX_DEPTH]; + is_object[0] = false; + bool after_value = false; + + internal::tape_ref iter(value.tape); + do { + // print commas after each value + if (after_value) { + format.comma(); + format.print_newline(); + } + + format.print_indents(depth); + + // If we are in an object, print the next key and :, and skip to the next + // value. + if (is_object[depth]) { + format.key(iter.get_string_view()); + format.print_space(); + iter.json_index++; + } + switch (iter.tape_ref_type()) { + + // Arrays + case tape_type::START_ARRAY: { + // If we're too deep, we need to recurse to go deeper. + depth++; + if (simdjson_unlikely(depth >= MAX_DEPTH)) { + append(simdjson::dom::array(iter)); + iter.json_index = iter.matching_brace_index() - 1; // Jump to the ] + depth--; + break; + } + + // Output start [ + format.start_array(); + iter.json_index++; + + // Handle empty [] (we don't want to come back around and print commas) + if (iter.tape_ref_type() == tape_type::END_ARRAY) { + format.end_array(); + depth--; + break; + } + + is_object[depth] = false; + after_value = false; + format.print_newline(); + continue; + } + + // Objects + case tape_type::START_OBJECT: { + // If we're too deep, we need to recurse to go deeper. + depth++; + if (simdjson_unlikely(depth >= MAX_DEPTH)) { + append(simdjson::dom::object(iter)); + iter.json_index = iter.matching_brace_index() - 1; // Jump to the } + depth--; + break; + } + + // Output start { + format.start_object(); + iter.json_index++; + + // Handle empty {} (we don't want to come back around and print commas) + if (iter.tape_ref_type() == tape_type::END_OBJECT) { + format.end_object(); + depth--; + break; + } + + is_object[depth] = true; + after_value = false; + format.print_newline(); + continue; + } + + // Scalars + case tape_type::STRING: + format.string(iter.get_string_view()); + break; + case tape_type::INT64: + format.number(iter.next_tape_value()); + iter.json_index++; // numbers take up 2 spots, so we need to increment + // extra + break; + case tape_type::UINT64: + format.number(iter.next_tape_value()); + iter.json_index++; // numbers take up 2 spots, so we need to increment + // extra + break; + case tape_type::DOUBLE: + format.number(iter.next_tape_value()); + iter.json_index++; // numbers take up 2 spots, so we need to increment + // extra + break; + case tape_type::TRUE_VALUE: + format.true_atom(); + break; + case tape_type::FALSE_VALUE: + format.false_atom(); + break; + case tape_type::NULL_VALUE: + format.null_atom(); + break; + + // These are impossible + case tape_type::END_ARRAY: + case tape_type::END_OBJECT: + case tape_type::ROOT: + SIMDJSON_UNREACHABLE(); + } + iter.json_index++; + after_value = true; + + // Handle multiple ends in a row + while (depth != 0 && (iter.tape_ref_type() == tape_type::END_ARRAY || + iter.tape_ref_type() == tape_type::END_OBJECT)) { + format.print_newline(); + depth--; + format.print_indents(depth); + if (iter.tape_ref_type() == tape_type::END_ARRAY) { + format.end_array(); + } else { + format.end_object(); + } + iter.json_index++; + } + + // Stop when we're at depth 0 + } while (depth != 0); + + format.print_newline(); +} + +template +inline void string_builder::append(simdjson::dom::object value) { + format.start_object(); + auto pair = value.begin(); + auto end = value.end(); + if (pair != end) { + append(*pair); + for (++pair; pair != end; ++pair) { + format.comma(); + append(*pair); + } + } + format.end_object(); +} + +template +inline void string_builder::append(simdjson::dom::array value) { + format.start_array(); + auto iter = value.begin(); + auto end = value.end(); + if (iter != end) { + append(*iter); + for (++iter; iter != end; ++iter) { + format.comma(); + append(*iter); + } + } + format.end_array(); +} + +template +simdjson_inline void string_builder::append(simdjson::dom::key_value_pair kv) { + format.key(kv.key); + append(kv.value); +} + +template +simdjson_inline void string_builder::clear() { + format.clear(); +} + +template +simdjson_inline std::string_view string_builder::str() const { + return format.str(); +} + + +} // namespace internal +} // namespace simdjson + +#endif +/* end file simdjson/dom/serialization-inl.h */ + +#endif // SIMDJSON_DOM_H +/* end file simdjson/dom.h */ +/* including simdjson/ondemand.h: #include "simdjson/ondemand.h" */ +/* begin file simdjson/ondemand.h */ +#ifndef SIMDJSON_ONDEMAND_H +#define SIMDJSON_ONDEMAND_H + +/* including simdjson/builtin/ondemand.h: #include "simdjson/builtin/ondemand.h" */ +/* begin file simdjson/builtin/ondemand.h */ +#ifndef SIMDJSON_BUILTIN_ONDEMAND_H +#define SIMDJSON_BUILTIN_ONDEMAND_H + +/* including simdjson/builtin.h: #include "simdjson/builtin.h" */ +/* begin file simdjson/builtin.h */ +#ifndef SIMDJSON_BUILTIN_H +#define SIMDJSON_BUILTIN_H + +/* including simdjson/builtin/base.h: #include "simdjson/builtin/base.h" */ +/* begin file simdjson/builtin/base.h */ +#ifndef SIMDJSON_BUILTIN_BASE_H +#define SIMDJSON_BUILTIN_BASE_H + +/* skipped duplicate #include "simdjson/base.h" */ +/* including simdjson/implementation_detection.h: #include "simdjson/implementation_detection.h" */ +/* begin file simdjson/implementation_detection.h */ +#ifndef SIMDJSON_IMPLEMENTATION_DETECTION_H +#define SIMDJSON_IMPLEMENTATION_DETECTION_H + +/* skipped duplicate #include "simdjson/base.h" */ + +// 0 is reserved, because undefined SIMDJSON_IMPLEMENTATION equals 0 in preprocessor macros. +#define SIMDJSON_IMPLEMENTATION_ID_arm64 1 +#define SIMDJSON_IMPLEMENTATION_ID_fallback 2 +#define SIMDJSON_IMPLEMENTATION_ID_haswell 3 +#define SIMDJSON_IMPLEMENTATION_ID_icelake 4 +#define SIMDJSON_IMPLEMENTATION_ID_ppc64 5 +#define SIMDJSON_IMPLEMENTATION_ID_westmere 6 + +#define SIMDJSON_IMPLEMENTATION_ID_FOR(IMPL) SIMDJSON_CAT(SIMDJSON_IMPLEMENTATION_ID_, IMPL) +#define SIMDJSON_IMPLEMENTATION_ID SIMDJSON_IMPLEMENTATION_ID_FOR(SIMDJSON_IMPLEMENTATION) + +#define SIMDJSON_IMPLEMENTATION_IS(IMPL) SIMDJSON_IMPLEMENTATION_ID == SIMDJSON_IMPLEMENTATION_ID_FOR(IMPL) + +// +// First, figure out which implementations can be run. Doing it here makes it so we don't have to worry about the order +// in which we include them. +// + +#ifndef SIMDJSON_IMPLEMENTATION_ARM64 +#define SIMDJSON_IMPLEMENTATION_ARM64 (SIMDJSON_IS_ARM64) +#endif +#define SIMDJSON_CAN_ALWAYS_RUN_ARM64 SIMDJSON_IMPLEMENTATION_ARM64 && SIMDJSON_IS_ARM64 + +// Default Icelake to on if this is x86-64. Even if we're not compiled for it, it could be selected +// at runtime. +#ifndef SIMDJSON_IMPLEMENTATION_ICELAKE +#define SIMDJSON_IMPLEMENTATION_ICELAKE ((SIMDJSON_IS_X86_64) && (SIMDJSON_AVX512_ALLOWED) && (SIMDJSON_COMPILER_SUPPORTS_VBMI2)) +#endif + +#ifdef _MSC_VER +// To see why (__BMI__) && (__PCLMUL__) && (__LZCNT__) are not part of this next line, see +// https://github.com/simdjson/simdjson/issues/1247 +#define SIMDJSON_CAN_ALWAYS_RUN_ICELAKE ((SIMDJSON_IMPLEMENTATION_ICELAKE) && (__AVX2__) && (__AVX512F__) && (__AVX512DQ__) && (__AVX512CD__) && (__AVX512BW__) && (__AVX512VL__) && (__AVX512VBMI2__)) +#else +#define SIMDJSON_CAN_ALWAYS_RUN_ICELAKE ((SIMDJSON_IMPLEMENTATION_ICELAKE) && (__AVX2__) && (__BMI__) && (__PCLMUL__) && (__LZCNT__) && (__AVX512F__) && (__AVX512DQ__) && (__AVX512CD__) && (__AVX512BW__) && (__AVX512VL__) && (__AVX512VBMI2__)) +#endif + +// Default Haswell to on if this is x86-64. Even if we're not compiled for it, it could be selected +// at runtime. +#ifndef SIMDJSON_IMPLEMENTATION_HASWELL +#if SIMDJSON_CAN_ALWAYS_RUN_ICELAKE +// if icelake is always available, never enable haswell. +#define SIMDJSON_IMPLEMENTATION_HASWELL 0 +#else +#define SIMDJSON_IMPLEMENTATION_HASWELL SIMDJSON_IS_X86_64 +#endif +#endif +#ifdef _MSC_VER +// To see why (__BMI__) && (__PCLMUL__) && (__LZCNT__) are not part of this next line, see +// https://github.com/simdjson/simdjson/issues/1247 +#define SIMDJSON_CAN_ALWAYS_RUN_HASWELL ((SIMDJSON_IMPLEMENTATION_HASWELL) && (SIMDJSON_IS_X86_64) && (__AVX2__)) +#else +#define SIMDJSON_CAN_ALWAYS_RUN_HASWELL ((SIMDJSON_IMPLEMENTATION_HASWELL) && (SIMDJSON_IS_X86_64) && (__AVX2__) && (__BMI__) && (__PCLMUL__) && (__LZCNT__)) +#endif + +// Default Westmere to on if this is x86-64. +#ifndef SIMDJSON_IMPLEMENTATION_WESTMERE +#if SIMDJSON_CAN_ALWAYS_RUN_ICELAKE || SIMDJSON_CAN_ALWAYS_RUN_HASWELL +// if icelake or haswell are always available, never enable westmere. +#define SIMDJSON_IMPLEMENTATION_WESTMERE 0 +#else +#define SIMDJSON_IMPLEMENTATION_WESTMERE SIMDJSON_IS_X86_64 +#endif +#endif +#define SIMDJSON_CAN_ALWAYS_RUN_WESTMERE (SIMDJSON_IMPLEMENTATION_WESTMERE && SIMDJSON_IS_X86_64 && __SSE4_2__ && __PCLMUL__) + +#ifndef SIMDJSON_IMPLEMENTATION_PPC64 +#define SIMDJSON_IMPLEMENTATION_PPC64 (SIMDJSON_IS_PPC64 && SIMDJSON_IS_PPC64_VMX) +#endif +#define SIMDJSON_CAN_ALWAYS_RUN_PPC64 SIMDJSON_IMPLEMENTATION_PPC64 && SIMDJSON_IS_PPC64 && SIMDJSON_IS_PPC64_VMX + +// Default Fallback to on unless a builtin implementation has already been selected. +#ifndef SIMDJSON_IMPLEMENTATION_FALLBACK +#if SIMDJSON_CAN_ALWAYS_RUN_ARM64 || SIMDJSON_CAN_ALWAYS_RUN_ICELAKE || SIMDJSON_CAN_ALWAYS_RUN_HASWELL || SIMDJSON_CAN_ALWAYS_RUN_WESTMERE || SIMDJSON_CAN_ALWAYS_RUN_PPC64 +// if anything at all except fallback can always run, then disable fallback. +#define SIMDJSON_IMPLEMENTATION_FALLBACK 0 +#else +#define SIMDJSON_IMPLEMENTATION_FALLBACK 1 +#endif +#endif +#define SIMDJSON_CAN_ALWAYS_RUN_FALLBACK SIMDJSON_IMPLEMENTATION_FALLBACK + +// Determine the best builtin implementation +#ifndef SIMDJSON_BUILTIN_IMPLEMENTATION + +#if SIMDJSON_CAN_ALWAYS_RUN_ICELAKE +#define SIMDJSON_BUILTIN_IMPLEMENTATION icelake +#elif SIMDJSON_CAN_ALWAYS_RUN_HASWELL +#define SIMDJSON_BUILTIN_IMPLEMENTATION haswell +#elif SIMDJSON_CAN_ALWAYS_RUN_WESTMERE +#define SIMDJSON_BUILTIN_IMPLEMENTATION westmere +#elif SIMDJSON_CAN_ALWAYS_RUN_ARM64 +#define SIMDJSON_BUILTIN_IMPLEMENTATION arm64 +#elif SIMDJSON_CAN_ALWAYS_RUN_PPC64 +#define SIMDJSON_BUILTIN_IMPLEMENTATION ppc64 +#elif SIMDJSON_CAN_ALWAYS_RUN_FALLBACK +#define SIMDJSON_BUILTIN_IMPLEMENTATION fallback +#else +#error "All possible implementations (including fallback) have been disabled! simdjson will not run." +#endif + +#endif // SIMDJSON_BUILTIN_IMPLEMENTATION + +#define SIMDJSON_BUILTIN_IMPLEMENTATION_ID SIMDJSON_IMPLEMENTATION_ID_FOR(SIMDJSON_BUILTIN_IMPLEMENTATION) +#define SIMDJSON_BUILTIN_IMPLEMENTATION_IS(IMPL) SIMDJSON_BUILTIN_IMPLEMENTATION_ID == SIMDJSON_IMPLEMENTATION_ID_FOR(IMPL) + +#endif // SIMDJSON_IMPLEMENTATION_DETECTION_H +/* end file simdjson/implementation_detection.h */ + +namespace simdjson { +#if SIMDJSON_BUILTIN_IMPLEMENTATION_IS(arm64) + namespace arm64 {} +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(fallback) + namespace fallback {} +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(haswell) + namespace haswell {} +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(icelake) + namespace icelake {} +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(ppc64) + namespace ppc64 {} +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(westmere) + namespace westmere {} +#else +#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION +#endif + + /** + * Represents the best statically linked simdjson implementation that can be used by the compiling + * program. + * + * Detects what options the program is compiled against, and picks the minimum implementation that + * will work on any computer that can run the program. For example, if you compile with g++ + * -march=westmere, it will pick the westmere implementation. The haswell implementation will + * still be available, and can be selected at runtime, but the builtin implementation (and any + * code that uses it) will use westmere. + */ + namespace builtin = SIMDJSON_BUILTIN_IMPLEMENTATION; +} // namespace simdjson + +#endif // SIMDJSON_BUILTIN_BASE_H +/* end file simdjson/builtin/base.h */ +/* including simdjson/builtin/implementation.h: #include "simdjson/builtin/implementation.h" */ +/* begin file simdjson/builtin/implementation.h */ +#ifndef SIMDJSON_BUILTIN_IMPLEMENTATION_H +#define SIMDJSON_BUILTIN_IMPLEMENTATION_H + +/* skipped duplicate #include "simdjson/builtin/base.h" */ + +/* including simdjson/generic/dependencies.h: #include "simdjson/generic/dependencies.h" */ +/* begin file simdjson/generic/dependencies.h */ +#ifdef SIMDJSON_CONDITIONAL_INCLUDE +#error simdjson/generic/dependencies.h must be included before defining SIMDJSON_CONDITIONAL_INCLUDE! +#endif + +#ifndef SIMDJSON_GENERIC_DEPENDENCIES_H +#define SIMDJSON_GENERIC_DEPENDENCIES_H + +// Internal headers needed for generics. +// All includes referencing simdjson headers *not* under simdjson/generic must be here! +// Otherwise, amalgamation will fail. +/* skipped duplicate #include "simdjson/base.h" */ +/* skipped duplicate #include "simdjson/implementation.h" */ +/* skipped duplicate #include "simdjson/implementation_detection.h" */ +/* including simdjson/internal/instruction_set.h: #include "simdjson/internal/instruction_set.h" */ +/* begin file simdjson/internal/instruction_set.h */ +/* From +https://github.com/endorno/pytorch/blob/master/torch/lib/TH/generic/simd/simd.h +Highly modified. + +Copyright (c) 2016- Facebook, Inc (Adam Paszke) +Copyright (c) 2014- Facebook, Inc (Soumith Chintala) +Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert) +Copyright (c) 2012-2014 Deepmind Technologies (Koray Kavukcuoglu) +Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu) +Copyright (c) 2011-2013 NYU (Clement Farabet) +Copyright (c) 2006-2010 NEC Laboratories America (Ronan Collobert, Leon Bottou, +Iain Melvin, Jason Weston) Copyright (c) 2006 Idiap Research Institute +(Samy Bengio) Copyright (c) 2001-2004 Idiap Research Institute (Ronan Collobert, +Samy Bengio, Johnny Mariethoz) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the names of Facebook, Deepmind Technologies, NYU, NEC Laboratories +America and IDIAP Research Institute nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef SIMDJSON_INTERNAL_INSTRUCTION_SET_H +#define SIMDJSON_INTERNAL_INSTRUCTION_SET_H + +namespace simdjson { +namespace internal { + +enum instruction_set { + DEFAULT = 0x0, + NEON = 0x1, + AVX2 = 0x4, + SSE42 = 0x8, + PCLMULQDQ = 0x10, + BMI1 = 0x20, + BMI2 = 0x40, + ALTIVEC = 0x80, + AVX512F = 0x100, + AVX512DQ = 0x200, + AVX512IFMA = 0x400, + AVX512PF = 0x800, + AVX512ER = 0x1000, + AVX512CD = 0x2000, + AVX512BW = 0x4000, + AVX512VL = 0x8000, + AVX512VBMI2 = 0x10000 +}; + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_INSTRUCTION_SET_H +/* end file simdjson/internal/instruction_set.h */ +/* skipped duplicate #include "simdjson/internal/dom_parser_implementation.h" */ +/* including simdjson/internal/jsoncharutils_tables.h: #include "simdjson/internal/jsoncharutils_tables.h" */ +/* begin file simdjson/internal/jsoncharutils_tables.h */ +#ifndef SIMDJSON_INTERNAL_JSONCHARUTILS_TABLES_H +#define SIMDJSON_INTERNAL_JSONCHARUTILS_TABLES_H + +/* skipped duplicate #include "simdjson/base.h" */ + +#ifdef JSON_TEST_STRINGS +void found_string(const uint8_t *buf, const uint8_t *parsed_begin, + const uint8_t *parsed_end); +void found_bad_string(const uint8_t *buf); +#endif + +namespace simdjson { +namespace internal { +// structural chars here are +// they are { 0x7b } 0x7d : 0x3a [ 0x5b ] 0x5d , 0x2c (and NULL) +// we are also interested in the four whitespace characters +// space 0x20, linefeed 0x0a, horizontal tab 0x09 and carriage return 0x0d + +extern SIMDJSON_DLLIMPORTEXPORT const bool structural_or_whitespace_negated[256]; +extern SIMDJSON_DLLIMPORTEXPORT const bool structural_or_whitespace[256]; +extern SIMDJSON_DLLIMPORTEXPORT const uint32_t digit_to_val32[886]; + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_JSONCHARUTILS_TABLES_H +/* end file simdjson/internal/jsoncharutils_tables.h */ +/* including simdjson/internal/numberparsing_tables.h: #include "simdjson/internal/numberparsing_tables.h" */ +/* begin file simdjson/internal/numberparsing_tables.h */ +#ifndef SIMDJSON_INTERNAL_NUMBERPARSING_TABLES_H +#define SIMDJSON_INTERNAL_NUMBERPARSING_TABLES_H + +/* skipped duplicate #include "simdjson/base.h" */ + +namespace simdjson { +namespace internal { +/** + * The smallest non-zero float (binary64) is 2^-1074. + * We take as input numbers of the form w x 10^q where w < 2^64. + * We have that w * 10^-343 < 2^(64-344) 5^-343 < 2^-1076. + * However, we have that + * (2^64-1) * 10^-342 = (2^64-1) * 2^-342 * 5^-342 > 2^-1074. + * Thus it is possible for a number of the form w * 10^-342 where + * w is a 64-bit value to be a non-zero floating-point number. + ********* + * Any number of form w * 10^309 where w>= 1 is going to be + * infinite in binary64 so we never need to worry about powers + * of 5 greater than 308. + */ +constexpr int smallest_power = -342; +constexpr int largest_power = 308; + +/** + * Represents a 128-bit value. + * low: least significant 64 bits. + * high: most significant 64 bits. + */ +struct value128 { + uint64_t low; + uint64_t high; +}; + + +// Precomputed powers of ten from 10^0 to 10^22. These +// can be represented exactly using the double type. +extern SIMDJSON_DLLIMPORTEXPORT const double power_of_ten[]; + + +/** + * When mapping numbers from decimal to binary, + * we go from w * 10^q to m * 2^p but we have + * 10^q = 5^q * 2^q, so effectively + * we are trying to match + * w * 2^q * 5^q to m * 2^p. Thus the powers of two + * are not a concern since they can be represented + * exactly using the binary notation, only the powers of five + * affect the binary significand. + */ + + +// The truncated powers of five from 5^-342 all the way to 5^308 +// The mantissa is truncated to 128 bits, and +// never rounded up. Uses about 10KB. +extern SIMDJSON_DLLIMPORTEXPORT const uint64_t power_of_five_128[]; +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_NUMBERPARSING_TABLES_H +/* end file simdjson/internal/numberparsing_tables.h */ +/* including simdjson/internal/simdprune_tables.h: #include "simdjson/internal/simdprune_tables.h" */ +/* begin file simdjson/internal/simdprune_tables.h */ +#ifndef SIMDJSON_INTERNAL_SIMDPRUNE_TABLES_H +#define SIMDJSON_INTERNAL_SIMDPRUNE_TABLES_H + +/* skipped duplicate #include "simdjson/base.h" */ + +#include + +namespace simdjson { // table modified and copied from +namespace internal { // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable + +extern SIMDJSON_DLLIMPORTEXPORT const unsigned char BitsSetTable256mul2[256]; + +extern SIMDJSON_DLLIMPORTEXPORT const uint8_t pshufb_combine_table[272]; + +// 256 * 8 bytes = 2kB, easily fits in cache. +extern SIMDJSON_DLLIMPORTEXPORT const uint64_t thintable_epi8[256]; + +} // namespace internal +} // namespace simdjson + +#endif // SIMDJSON_INTERNAL_SIMDPRUNE_TABLES_H +/* end file simdjson/internal/simdprune_tables.h */ + +#endif // SIMDJSON_GENERIC_DEPENDENCIES_H +/* end file simdjson/generic/dependencies.h */ + +/* defining SIMDJSON_CONDITIONAL_INCLUDE */ +#define SIMDJSON_CONDITIONAL_INCLUDE + +#if SIMDJSON_BUILTIN_IMPLEMENTATION_IS(arm64) +/* including simdjson/arm64/implementation.h: #include "simdjson/arm64/implementation.h" */ +/* begin file simdjson/arm64/implementation.h */ +#ifndef SIMDJSON_ARM64_IMPLEMENTATION_H +#define SIMDJSON_ARM64_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation("arm64", "ARM NEON", internal::instruction_set::NEON) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_IMPLEMENTATION_H +/* end file simdjson/arm64/implementation.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(fallback) +/* including simdjson/fallback/implementation.h: #include "simdjson/fallback/implementation.h" */ +/* begin file simdjson/fallback/implementation.h */ +#ifndef SIMDJSON_FALLBACK_IMPLEMENTATION_H +#define SIMDJSON_FALLBACK_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation( + "fallback", + "Generic fallback implementation", + 0 + ) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_IMPLEMENTATION_H +/* end file simdjson/fallback/implementation.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(haswell) +/* including simdjson/haswell/implementation.h: #include "simdjson/haswell/implementation.h" */ +/* begin file simdjson/haswell/implementation.h */ +#ifndef SIMDJSON_HASWELL_IMPLEMENTATION_H +#define SIMDJSON_HASWELL_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_HASWELL +namespace simdjson { +namespace haswell { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation( + "haswell", + "Intel/AMD AVX2", + internal::instruction_set::AVX2 | internal::instruction_set::PCLMULQDQ | internal::instruction_set::BMI1 | internal::instruction_set::BMI2 + ) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_IMPLEMENTATION_H +/* end file simdjson/haswell/implementation.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(icelake) +/* including simdjson/icelake/implementation.h: #include "simdjson/icelake/implementation.h" */ +/* begin file simdjson/icelake/implementation.h */ +#ifndef SIMDJSON_ICELAKE_IMPLEMENTATION_H +#define SIMDJSON_ICELAKE_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_ICELAKE +namespace simdjson { +namespace icelake { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation( + "icelake", + "Intel/AMD AVX512", + internal::instruction_set::AVX2 | internal::instruction_set::PCLMULQDQ | internal::instruction_set::BMI1 | internal::instruction_set::BMI2 | internal::instruction_set::AVX512F | internal::instruction_set::AVX512DQ | internal::instruction_set::AVX512CD | internal::instruction_set::AVX512BW | internal::instruction_set::AVX512VL | internal::instruction_set::AVX512VBMI2 + ) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_IMPLEMENTATION_H +/* end file simdjson/icelake/implementation.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(ppc64) +/* including simdjson/ppc64/implementation.h: #include "simdjson/ppc64/implementation.h" */ +/* begin file simdjson/ppc64/implementation.h */ +#ifndef SIMDJSON_PPC64_IMPLEMENTATION_H +#define SIMDJSON_PPC64_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +/** + * Implementation for ALTIVEC (PPC64). + */ +namespace ppc64 { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() + : simdjson::implementation("ppc64", "PPC64 ALTIVEC", + internal::instruction_set::ALTIVEC) {} + + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, size_t max_length, + std::unique_ptr &dst) + const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, + uint8_t *dst, + size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, + size_t len) const noexcept final; +}; + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_IMPLEMENTATION_H +/* end file simdjson/ppc64/implementation.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(westmere) +/* including simdjson/westmere/implementation.h: #include "simdjson/westmere/implementation.h" */ +/* begin file simdjson/westmere/implementation.h */ +#ifndef SIMDJSON_WESTMERE_IMPLEMENTATION_H +#define SIMDJSON_WESTMERE_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/instruction_set.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_WESTMERE +namespace simdjson { +namespace westmere { + +/** + * @private + */ +class implementation final : public simdjson::implementation { +public: + simdjson_inline implementation() : simdjson::implementation("westmere", "Intel/AMD SSE4.2", internal::instruction_set::SSE42 | internal::instruction_set::PCLMULQDQ) {} + simdjson_warn_unused error_code create_dom_parser_implementation( + size_t capacity, + size_t max_length, + std::unique_ptr& dst + ) const noexcept final; + simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final; + simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final; +}; + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_IMPLEMENTATION_H +/* end file simdjson/westmere/implementation.h */ +#else +#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION +#endif + +/* undefining SIMDJSON_CONDITIONAL_INCLUDE */ +#undef SIMDJSON_CONDITIONAL_INCLUDE + +namespace simdjson { + /** + * Function which returns a pointer to an implementation matching the "builtin" implementation. + * The builtin implementation is the best statically linked simdjson implementation that can be used by the compiling + * program. If you compile with g++ -march=haswell, this will return the haswell implementation. + * It is handy to be able to check what builtin was used: builtin_implementation()->name(). + */ + const implementation * builtin_implementation(); +} // namespace simdjson + +#endif // SIMDJSON_BUILTIN_IMPLEMENTATION_H +/* end file simdjson/builtin/implementation.h */ + +/* skipped duplicate #include "simdjson/generic/dependencies.h" */ + +/* defining SIMDJSON_CONDITIONAL_INCLUDE */ +#define SIMDJSON_CONDITIONAL_INCLUDE + +#if SIMDJSON_BUILTIN_IMPLEMENTATION_IS(arm64) +/* including simdjson/arm64.h: #include "simdjson/arm64.h" */ +/* begin file simdjson/arm64.h */ +#ifndef SIMDJSON_ARM64_H +#define SIMDJSON_ARM64_H + +/* including simdjson/arm64/begin.h: #include "simdjson/arm64/begin.h" */ +/* begin file simdjson/arm64/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "arm64" */ +#define SIMDJSON_IMPLEMENTATION arm64 +/* including simdjson/arm64/base.h: #include "simdjson/arm64/base.h" */ +/* begin file simdjson/arm64/base.h */ +#ifndef SIMDJSON_ARM64_BASE_H +#define SIMDJSON_ARM64_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Implementation for NEON (ARMv8). + */ +namespace arm64 { + +class implementation; + +namespace { +namespace simd { +template struct simd8; +template struct simd8x64; +} // namespace simd +} // unnamed namespace + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_BASE_H +/* end file simdjson/arm64/base.h */ +/* including simdjson/arm64/intrinsics.h: #include "simdjson/arm64/intrinsics.h" */ +/* begin file simdjson/arm64/intrinsics.h */ +#ifndef SIMDJSON_ARM64_INTRINSICS_H +#define SIMDJSON_ARM64_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This should be the correct header whether +// you use visual studio or other compilers. +#include + +static_assert(sizeof(uint8x16_t) <= simdjson::SIMDJSON_PADDING, "insufficient padding for arm64"); + +#endif // SIMDJSON_ARM64_INTRINSICS_H +/* end file simdjson/arm64/intrinsics.h */ +/* including simdjson/arm64/bitmanipulation.h: #include "simdjson/arm64/bitmanipulation.h" */ +/* begin file simdjson/arm64/bitmanipulation.h */ +#ifndef SIMDJSON_ARM64_BITMANIPULATION_H +#define SIMDJSON_ARM64_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num-1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int count_ones(uint64_t input_num) { + return vaddv_u8(vcnt_u8(vcreate_u8(input_num))); +} + + +#if defined(__GNUC__) // catches clang and gcc +/** + * ARM has a fast 64-bit "bit reversal function" that is handy. However, + * it is not generally available as an intrinsic function under Visual + * Studio (though this might be changing). Even under clang/gcc, we + * apparently need to invoke inline assembly. + */ +/* + * We use SIMDJSON_PREFER_REVERSE_BITS as a hint that algorithms that + * work well with bit reversal may use it. + */ +#define SIMDJSON_PREFER_REVERSE_BITS 1 + +/* reverse the bits */ +simdjson_inline uint64_t reverse_bits(uint64_t input_num) { + uint64_t rev_bits; + __asm("rbit %0, %1" : "=r"(rev_bits) : "r"(input_num)); + return rev_bits; +} + +/** + * Flips bit at index 63 - lz. Thus if you have 'leading_zeroes' leading zeroes, + * then this will set to zero the leading bit. It is possible for leading_zeroes to be + * greating or equal to 63 in which case we trigger undefined behavior, but the output + * of such undefined behavior is never used. + **/ +SIMDJSON_NO_SANITIZE_UNDEFINED +simdjson_inline uint64_t zero_leading_bit(uint64_t rev_bits, int leading_zeroes) { + return rev_bits ^ (uint64_t(0x8000000000000000) >> leading_zeroes); +} + +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + *result = value1 + value2; + return *result < value1; +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_BITMANIPULATION_H +/* end file simdjson/arm64/bitmanipulation.h */ +/* including simdjson/arm64/bitmask.h: #include "simdjson/arm64/bitmask.h" */ +/* begin file simdjson/arm64/bitmask.h */ +#ifndef SIMDJSON_ARM64_BITMASK_H +#define SIMDJSON_ARM64_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(uint64_t bitmask) { + ///////////// + // We could do this with PMULL, but it is apparently slow. + // + //#ifdef __ARM_FEATURE_CRYPTO // some ARM processors lack this extension + //return vmull_p64(-1ULL, bitmask); + //#else + // Analysis by @sebpop: + // When diffing the assembly for src/stage1_find_marks.cpp I see that the eors are all spread out + // in between other vector code, so effectively the extra cycles of the sequence do not matter + // because the GPR units are idle otherwise and the critical path is on the FP side. + // Also the PMULL requires two extra fmovs: GPR->FP (3 cycles in N1, 5 cycles in A72 ) + // and FP->GPR (2 cycles on N1 and 5 cycles on A72.) + /////////// + bitmask ^= bitmask << 1; + bitmask ^= bitmask << 2; + bitmask ^= bitmask << 4; + bitmask ^= bitmask << 8; + bitmask ^= bitmask << 16; + bitmask ^= bitmask << 32; + return bitmask; +} + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif +/* end file simdjson/arm64/bitmask.h */ +/* including simdjson/arm64/numberparsing_defs.h: #include "simdjson/arm64/numberparsing_defs.h" */ +/* begin file simdjson/arm64/numberparsing_defs.h */ +#ifndef SIMDJSON_ARM64_NUMBERPARSING_DEFS_H +#define SIMDJSON_ARM64_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +#if _M_ARM64 +// __umulh requires intrin.h +#include +#endif // _M_ARM64 + +namespace simdjson { +namespace arm64 { +namespace numberparsing { + +// we don't have SSE, so let us use a scalar function +// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + uint64_t val; + std::memcpy(&val, chars, sizeof(uint64_t)); + val = (val & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8; + val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16; + return uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32); +} + +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace arm64 +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_ARM64_NUMBERPARSING_DEFS_H +/* end file simdjson/arm64/numberparsing_defs.h */ +/* including simdjson/arm64/simd.h: #include "simdjson/arm64/simd.h" */ +/* begin file simdjson/arm64/simd.h */ +#ifndef SIMDJSON_ARM64_SIMD_H +#define SIMDJSON_ARM64_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace simd { + +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO +namespace { +// Start of private section with Visual Studio workaround + + +#ifndef simdjson_make_uint8x16_t +#define simdjson_make_uint8x16_t(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \ + x13, x14, x15, x16) \ + ([=]() { \ + uint8_t array[16] = {x1, x2, x3, x4, x5, x6, x7, x8, \ + x9, x10, x11, x12, x13, x14, x15, x16}; \ + return vld1q_u8(array); \ + }()) +#endif +#ifndef simdjson_make_int8x16_t +#define simdjson_make_int8x16_t(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \ + x13, x14, x15, x16) \ + ([=]() { \ + int8_t array[16] = {x1, x2, x3, x4, x5, x6, x7, x8, \ + x9, x10, x11, x12, x13, x14, x15, x16}; \ + return vld1q_s8(array); \ + }()) +#endif + +#ifndef simdjson_make_uint8x8_t +#define simdjson_make_uint8x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + uint8_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1_u8(array); \ + }()) +#endif +#ifndef simdjson_make_int8x8_t +#define simdjson_make_int8x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + int8_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1_s8(array); \ + }()) +#endif +#ifndef simdjson_make_uint16x8_t +#define simdjson_make_uint16x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + uint16_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1q_u16(array); \ + }()) +#endif +#ifndef simdjson_make_int16x8_t +#define simdjson_make_int16x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + int16_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1q_s16(array); \ + }()) +#endif + +// End of private section with Visual Studio workaround +} // namespace +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO + + + template + struct simd8; + + // + // Base class of simd8 and simd8, both of which use uint8x16_t internally. + // + template> + struct base_u8 { + uint8x16_t value; + static const int SIZE = sizeof(value); + + // Conversion from/to SIMD register + simdjson_inline base_u8(const uint8x16_t _value) : value(_value) {} + simdjson_inline operator const uint8x16_t&() const { return this->value; } + simdjson_inline operator uint8x16_t&() { return this->value; } + + // Bit operations + simdjson_inline simd8 operator|(const simd8 other) const { return vorrq_u8(*this, other); } + simdjson_inline simd8 operator&(const simd8 other) const { return vandq_u8(*this, other); } + simdjson_inline simd8 operator^(const simd8 other) const { return veorq_u8(*this, other); } + simdjson_inline simd8 bit_andnot(const simd8 other) const { return vbicq_u8(*this, other); } + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + simdjson_inline simd8& operator|=(const simd8 other) { auto this_cast = static_cast*>(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline simd8& operator&=(const simd8 other) { auto this_cast = static_cast*>(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline simd8& operator^=(const simd8 other) { auto this_cast = static_cast*>(this); *this_cast = *this_cast ^ other; return *this_cast; } + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return vceqq_u8(lhs, rhs); } + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return vextq_u8(prev_chunk, *this, 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base_u8 { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + static simdjson_inline simd8 splat(bool _value) { return vmovq_n_u8(uint8_t(-(!!_value))); } + + simdjson_inline simd8(const uint8x16_t _value) : base_u8(_value) {} + // False constructor + simdjson_inline simd8() : simd8(vdupq_n_u8(0)) {} + // Splat constructor + simdjson_inline simd8(bool _value) : simd8(splat(_value)) {} + + // We return uint32_t instead of uint16_t because that seems to be more efficient for most + // purposes (cutting it down to uint16_t costs performance in some compilers). + simdjson_inline uint32_t to_bitmask() const { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + const uint8x16_t bit_mask = simdjson_make_uint8x16_t(0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80); +#else + const uint8x16_t bit_mask = {0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80}; +#endif + auto minput = *this & bit_mask; + uint8x16_t tmp = vpaddq_u8(minput, minput); + tmp = vpaddq_u8(tmp, tmp); + tmp = vpaddq_u8(tmp, tmp); + return vgetq_lane_u16(vreinterpretq_u16_u8(tmp), 0); + } + simdjson_inline bool any() const { return vmaxvq_u8(*this) != 0; } + }; + + // Unsigned bytes + template<> + struct simd8: base_u8 { + static simdjson_inline uint8x16_t splat(uint8_t _value) { return vmovq_n_u8(_value); } + static simdjson_inline uint8x16_t zero() { return vdupq_n_u8(0); } + static simdjson_inline uint8x16_t load(const uint8_t* values) { return vld1q_u8(values); } + + simdjson_inline simd8(const uint8x16_t _value) : base_u8(_value) {} + // Zero constructor + simdjson_inline simd8() : simd8(zero()) {} + // Array constructor + simdjson_inline simd8(const uint8_t values[16]) : simd8(load(values)) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Member-by-member initialization +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(simdjson_make_uint8x16_t( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} +#else + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(uint8x16_t{ + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + }) {} +#endif + + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Store to array + simdjson_inline void store(uint8_t dst[16]) const { return vst1q_u8(dst, *this); } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return vqaddq_u8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return vqsubq_u8(*this, other); } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return vaddq_u8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return vsubq_u8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *this; } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *this; } + + // Order-specific operations + simdjson_inline uint8_t max_val() const { return vmaxvq_u8(*this); } + simdjson_inline uint8_t min_val() const { return vminvq_u8(*this); } + simdjson_inline simd8 max_val(const simd8 other) const { return vmaxq_u8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return vminq_u8(*this, other); } + simdjson_inline simd8 operator<=(const simd8 other) const { return vcleq_u8(*this, other); } + simdjson_inline simd8 operator>=(const simd8 other) const { return vcgeq_u8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return vcltq_u8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return vcgtq_u8(*this, other); } + // Same as >, but instead of guaranteeing all 1's == true, false = 0 and true = nonzero. For ARM, returns all 1's. + simdjson_inline simd8 gt_bits(const simd8 other) const { return simd8(*this > other); } + // Same as <, but instead of guaranteeing all 1's == true, false = 0 and true = nonzero. For ARM, returns all 1's. + simdjson_inline simd8 lt_bits(const simd8 other) const { return simd8(*this < other); } + + // Bit-specific operations + simdjson_inline simd8 any_bits_set(simd8 bits) const { return vtstq_u8(*this, bits); } + simdjson_inline bool any_bits_set_anywhere() const { return this->max_val() != 0; } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return (*this & bits).any_bits_set_anywhere(); } + template + simdjson_inline simd8 shr() const { return vshrq_n_u8(*this, N); } + template + simdjson_inline simd8 shl() const { return vshlq_n_u8(*this, N); } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return lookup_table.apply_lookup_16_to(*this); + } + + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 16 - count_ones(mask) bytes of the result are significant but 16 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint16_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + uint64x2_t shufmask64 = {thintable_epi8[mask1], thintable_epi8[mask2]}; + uint8x16_t shufmask = vreinterpretq_u8_u64(shufmask64); + // we increment by 0x08 the second half of the mask +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + uint8x16_t inc = simdjson_make_uint8x16_t(0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08); +#else + uint8x16_t inc = {0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; +#endif + shufmask = vaddq_u8(shufmask, inc); + // this is the version "nearly pruned" + uint8x16_t pruned = vqtbl1q_u8(*this, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + uint8x16_t compactmask = vld1q_u8(reinterpret_cast(pshufb_combine_table + pop1 * 8)); + uint8x16_t answer = vqtbl1q_u8(pruned, compactmask); + vst1q_u8(reinterpret_cast(output), answer); + } + + // Copies all bytes corresponding to a 0 in the low half of the mask (interpreted as a + // bitset) to output1, then those corresponding to a 0 in the high half to output2. + template + simdjson_inline void compress_halves(uint16_t mask, L *output1, L *output2) const { + using internal::thintable_epi8; + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + uint8x8_t compactmask1 = vcreate_u8(thintable_epi8[mask1]); + uint8x8_t compactmask2 = vcreate_u8(thintable_epi8[mask2]); + // we increment by 0x08 the second half of the mask +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + uint8x8_t inc = simdjson_make_uint8x8_t(0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08); +#else + uint8x8_t inc = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; +#endif + compactmask2 = vadd_u8(compactmask2, inc); + // store each result (with the second store possibly overlapping the first) + vst1_u8((uint8_t*)output1, vqtbl1_u8(*this, compactmask1)); + vst1_u8((uint8_t*)output2, vqtbl1_u8(*this, compactmask2)); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + + template + simdjson_inline simd8 apply_lookup_16_to(const simd8 original) { + return vqtbl1q_u8(*this, simd8(original)); + } + }; + + // Signed bytes + template<> + struct simd8 { + int8x16_t value; + + static simdjson_inline simd8 splat(int8_t _value) { return vmovq_n_s8(_value); } + static simdjson_inline simd8 zero() { return vdupq_n_s8(0); } + static simdjson_inline simd8 load(const int8_t values[16]) { return vld1q_s8(values); } + + // Conversion from/to SIMD register + simdjson_inline simd8(const int8x16_t _value) : value{_value} {} + simdjson_inline operator const int8x16_t&() const { return this->value; } + simdjson_inline operator int8x16_t&() { return this->value; } + + // Zero constructor + simdjson_inline simd8() : simd8(zero()) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {} + // Member-by-member initialization +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(simdjson_make_int8x16_t( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} +#else + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(int8x16_t{ + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + }) {} +#endif + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Store to array + simdjson_inline void store(int8_t dst[16]) const { return vst1q_s8(dst, *this); } + + // Explicit conversion to/from unsigned + // + // Under Visual Studio/ARM64 uint8x16_t and int8x16_t are apparently the same type. + // In theory, we could check this occurrence with std::same_as and std::enabled_if but it is C++14 + // and relatively ugly and hard to read. +#ifndef SIMDJSON_REGULAR_VISUAL_STUDIO + simdjson_inline explicit simd8(const uint8x16_t other): simd8(vreinterpretq_s8_u8(other)) {} +#endif + simdjson_inline explicit operator simd8() const { return vreinterpretq_u8_s8(this->value); } + + // Math + simdjson_inline simd8 operator+(const simd8 other) const { return vaddq_s8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return vsubq_s8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *this; } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *this; } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return vmaxq_s8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return vminq_s8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return vcgtq_s8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return vcltq_s8(*this, other); } + simdjson_inline simd8 operator==(const simd8 other) const { return vceqq_s8(*this, other); } + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return vextq_s8(prev_chunk, *this, 16 - N); + } + + // Perform a lookup assuming no value is larger than 16 + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return lookup_table.apply_lookup_16_to(*this); + } + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + + template + simdjson_inline simd8 apply_lookup_16_to(const simd8 original) { + return vqtbl1q_s8(*this, simd8(original)); + } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, "ARM kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, const simd8 chunk2, const simd8 chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+16), simd8::load(ptr+32), simd8::load(ptr+48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + this->chunks[2].store(ptr+sizeof(simd8)*2); + this->chunks[3].store(ptr+sizeof(simd8)*3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | (this->chunks[2] | this->chunks[3]); + } + + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + uint64_t popcounts = vget_lane_u64(vreinterpret_u64_u8(vcnt_u8(vcreate_u8(~mask))), 0); + // compute the prefix sum of the popcounts of each byte + uint64_t offsets = popcounts * 0x0101010101010101; + this->chunks[0].compress_halves(uint16_t(mask), output, &output[popcounts & 0xFF]); + this->chunks[1].compress_halves(uint16_t(mask >> 16), &output[(offsets >> 8) & 0xFF], &output[(offsets >> 16) & 0xFF]); + this->chunks[2].compress_halves(uint16_t(mask >> 32), &output[(offsets >> 24) & 0xFF], &output[(offsets >> 32) & 0xFF]); + this->chunks[3].compress_halves(uint16_t(mask >> 48), &output[(offsets >> 40) & 0xFF], &output[(offsets >> 48) & 0xFF]); + return offsets >> 56; + } + + simdjson_inline uint64_t to_bitmask() const { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + const uint8x16_t bit_mask = simdjson_make_uint8x16_t( + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 + ); +#else + const uint8x16_t bit_mask = { + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 + }; +#endif + // Add each of the elements next to each other, successively, to stuff each 8 byte mask into one. + uint8x16_t sum0 = vpaddq_u8(this->chunks[0] & bit_mask, this->chunks[1] & bit_mask); + uint8x16_t sum1 = vpaddq_u8(this->chunks[2] & bit_mask, this->chunks[3] & bit_mask); + sum0 = vpaddq_u8(sum0, sum1); + sum0 = vpaddq_u8(sum0, sum0); + return vgetq_lane_u64(vreinterpretq_u64_u8(sum0), 0); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask, + this->chunks[2] == mask, + this->chunks[3] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask, + this->chunks[2] <= mask, + this->chunks[3] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_SIMD_H +/* end file simdjson/arm64/simd.h */ +/* including simdjson/arm64/stringparsing_defs.h: #include "simdjson/arm64/stringparsing_defs.h" */ +/* begin file simdjson/arm64/stringparsing_defs.h */ +#ifndef SIMDJSON_ARM64_STRINGPARSING_DEFS_H +#define SIMDJSON_ARM64_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/simd.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return bs_bits != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 31 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v0(src); + simd8 v1(src + sizeof(v0)); + v0.store(dst); + v1.store(dst + sizeof(v0)); + + // Getting a 64-bit bitmask is much cheaper than multiple 16-bit bitmasks on ARM; therefore, we + // smash them together into a 64-byte mask and get the bitmask from there. + uint64_t bs_and_quote = simd8x64(v0 == '\\', v1 == '\\', v0 == '"', v1 == '"').to_bitmask(); + return { + uint32_t(bs_and_quote), // bs_bits + uint32_t(bs_and_quote >> 32) // quote_bits + }; +} + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_STRINGPARSING_DEFS_H +/* end file simdjson/arm64/stringparsing_defs.h */ + +#define SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT 1 +/* end file simdjson/arm64/begin.h */ +/* including simdjson/generic/amalgamated.h for arm64: #include "simdjson/generic/amalgamated.h" */ +/* begin file simdjson/generic/amalgamated.h for arm64 */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_DEPENDENCIES_H) +#error simdjson/generic/dependencies.h must be included before simdjson/generic/amalgamated.h! +#endif + +/* including simdjson/generic/base.h for arm64: #include "simdjson/generic/base.h" */ +/* begin file simdjson/generic/base.h for arm64 */ +#ifndef SIMDJSON_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): // If we haven't got an implementation yet, we're in the editor, editing a generic file! Just */ +/* amalgamation skipped (editor-only): // use the most advanced one we can so the most possible stuff can be tested. */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation_detection.h" */ +/* amalgamation skipped (editor-only): #if SIMDJSON_IMPLEMENTATION_ICELAKE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_HASWELL */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_WESTMERE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_ARM64 */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_PPC64 */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_FALLBACK */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/begin.h" */ +/* amalgamation skipped (editor-only): #else */ +/* amalgamation skipped (editor-only): #error "All possible implementations (including fallback) have been disabled! simdjson will not run." */ +/* amalgamation skipped (editor-only): #endif */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { + +struct open_container; +class dom_parser_implementation; + +/** + * The type of a JSON number + */ +enum class number_type { + floating_point_number=1, /// a binary64 number + signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + unsigned_integer /// a positive integer larger or equal to 1<<63 +}; + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_BASE_H +/* end file simdjson/generic/base.h for arm64 */ +/* including simdjson/generic/jsoncharutils.h for arm64: #include "simdjson/generic/jsoncharutils.h" */ +/* begin file simdjson/generic/jsoncharutils.h for arm64 */ +#ifndef SIMDJSON_GENERIC_JSONCHARUTILS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_JSONCHARUTILS_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/jsoncharutils_tables.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace jsoncharutils { + +// return non-zero if not a structural or whitespace char +// zero otherwise +simdjson_inline uint32_t is_not_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace_negated[c]; +} + +simdjson_inline uint32_t is_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace[c]; +} + +// returns a value with the high 16 bits set if not valid +// otherwise returns the conversion of the 4 hex digits at src into the bottom +// 16 bits of the 32-bit return register +// +// see +// https://lemire.me/blog/2019/04/17/parsing-short-hexadecimal-strings-efficiently/ +static inline uint32_t hex_to_u32_nocheck( + const uint8_t *src) { // strictly speaking, static inline is a C-ism + uint32_t v1 = internal::digit_to_val32[630 + src[0]]; + uint32_t v2 = internal::digit_to_val32[420 + src[1]]; + uint32_t v3 = internal::digit_to_val32[210 + src[2]]; + uint32_t v4 = internal::digit_to_val32[0 + src[3]]; + return v1 | v2 | v3 | v4; +} + +// given a code point cp, writes to c +// the utf-8 code, outputting the length in +// bytes, if the length is zero, the code point +// is invalid +// +// This can possibly be made faster using pdep +// and clz and table lookups, but JSON documents +// have few escaped code points, and the following +// function looks cheap. +// +// Note: we assume that surrogates are treated separately +// +simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) { + if (cp <= 0x7F) { + c[0] = uint8_t(cp); + return 1; // ascii + } + if (cp <= 0x7FF) { + c[0] = uint8_t((cp >> 6) + 192); + c[1] = uint8_t((cp & 63) + 128); + return 2; // universal plane + // Surrogates are treated elsewhere... + //} //else if (0xd800 <= cp && cp <= 0xdfff) { + // return 0; // surrogates // could put assert here + } else if (cp <= 0xFFFF) { + c[0] = uint8_t((cp >> 12) + 224); + c[1] = uint8_t(((cp >> 6) & 63) + 128); + c[2] = uint8_t((cp & 63) + 128); + return 3; + } else if (cp <= 0x10FFFF) { // if you know you have a valid code point, this + // is not needed + c[0] = uint8_t((cp >> 18) + 240); + c[1] = uint8_t(((cp >> 12) & 63) + 128); + c[2] = uint8_t(((cp >> 6) & 63) + 128); + c[3] = uint8_t((cp & 63) + 128); + return 4; + } + // will return 0 when the code point was too large. + return 0; // bad r +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +} // namespace jsoncharutils +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_JSONCHARUTILS_H +/* end file simdjson/generic/jsoncharutils.h for arm64 */ +/* including simdjson/generic/atomparsing.h for arm64: #include "simdjson/generic/atomparsing.h" */ +/* begin file simdjson/generic/atomparsing.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ATOMPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ATOMPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace arm64 { +namespace { +/// @private +namespace atomparsing { + +// The string_to_uint32 is exclusively used to map literal strings to 32-bit values. +// We use memcpy instead of a pointer cast to avoid undefined behaviors since we cannot +// be certain that the character pointer will be properly aligned. +// You might think that using memcpy makes this function expensive, but you'd be wrong. +// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false"); +// to the compile-time constant 1936482662. +simdjson_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; } + + +// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive. +// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about. +simdjson_warn_unused +simdjson_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) { + uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++) + static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes"); + std::memcpy(&srcval, src, sizeof(uint32_t)); + return srcval ^ string_to_uint32(atom); +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src) { + return (str4ncmp(src, "true") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_true_atom(src); } + else if (len == 4) { return !str4ncmp(src, "true"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src) { + return (str4ncmp(src+1, "alse") | jsoncharutils::is_not_structural_or_whitespace(src[5])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src, size_t len) { + if (len > 5) { return is_valid_false_atom(src); } + else if (len == 5) { return !str4ncmp(src+1, "alse"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src) { + return (str4ncmp(src, "null") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_null_atom(src); } + else if (len == 4) { return !str4ncmp(src, "null"); } + else { return false; } +} + +} // namespace atomparsing +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ATOMPARSING_H +/* end file simdjson/generic/atomparsing.h for arm64 */ +/* including simdjson/generic/dom_parser_implementation.h for arm64: #include "simdjson/generic/dom_parser_implementation.h" */ +/* begin file simdjson/generic/dom_parser_implementation.h for arm64 */ +#ifndef SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { + +// expectation: sizeof(open_container) = 64/8. +struct open_container { + uint32_t tape_index; // where, on the tape, does the scope ([,{) begins + uint32_t count; // how many elements in the scope +}; // struct open_container + +static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits"); + +class dom_parser_implementation final : public internal::dom_parser_implementation { +public: + /** Tape location of each open { or [ */ + std::unique_ptr open_containers{}; + /** Whether each open container is a [ or { */ + std::unique_ptr is_array{}; + /** Buffer passed to stage 1 */ + const uint8_t *buf{}; + /** Length passed to stage 1 */ + size_t len{0}; + /** Document passed to stage 2 */ + dom::document *doc{}; + + inline dom_parser_implementation() noexcept; + inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; + inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; + dom_parser_implementation(const dom_parser_implementation &) = delete; + dom_parser_implementation &operator=(const dom_parser_implementation &) = delete; + + simdjson_warn_unused error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage1(const uint8_t *buf, size_t len, stage1_mode partial) noexcept final; + simdjson_warn_unused error_code stage2(dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage2_next(dom::document &doc) noexcept final; + simdjson_warn_unused uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept final; + simdjson_warn_unused uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept final; + inline simdjson_warn_unused error_code set_capacity(size_t capacity) noexcept final; + inline simdjson_warn_unused error_code set_max_depth(size_t max_depth) noexcept final; +private: + simdjson_inline simdjson_warn_unused error_code set_capacity_stage1(size_t capacity); + +}; + +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { +namespace arm64 { + +inline dom_parser_implementation::dom_parser_implementation() noexcept = default; +inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; +inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; + +// Leaving these here so they can be inlined if so desired +inline simdjson_warn_unused error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept { + if(capacity > SIMDJSON_MAXSIZE_BYTES) { return CAPACITY; } + // Stage 1 index output + size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7; + structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] ); + if (!structural_indexes) { _capacity = 0; return MEMALLOC; } + structural_indexes[0] = 0; + n_structural_indexes = 0; + + _capacity = capacity; + return SUCCESS; +} + +inline simdjson_warn_unused error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept { + // Stage 2 stacks + open_containers.reset(new (std::nothrow) open_container[max_depth]); + is_array.reset(new (std::nothrow) bool[max_depth]); + if (!is_array || !open_containers) { _max_depth = 0; return MEMALLOC; } + + _max_depth = max_depth; + return SUCCESS; +} + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file simdjson/generic/dom_parser_implementation.h for arm64 */ +/* including simdjson/generic/implementation_simdjson_result_base.h for arm64: #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base.h for arm64 */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { + +// This is a near copy of include/error.h's implementation_simdjson_result_base, except it doesn't use std::pair +// so we can avoid inlining errors +// TODO reconcile these! +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + * + * This is a base class for implementations that want to add functions to the result type for + * chaining. + * + * Override like: + * + * struct simdjson_result : public internal::implementation_simdjson_result_base { + * simdjson_result() noexcept : internal::implementation_simdjson_result_base() {} + * simdjson_result(error_code error) noexcept : internal::implementation_simdjson_result_base(error) {} + * simdjson_result(T &&value) noexcept : internal::implementation_simdjson_result_base(std::forward(value)) {} + * simdjson_result(T &&value, error_code error) noexcept : internal::implementation_simdjson_result_base(value, error) {} + * // Your extra methods here + * } + * + * Then any method returning simdjson_result will be chainable with your methods. + */ +template +struct implementation_simdjson_result_base { + + /** + * Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline implementation_simdjson_result_base() noexcept = default; + + /** + * Create a new error result. + */ + simdjson_inline implementation_simdjson_result_base(error_code error) noexcept; + + /** + * Create a new successful result. + */ + simdjson_inline implementation_simdjson_result_base(T &&value) noexcept; + + /** + * Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline implementation_simdjson_result_base(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); + + +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T& value_unsafe() & noexcept; + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; +protected: + /** users should never directly access first and second. **/ + T first{}; /** Users should never directly access 'first'. **/ + error_code second{UNINITIALIZED}; /** Users should never directly access 'second'. **/ +}; // struct implementation_simdjson_result_base + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H +/* end file simdjson/generic/implementation_simdjson_result_base.h for arm64 */ +/* including simdjson/generic/numberparsing.h for arm64: #include "simdjson/generic/numberparsing.h" */ +/* begin file simdjson/generic/numberparsing.h for arm64 */ +#ifndef SIMDJSON_GENERIC_NUMBERPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_NUMBERPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include +#include + +namespace simdjson { +namespace arm64 { +namespace numberparsing { + +#ifdef JSON_TEST_NUMBERS +#define INVALID_NUMBER(SRC) (found_invalid_number((SRC)), NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (found_integer((VALUE), (SRC)), (WRITER).append_s64((VALUE))) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (found_unsigned_integer((VALUE), (SRC)), (WRITER).append_u64((VALUE))) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (found_float((VALUE), (SRC)), (WRITER).append_double((VALUE))) +#else +#define INVALID_NUMBER(SRC) (NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (WRITER).append_s64((VALUE)) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (WRITER).append_u64((VALUE)) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (WRITER).append_double((VALUE)) +#endif + +namespace { + +// Convert a mantissa, an exponent and a sign bit into an ieee64 double. +// The real_exponent needs to be in [0, 2046] (technically real_exponent = 2047 would be acceptable). +// The mantissa should be in [0,1<<53). The bit at index (1ULL << 52) while be zeroed. +simdjson_inline double to_double(uint64_t mantissa, uint64_t real_exponent, bool negative) { + double d; + mantissa &= ~(1ULL << 52); + mantissa |= real_exponent << 52; + mantissa |= ((static_cast(negative)) << 63); + std::memcpy(&d, &mantissa, sizeof(d)); + return d; +} + +// Attempts to compute i * 10^(power) exactly; and if "negative" is +// true, negate the result. +// This function will only work in some cases, when it does not work, success is +// set to false. This should work *most of the time* (like 99% of the time). +// We assume that power is in the [smallest_power, +// largest_power] interval: the caller is responsible for this check. +simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative, double &d) { + // we start with a fast path + // It was described in + // Clinger WD. How to read floating point numbers accurately. + // ACM SIGPLAN Notices. 1990 +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + // We cannot be certain that x/y is rounded to nearest. + if (0 <= power && power <= 22 && i <= 9007199254740991) +#else + if (-22 <= power && power <= 22 && i <= 9007199254740991) +#endif + { + // convert the integer into a double. This is lossless since + // 0 <= i <= 2^53 - 1. + d = double(i); + // + // The general idea is as follows. + // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then + // 1) Both s and p can be represented exactly as 64-bit floating-point + // values + // (binary64). + // 2) Because s and p can be represented exactly as floating-point values, + // then s * p + // and s / p will produce correctly rounded values. + // + if (power < 0) { + d = d / simdjson::internal::power_of_ten[-power]; + } else { + d = d * simdjson::internal::power_of_ten[power]; + } + if (negative) { + d = -d; + } + return true; + } + // When 22 < power && power < 22 + 16, we could + // hope for another, secondary fast path. It was + // described by David M. Gay in "Correctly rounded + // binary-decimal and decimal-binary conversions." (1990) + // If you need to compute i * 10^(22 + x) for x < 16, + // first compute i * 10^x, if you know that result is exact + // (e.g., when i * 10^x < 2^53), + // then you can still proceed and do (i * 10^x) * 10^22. + // Is this worth your time? + // You need 22 < power *and* power < 22 + 16 *and* (i * 10^(x-22) < 2^53) + // for this second fast path to work. + // If you you have 22 < power *and* power < 22 + 16, and then you + // optimistically compute "i * 10^(x-22)", there is still a chance that you + // have wasted your time if i * 10^(x-22) >= 2^53. It makes the use cases of + // this optimization maybe less common than we would like. Source: + // http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + // also used in RapidJSON: https://rapidjson.org/strtod_8h_source.html + + // The fast path has now failed, so we are failing back on the slower path. + + // In the slow path, we need to adjust i so that it is > 1<<63 which is always + // possible, except if i == 0, so we handle i == 0 separately. + if(i == 0) { + d = negative ? -0.0 : 0.0; + return true; + } + + + // The exponent is 1024 + 63 + power + // + floor(log(5**power)/log(2)). + // The 1024 comes from the ieee64 standard. + // The 63 comes from the fact that we use a 64-bit word. + // + // Computing floor(log(5**power)/log(2)) could be + // slow. Instead we use a fast function. + // + // For power in (-400,350), we have that + // (((152170 + 65536) * power ) >> 16); + // is equal to + // floor(log(5**power)/log(2)) + power when power >= 0 + // and it is equal to + // ceil(log(5**-power)/log(2)) + power when power < 0 + // + // The 65536 is (1<<16) and corresponds to + // (65536 * power) >> 16 ---> power + // + // ((152170 * power ) >> 16) is equal to + // floor(log(5**power)/log(2)) + // + // Note that this is not magic: 152170/(1<<16) is + // approximatively equal to log(5)/log(2). + // The 1<<16 value is a power of two; we could use a + // larger power of 2 if we wanted to. + // + int64_t exponent = (((152170 + 65536) * power) >> 16) + 1024 + 63; + + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(i); + i <<= lz; + + + // We are going to need to do some 64-bit arithmetic to get a precise product. + // We use a table lookup approach. + // It is safe because + // power >= smallest_power + // and power <= largest_power + // We recover the mantissa of the power, it has a leading 1. It is always + // rounded down. + // + // We want the most significant 64 bits of the product. We know + // this will be non-zero because the most significant bit of i is + // 1. + const uint32_t index = 2 * uint32_t(power - simdjson::internal::smallest_power); + // Optimization: It may be that materializing the index as a variable might confuse some compilers and prevent effective complex-addressing loads. (Done for code clarity.) + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); + // Both i and power_of_five_128[index] have their most significant bit set to 1 which + // implies that the either the most or the second most significant bit of the product + // is 1. We pack values in this manner for efficiency reasons: it maximizes the use + // we make of the product. It also makes it easy to reason about the product: there + // is 0 or 1 leading zero in the product. + + // Unless the least significant 9 bits of the high (64-bit) part of the full + // product are all 1s, then we know that the most significant 55 bits are + // exact and no further work is needed. Having 55 bits is necessary because + // we need 53 bits for the mantissa but we have to have one rounding bit and + // we can waste a bit if the most significant bit of the product is zero. + if((firstproduct.high & 0x1FF) == 0x1FF) { + // We want to compute i * 5^q, but only care about the top 55 bits at most. + // Consider the scenario where q>=0. Then 5^q may not fit in 64-bits. Doing + // the full computation is wasteful. So we do what is called a "truncated + // multiplication". + // We take the most significant 64-bits, and we put them in + // power_of_five_128[index]. Usually, that's good enough to approximate i * 5^q + // to the desired approximation using one multiplication. Sometimes it does not suffice. + // Then we store the next most significant 64 bits in power_of_five_128[index + 1], and + // then we get a better approximation to i * 5^q. + // + // That's for when q>=0. The logic for q<0 is somewhat similar but it is somewhat + // more complicated. + // + // There is an extra layer of complexity in that we need more than 55 bits of + // accuracy in the round-to-even scenario. + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if(secondproduct.high > firstproduct.low) { firstproduct.high++; } + // As it has been proven by Noble Mushtak and Daniel Lemire in "Fast Number Parsing Without + // Fallback" (https://arxiv.org/abs/2212.06644), at this point we are sure that the product + // is sufficiently accurate, and more computation is not needed. + } + uint64_t lower = firstproduct.low; + uint64_t upper = firstproduct.high; + // The final mantissa should be 53 bits with a leading 1. + // We shift it so that it occupies 54 bits with a leading 1. + /////// + uint64_t upperbit = upper >> 63; + uint64_t mantissa = upper >> (upperbit + 9); + lz += int(1 ^ upperbit); + + // Here we have mantissa < (1<<54). + int64_t real_exponent = exponent - lz; + if (simdjson_unlikely(real_exponent <= 0)) { // we have a subnormal? + // Here have that real_exponent <= 0 so -real_exponent >= 0 + if(-real_exponent + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure. + d = negative ? -0.0 : 0.0; + return true; + } + // next line is safe because -real_exponent + 1 < 0 + mantissa >>= -real_exponent + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0. + mantissa += (mantissa & 1); // round up + mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + real_exponent = (mantissa < (uint64_t(1) << 52)) ? 0 : 1; + d = to_double(mantissa, real_exponent, negative); + return true; + } + // We have to round to even. The "to even" part + // is only a problem when we are right in between two floats + // which we guard against. + // If we have lots of trailing zeros, we may fall right between two + // floating-point values. + // + // The round-to-even cases take the form of a number 2m+1 which is in (2^53,2^54] + // times a power of two. That is, it is right between a number with binary significand + // m and another number with binary significand m+1; and it must be the case + // that it cannot be represented by a float itself. + // + // We must have that w * 10 ^q == (2m+1) * 2^p for some power of two 2^p. + // Recall that 10^q = 5^q * 2^q. + // When q >= 0, we must have that (2m+1) is divible by 5^q, so 5^q <= 2^54. We have that + // 5^23 <= 2^54 and it is the last power of five to qualify, so q <= 23. + // When q<0, we have w >= (2m+1) x 5^{-q}. We must have that w<2^{64} so + // (2m+1) x 5^{-q} < 2^{64}. We have that 2m+1>2^{53}. Hence, we must have + // 2^{53} x 5^{-q} < 2^{64}. + // Hence we have 5^{-q} < 2^{11}$ or q>= -4. + // + // We require lower <= 1 and not lower == 0 because we could not prove that + // that lower == 0 is implied; but we could prove that lower <= 1 is a necessary and sufficient test. + if (simdjson_unlikely((lower <= 1) && (power >= -4) && (power <= 23) && ((mantissa & 3) == 1))) { + if((mantissa << (upperbit + 64 - 53 - 2)) == upper) { + mantissa &= ~1; // flip it so that we do not round up + } + } + + mantissa += mantissa & 1; + mantissa >>= 1; + + // Here we have mantissa < (1<<53), unless there was an overflow + if (mantissa >= (1ULL << 53)) { + ////////// + // This will happen when parsing values such as 7.2057594037927933e+16 + //////// + mantissa = (1ULL << 52); + real_exponent++; + } + mantissa &= ~(1ULL << 52); + // we have to check that real_exponent is in range, otherwise we bail out + if (simdjson_unlikely(real_exponent > 2046)) { + // We have an infinite value!!! We could actually throw an error here if we could. + return false; + } + d = to_double(mantissa, real_exponent, negative); + return true; +} + +// We call a fallback floating-point parser that might be slow. Note +// it will accept JSON numbers, but the JSON spec. is more restrictive so +// before you call parse_float_fallback, you need to have validated the input +// string with the JSON grammar. +// It will return an error (false) if the parsed number is infinite. +// The string parsing itself always succeeds. We know that there is at least +// one digit. +static bool parse_float_fallback(const uint8_t *ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +static bool parse_float_fallback(const uint8_t *ptr, const uint8_t *end_ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr), reinterpret_cast(end_ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +// check quickly whether the next 8 chars are made of digits +// at a glance, it looks better than Mula's +// http://0x80.pl/articles/swar-digits-validate.html +simdjson_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) { + uint64_t val; + // this can read up to 7 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(7 <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be bigger than 7"); + std::memcpy(&val, chars, 8); + // a branchy method might be faster: + // return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030) + // && (( (val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0 ) == + // 0x3030303030303030); + return (((val & 0xF0F0F0F0F0F0F0F0) | + (((val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4)) == + 0x3333333333333333); +} + +template +SIMDJSON_NO_SANITIZE_UNDEFINED // We deliberately allow overflow here and check later +simdjson_inline bool parse_digit(const uint8_t c, I &i) { + const uint8_t digit = static_cast(c - '0'); + if (digit > 9) { + return false; + } + // PERF NOTE: multiplication by 10 is cheaper than arbitrary integer multiplication + i = 10 * i + digit; // might overflow, we will handle the overflow later + return true; +} + +simdjson_inline error_code parse_decimal_after_separator(simdjson_unused const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) { + // we continue with the fiction that we have an integer. If the + // floating point number is representable as x * 10^z for some integer + // z that fits in 53 bits, then we will be able to convert back the + // the integer into a float in a lossless manner. + const uint8_t *const first_after_period = p; + +#ifdef SIMDJSON_SWAR_NUMBER_PARSING +#if SIMDJSON_SWAR_NUMBER_PARSING + // this helps if we have lots of decimals! + // this turns out to be frequent enough. + if (is_made_of_eight_digits_fast(p)) { + i = i * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + } +#endif // SIMDJSON_SWAR_NUMBER_PARSING +#endif // #ifdef SIMDJSON_SWAR_NUMBER_PARSING + // Unrolling the first digit makes a small difference on some implementations (e.g. westmere) + if (parse_digit(*p, i)) { ++p; } + while (parse_digit(*p, i)) { p++; } + exponent = first_after_period - p; + // Decimal without digits (123.) is illegal + if (exponent == 0) { + return INVALID_NUMBER(src); + } + return SUCCESS; +} + +simdjson_inline error_code parse_exponent(simdjson_unused const uint8_t *const src, const uint8_t *&p, int64_t &exponent) { + // Exp Sign: -123.456e[-]78 + bool neg_exp = ('-' == *p); + if (neg_exp || '+' == *p) { p++; } // Skip + as well + + // Exponent: -123.456e-[78] + auto start_exp = p; + int64_t exp_number = 0; + while (parse_digit(*p, exp_number)) { ++p; } + // It is possible for parse_digit to overflow. + // In particular, it could overflow to INT64_MIN, and we cannot do - INT64_MIN. + // Thus we *must* check for possible overflow before we negate exp_number. + + // Performance notes: it may seem like combining the two "simdjson_unlikely checks" below into + // a single simdjson_unlikely path would be faster. The reasoning is sound, but the compiler may + // not oblige and may, in fact, generate two distinct paths in any case. It might be + // possible to do uint64_t(p - start_exp - 1) >= 18 but it could end up trading off + // instructions for a simdjson_likely branch, an unconclusive gain. + + // If there were no digits, it's an error. + if (simdjson_unlikely(p == start_exp)) { + return INVALID_NUMBER(src); + } + // We have a valid positive exponent in exp_number at this point, except that + // it may have overflowed. + + // If there were more than 18 digits, we may have overflowed the integer. We have to do + // something!!!! + if (simdjson_unlikely(p > start_exp+18)) { + // Skip leading zeroes: 1e000000000000000000001 is technically valid and doesn't overflow + while (*start_exp == '0') { start_exp++; } + // 19 digits could overflow int64_t and is kind of absurd anyway. We don't + // support exponents smaller than -999,999,999,999,999,999 and bigger + // than 999,999,999,999,999,999. + // We can truncate. + // Note that 999999999999999999 is assuredly too large. The maximal ieee64 value before + // infinity is ~1.8e308. The smallest subnormal is ~5e-324. So, actually, we could + // truncate at 324. + // Note that there is no reason to fail per se at this point in time. + // E.g., 0e999999999999999999999 is a fine number. + if (p > start_exp+18) { exp_number = 999999999999999999; } + } + // At this point, we know that exp_number is a sane, positive, signed integer. + // It is <= 999,999,999,999,999,999. As long as 'exponent' is in + // [-8223372036854775808, 8223372036854775808], we won't overflow. Because 'exponent' + // is bounded in magnitude by the size of the JSON input, we are fine in this universe. + // To sum it up: the next line should never overflow. + exponent += (neg_exp ? -exp_number : exp_number); + return SUCCESS; +} + +simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t digit_count) { + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + const uint8_t *start = start_digits; + while ((*start == '0') || (*start == '.')) { ++start; } + // we over-decrement by one when there is a '.' + return digit_count - size_t(start - start_digits); +} + +} // unnamed namespace + +/** @private */ +static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) { + if (parse_float_fallback(src, answer)) { + return SUCCESS; + } + return INVALID_NUMBER(src); +} + +/** @private */ +template +simdjson_inline error_code write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer) { + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon in practice. + // + // 9999999999999999999 < 2**64 so we can accommodate 19 digits. + // If we have a decimal separator, then digit_count - 1 is the number of digits, but we + // may not have a decimal separator! + if (simdjson_unlikely(digit_count > 19 && significant_digits(start_digits, digit_count) > 19)) { + // Ok, chances are good that we had an overflow! + // this is almost never going to get called!!! + // we start anew, going slowly!!! + // This will happen in the following examples: + // 10000000000000000000000000000000000000000000e+308 + // 3.1415926535897932384626433832795028841971693993751 + // + // NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer + // reference to it, it would force it to be stored in memory, preventing the compiler from + // picking it apart and putting into registers. i.e. if we pass it as reference, + // it gets slow. + double d; + error_code error = slow_float_parsing(src, &d); + writer.append_double(d); + return error; + } + // NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other + // way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331 + // To future reader: we'd love if someone found a better way, or at least could explain this result! + if (simdjson_unlikely(exponent < simdjson::internal::smallest_power) || (exponent > simdjson::internal::largest_power)) { + // + // Important: smallest_power is such that it leads to a zero value. + // Observe that 18446744073709551615e-343 == 0, i.e. (2**64 - 1) e -343 is zero + // so something x 10^-343 goes to zero, but not so with something x 10^-342. + static_assert(simdjson::internal::smallest_power <= -342, "smallest_power is not small enough"); + // + if((exponent < simdjson::internal::smallest_power) || (i == 0)) { + // E.g. Parse "-0.0e-999" into the same value as "-0.0". See https://en.wikipedia.org/wiki/Signed_zero + WRITE_DOUBLE(negative ? -0.0 : 0.0, src, writer); + return SUCCESS; + } else { // (exponent > largest_power) and (i != 0) + // We have, for sure, an infinite value and simdjson refuses to parse infinite values. + return INVALID_NUMBER(src); + } + } + double d; + if (!compute_float_64(exponent, i, negative, d)) { + // we are almost never going to get here. + if (!parse_float_fallback(src, &d)) { return INVALID_NUMBER(src); } + } + WRITE_DOUBLE(d, src, writer); + return SUCCESS; +} + +// for performance analysis, it is sometimes useful to skip parsing +#ifdef SIMDJSON_SKIPNUMBERPARSING + +template +simdjson_inline error_code parse_number(const uint8_t *const, W &writer) { + writer.append_s64(0); // always write zero + return SUCCESS; // always succeeds +} + +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { return number_type::signed_integer; } +#else + +// parse the number at src +// define JSON_TEST_NUMBERS for unit testing +// +// It is assumed that the number is followed by a structural ({,},],[) character +// or a white space character. If that is not the case (e.g., when the JSON +// document is made of a single number), then it is necessary to copy the +// content and append a space before calling this function. +// +// Our objective is accurate parsing (ULP of 0) at high speed. +template +simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) { + + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + if (digit_count == 0 || ('0' == *start_digits && digit_count > 1)) { return INVALID_NUMBER(src); } + + // + // Handle floats if there is a . or e (or both) + // + int64_t exponent = 0; + bool is_float = false; + if ('.' == *p) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) ); + digit_count = int(p - start_digits); // used later to guard against overflows + } + if (('e' == *p) || ('E' == *p)) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_exponent(src, p, exponent) ); + } + if (is_float) { + const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p); + SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) ); + if (dirty_end) { return INVALID_NUMBER(src); } + return SUCCESS; + } + + // The longest negative 64-bit number is 19 digits. + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + size_t longest_digit_count = negative ? 19 : 20; + if (digit_count > longest_digit_count) { return INVALID_NUMBER(src); } + if (digit_count == longest_digit_count) { + if (negative) { + // Anything negative above INT64_MAX+1 is invalid + if (i > uint64_t(INT64_MAX)+1) { return INVALID_NUMBER(src); } + WRITE_INTEGER(~i+1, src, writer); + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + } else if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INVALID_NUMBER(src); } + } + + // Write unsigned if it doesn't fit in a signed integer. + if (i > uint64_t(INT64_MAX)) { + WRITE_UNSIGNED(i, src, writer); + } else { + WRITE_INTEGER(negative ? (~i+1) : i, src, writer); + } + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; +} + +// Inlineable functions +namespace { + +// This table can be used to characterize the final character of an integer +// string. For JSON structural character and allowable white space characters, +// we return SUCCESS. For 'e', '.' and 'E', we return INCORRECT_TYPE. Otherwise +// we return NUMBER_ERROR. +// Optimization note: we could easily reduce the size of the table by half (to 128) +// at the cost of an extra branch. +// Optimization note: we want the values to use at most 8 bits (not, e.g., 32 bits): +static_assert(error_code(uint8_t(NUMBER_ERROR))== NUMBER_ERROR, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(SUCCESS))== SUCCESS, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(INCORRECT_TYPE))== INCORRECT_TYPE, "bad NUMBER_ERROR cast"); + +const uint8_t integer_string_finisher[256] = { + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, INCORRECT_TYPE, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, SUCCESS, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR}; + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + + +// Parse any number from 0 to 18,446,744,073,709,551,615 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src, const uint8_t * const src_end) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if ((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { + const uint8_t *p = src + 1; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (*p != '"') { return NUMBER_ERROR; } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + // Note: we use src[1] and not src[0] because src[0] is the quote character in this + // instance. + if (src[1] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src, const uint8_t * const src_end) noexcept { + // + // Check for minus sign + // + if(src == src_end) { return NUMBER_ERROR; } + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = src; + uint64_t i = 0; + while (parse_digit(*src, i)) { src++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(src - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*src)) { + // return (*src == '.' || *src == 'e' || *src == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(*src != '"') { return NUMBER_ERROR; } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { + return (*src == '-'); +} + +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { return true; } + return false; +} + +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { + // We have an integer. + // If the number is negative and valid, it must be a signed integer. + if(negative) { return number_type::signed_integer; } + // We want values larger or equal to 9223372036854775808 to be unsigned + // integers, and the other values to be signed integers. + int digit_count = int(p - src); + if(digit_count >= 19) { + const uint8_t * smaller_big_integer = reinterpret_cast("9223372036854775808"); + if((digit_count >= 20) || (memcmp(src, smaller_big_integer, 19) >= 0)) { + return number_type::unsigned_integer; + } + } + return number_type::signed_integer; + } + // Hopefully, we have 'e' or 'E' or '.'. + return number_type::floating_point_number; +} + +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src, const uint8_t * const src_end) noexcept { + if(src == src_end) { return NUMBER_ERROR; } + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + if(p == src_end) { return NUMBER_ERROR; } + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while ((p != src_end) && parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely((p != src_end) && (*p == '.'))) { + p++; + const uint8_t *start_decimal_digits = p; + if ((p == src_end) || !parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = start_digits-src > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if ((p != src_end) && (*p == 'e' || *p == 'E')) { + p++; + if(p == src_end) { return NUMBER_ERROR; } + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while ((p != src_end) && parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (*p != '"') { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +} // unnamed namespace +#endif // SIMDJSON_SKIPNUMBERPARSING + +} // namespace numberparsing + +inline std::ostream& operator<<(std::ostream& out, number_type type) noexcept { + switch (type) { + case number_type::signed_integer: out << "integer in [-9223372036854775808,9223372036854775808)"; break; + case number_type::unsigned_integer: out << "unsigned integer in [9223372036854775808,18446744073709551616)"; break; + case number_type::floating_point_number: out << "floating-point number (binary64)"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_NUMBERPARSING_H +/* end file simdjson/generic/numberparsing.h for arm64 */ + +/* including simdjson/generic/implementation_simdjson_result_base-inl.h for arm64: #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { + +// +// internal::implementation_simdjson_result_base inline implementation +// + +template +simdjson_inline void implementation_simdjson_result_base::tie(T &value, error_code &error) && noexcept { + error = this->second; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +simdjson_warn_unused simdjson_inline error_code implementation_simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; +} + +template +simdjson_inline error_code implementation_simdjson_result_base::error() const noexcept { + return this->second; +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& implementation_simdjson_result_base::value() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline T&& implementation_simdjson_result_base::take_value() && noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& implementation_simdjson_result_base::value_unsafe() const& noexcept { + return this->first; +} + +template +simdjson_inline T& implementation_simdjson_result_base::value_unsafe() & noexcept { + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value_unsafe() && noexcept { + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value, error_code error) noexcept + : first{std::forward(value)}, second{error} {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(error_code error) noexcept + : implementation_simdjson_result_base(T{}, error) {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value) noexcept + : implementation_simdjson_result_base(std::forward(value), SUCCESS) {} + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H +/* end file simdjson/generic/implementation_simdjson_result_base-inl.h for arm64 */ +/* end file simdjson/generic/amalgamated.h for arm64 */ +/* including simdjson/arm64/end.h: #include "simdjson/arm64/end.h" */ +/* begin file simdjson/arm64/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#undef SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT +/* undefining SIMDJSON_IMPLEMENTATION from "arm64" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/arm64/end.h */ + +#endif // SIMDJSON_ARM64_H +/* end file simdjson/arm64.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(fallback) +/* including simdjson/fallback.h: #include "simdjson/fallback.h" */ +/* begin file simdjson/fallback.h */ +#ifndef SIMDJSON_FALLBACK_H +#define SIMDJSON_FALLBACK_H + +/* including simdjson/fallback/begin.h: #include "simdjson/fallback/begin.h" */ +/* begin file simdjson/fallback/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "fallback" */ +#define SIMDJSON_IMPLEMENTATION fallback +/* including simdjson/fallback/base.h: #include "simdjson/fallback/base.h" */ +/* begin file simdjson/fallback/base.h */ +#ifndef SIMDJSON_FALLBACK_BASE_H +#define SIMDJSON_FALLBACK_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Fallback implementation (runs on any machine). + */ +namespace fallback { + +class implementation; + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_BASE_H +/* end file simdjson/fallback/base.h */ +/* including simdjson/fallback/bitmanipulation.h: #include "simdjson/fallback/bitmanipulation.h" */ +/* begin file simdjson/fallback/bitmanipulation.h */ +#ifndef SIMDJSON_FALLBACK_BITMANIPULATION_H +#define SIMDJSON_FALLBACK_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace { + +#if defined(_MSC_VER) && !defined(_M_ARM64) && !defined(_M_X64) +static inline unsigned char _BitScanForward64(unsigned long* ret, uint64_t x) { + unsigned long x0 = (unsigned long)x, top, bottom; + _BitScanForward(&top, (unsigned long)(x >> 32)); + _BitScanForward(&bottom, x0); + *ret = x0 ? bottom : 32 + top; + return x != 0; +} +static unsigned char _BitScanReverse64(unsigned long* ret, uint64_t x) { + unsigned long x1 = (unsigned long)(x >> 32), top, bottom; + _BitScanReverse(&top, x1); + _BitScanReverse(&bottom, (unsigned long)x); + *ret = x1 ? top + 32 : bottom; + return x != 0; +} +#endif + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#ifdef _MSC_VER + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// _MSC_VER +} + +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_BITMANIPULATION_H +/* end file simdjson/fallback/bitmanipulation.h */ +/* including simdjson/fallback/stringparsing_defs.h: #include "simdjson/fallback/stringparsing_defs.h" */ +/* begin file simdjson/fallback/stringparsing_defs.h */ +#ifndef SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H +#define SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace { + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 1; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return c == '"'; } + simdjson_inline bool has_backslash() { return c == '\\'; } + simdjson_inline int quote_index() { return c == '"' ? 0 : 1; } + simdjson_inline int backslash_index() { return c == '\\' ? 0 : 1; } + + uint8_t c; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // store to dest unconditionally - we can overwrite the bits we don't like later + dst[0] = src[0]; + return { src[0] }; +} + +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H +/* end file simdjson/fallback/stringparsing_defs.h */ +/* including simdjson/fallback/numberparsing_defs.h: #include "simdjson/fallback/numberparsing_defs.h" */ +/* begin file simdjson/fallback/numberparsing_defs.h */ +#ifndef SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H +#define SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +#ifdef JSON_TEST_NUMBERS // for unit testing +void found_invalid_number(const uint8_t *buf); +void found_integer(int64_t result, const uint8_t *buf); +void found_unsigned_integer(uint64_t result, const uint8_t *buf); +void found_float(double result, const uint8_t *buf); +#endif + +namespace simdjson { +namespace fallback { +namespace numberparsing { + +// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const char *chars) { + uint64_t val; + memcpy(&val, chars, sizeof(uint64_t)); + val = (val & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8; + val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16; + return uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32); +} + +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + return parse_eight_digits_unrolled(reinterpret_cast(chars)); +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace fallback +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H +/* end file simdjson/fallback/numberparsing_defs.h */ +/* end file simdjson/fallback/begin.h */ +/* including simdjson/generic/amalgamated.h for fallback: #include "simdjson/generic/amalgamated.h" */ +/* begin file simdjson/generic/amalgamated.h for fallback */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_DEPENDENCIES_H) +#error simdjson/generic/dependencies.h must be included before simdjson/generic/amalgamated.h! +#endif + +/* including simdjson/generic/base.h for fallback: #include "simdjson/generic/base.h" */ +/* begin file simdjson/generic/base.h for fallback */ +#ifndef SIMDJSON_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): // If we haven't got an implementation yet, we're in the editor, editing a generic file! Just */ +/* amalgamation skipped (editor-only): // use the most advanced one we can so the most possible stuff can be tested. */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation_detection.h" */ +/* amalgamation skipped (editor-only): #if SIMDJSON_IMPLEMENTATION_ICELAKE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_HASWELL */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_WESTMERE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_ARM64 */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_PPC64 */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_FALLBACK */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/begin.h" */ +/* amalgamation skipped (editor-only): #else */ +/* amalgamation skipped (editor-only): #error "All possible implementations (including fallback) have been disabled! simdjson will not run." */ +/* amalgamation skipped (editor-only): #endif */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { + +struct open_container; +class dom_parser_implementation; + +/** + * The type of a JSON number + */ +enum class number_type { + floating_point_number=1, /// a binary64 number + signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + unsigned_integer /// a positive integer larger or equal to 1<<63 +}; + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_BASE_H +/* end file simdjson/generic/base.h for fallback */ +/* including simdjson/generic/jsoncharutils.h for fallback: #include "simdjson/generic/jsoncharutils.h" */ +/* begin file simdjson/generic/jsoncharutils.h for fallback */ +#ifndef SIMDJSON_GENERIC_JSONCHARUTILS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_JSONCHARUTILS_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/jsoncharutils_tables.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace { +namespace jsoncharutils { + +// return non-zero if not a structural or whitespace char +// zero otherwise +simdjson_inline uint32_t is_not_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace_negated[c]; +} + +simdjson_inline uint32_t is_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace[c]; +} + +// returns a value with the high 16 bits set if not valid +// otherwise returns the conversion of the 4 hex digits at src into the bottom +// 16 bits of the 32-bit return register +// +// see +// https://lemire.me/blog/2019/04/17/parsing-short-hexadecimal-strings-efficiently/ +static inline uint32_t hex_to_u32_nocheck( + const uint8_t *src) { // strictly speaking, static inline is a C-ism + uint32_t v1 = internal::digit_to_val32[630 + src[0]]; + uint32_t v2 = internal::digit_to_val32[420 + src[1]]; + uint32_t v3 = internal::digit_to_val32[210 + src[2]]; + uint32_t v4 = internal::digit_to_val32[0 + src[3]]; + return v1 | v2 | v3 | v4; +} + +// given a code point cp, writes to c +// the utf-8 code, outputting the length in +// bytes, if the length is zero, the code point +// is invalid +// +// This can possibly be made faster using pdep +// and clz and table lookups, but JSON documents +// have few escaped code points, and the following +// function looks cheap. +// +// Note: we assume that surrogates are treated separately +// +simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) { + if (cp <= 0x7F) { + c[0] = uint8_t(cp); + return 1; // ascii + } + if (cp <= 0x7FF) { + c[0] = uint8_t((cp >> 6) + 192); + c[1] = uint8_t((cp & 63) + 128); + return 2; // universal plane + // Surrogates are treated elsewhere... + //} //else if (0xd800 <= cp && cp <= 0xdfff) { + // return 0; // surrogates // could put assert here + } else if (cp <= 0xFFFF) { + c[0] = uint8_t((cp >> 12) + 224); + c[1] = uint8_t(((cp >> 6) & 63) + 128); + c[2] = uint8_t((cp & 63) + 128); + return 3; + } else if (cp <= 0x10FFFF) { // if you know you have a valid code point, this + // is not needed + c[0] = uint8_t((cp >> 18) + 240); + c[1] = uint8_t(((cp >> 12) & 63) + 128); + c[2] = uint8_t(((cp >> 6) & 63) + 128); + c[3] = uint8_t((cp & 63) + 128); + return 4; + } + // will return 0 when the code point was too large. + return 0; // bad r +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +} // namespace jsoncharutils +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_JSONCHARUTILS_H +/* end file simdjson/generic/jsoncharutils.h for fallback */ +/* including simdjson/generic/atomparsing.h for fallback: #include "simdjson/generic/atomparsing.h" */ +/* begin file simdjson/generic/atomparsing.h for fallback */ +#ifndef SIMDJSON_GENERIC_ATOMPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ATOMPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace fallback { +namespace { +/// @private +namespace atomparsing { + +// The string_to_uint32 is exclusively used to map literal strings to 32-bit values. +// We use memcpy instead of a pointer cast to avoid undefined behaviors since we cannot +// be certain that the character pointer will be properly aligned. +// You might think that using memcpy makes this function expensive, but you'd be wrong. +// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false"); +// to the compile-time constant 1936482662. +simdjson_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; } + + +// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive. +// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about. +simdjson_warn_unused +simdjson_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) { + uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++) + static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes"); + std::memcpy(&srcval, src, sizeof(uint32_t)); + return srcval ^ string_to_uint32(atom); +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src) { + return (str4ncmp(src, "true") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_true_atom(src); } + else if (len == 4) { return !str4ncmp(src, "true"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src) { + return (str4ncmp(src+1, "alse") | jsoncharutils::is_not_structural_or_whitespace(src[5])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src, size_t len) { + if (len > 5) { return is_valid_false_atom(src); } + else if (len == 5) { return !str4ncmp(src+1, "alse"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src) { + return (str4ncmp(src, "null") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_null_atom(src); } + else if (len == 4) { return !str4ncmp(src, "null"); } + else { return false; } +} + +} // namespace atomparsing +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ATOMPARSING_H +/* end file simdjson/generic/atomparsing.h for fallback */ +/* including simdjson/generic/dom_parser_implementation.h for fallback: #include "simdjson/generic/dom_parser_implementation.h" */ +/* begin file simdjson/generic/dom_parser_implementation.h for fallback */ +#ifndef SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { + +// expectation: sizeof(open_container) = 64/8. +struct open_container { + uint32_t tape_index; // where, on the tape, does the scope ([,{) begins + uint32_t count; // how many elements in the scope +}; // struct open_container + +static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits"); + +class dom_parser_implementation final : public internal::dom_parser_implementation { +public: + /** Tape location of each open { or [ */ + std::unique_ptr open_containers{}; + /** Whether each open container is a [ or { */ + std::unique_ptr is_array{}; + /** Buffer passed to stage 1 */ + const uint8_t *buf{}; + /** Length passed to stage 1 */ + size_t len{0}; + /** Document passed to stage 2 */ + dom::document *doc{}; + + inline dom_parser_implementation() noexcept; + inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; + inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; + dom_parser_implementation(const dom_parser_implementation &) = delete; + dom_parser_implementation &operator=(const dom_parser_implementation &) = delete; + + simdjson_warn_unused error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage1(const uint8_t *buf, size_t len, stage1_mode partial) noexcept final; + simdjson_warn_unused error_code stage2(dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage2_next(dom::document &doc) noexcept final; + simdjson_warn_unused uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept final; + simdjson_warn_unused uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept final; + inline simdjson_warn_unused error_code set_capacity(size_t capacity) noexcept final; + inline simdjson_warn_unused error_code set_max_depth(size_t max_depth) noexcept final; +private: + simdjson_inline simdjson_warn_unused error_code set_capacity_stage1(size_t capacity); + +}; + +} // namespace fallback +} // namespace simdjson + +namespace simdjson { +namespace fallback { + +inline dom_parser_implementation::dom_parser_implementation() noexcept = default; +inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; +inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; + +// Leaving these here so they can be inlined if so desired +inline simdjson_warn_unused error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept { + if(capacity > SIMDJSON_MAXSIZE_BYTES) { return CAPACITY; } + // Stage 1 index output + size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7; + structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] ); + if (!structural_indexes) { _capacity = 0; return MEMALLOC; } + structural_indexes[0] = 0; + n_structural_indexes = 0; + + _capacity = capacity; + return SUCCESS; +} + +inline simdjson_warn_unused error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept { + // Stage 2 stacks + open_containers.reset(new (std::nothrow) open_container[max_depth]); + is_array.reset(new (std::nothrow) bool[max_depth]); + if (!is_array || !open_containers) { _max_depth = 0; return MEMALLOC; } + + _max_depth = max_depth; + return SUCCESS; +} + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file simdjson/generic/dom_parser_implementation.h for fallback */ +/* including simdjson/generic/implementation_simdjson_result_base.h for fallback: #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base.h for fallback */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { + +// This is a near copy of include/error.h's implementation_simdjson_result_base, except it doesn't use std::pair +// so we can avoid inlining errors +// TODO reconcile these! +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + * + * This is a base class for implementations that want to add functions to the result type for + * chaining. + * + * Override like: + * + * struct simdjson_result : public internal::implementation_simdjson_result_base { + * simdjson_result() noexcept : internal::implementation_simdjson_result_base() {} + * simdjson_result(error_code error) noexcept : internal::implementation_simdjson_result_base(error) {} + * simdjson_result(T &&value) noexcept : internal::implementation_simdjson_result_base(std::forward(value)) {} + * simdjson_result(T &&value, error_code error) noexcept : internal::implementation_simdjson_result_base(value, error) {} + * // Your extra methods here + * } + * + * Then any method returning simdjson_result will be chainable with your methods. + */ +template +struct implementation_simdjson_result_base { + + /** + * Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline implementation_simdjson_result_base() noexcept = default; + + /** + * Create a new error result. + */ + simdjson_inline implementation_simdjson_result_base(error_code error) noexcept; + + /** + * Create a new successful result. + */ + simdjson_inline implementation_simdjson_result_base(T &&value) noexcept; + + /** + * Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline implementation_simdjson_result_base(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); + + +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T& value_unsafe() & noexcept; + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; +protected: + /** users should never directly access first and second. **/ + T first{}; /** Users should never directly access 'first'. **/ + error_code second{UNINITIALIZED}; /** Users should never directly access 'second'. **/ +}; // struct implementation_simdjson_result_base + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H +/* end file simdjson/generic/implementation_simdjson_result_base.h for fallback */ +/* including simdjson/generic/numberparsing.h for fallback: #include "simdjson/generic/numberparsing.h" */ +/* begin file simdjson/generic/numberparsing.h for fallback */ +#ifndef SIMDJSON_GENERIC_NUMBERPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_NUMBERPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include +#include + +namespace simdjson { +namespace fallback { +namespace numberparsing { + +#ifdef JSON_TEST_NUMBERS +#define INVALID_NUMBER(SRC) (found_invalid_number((SRC)), NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (found_integer((VALUE), (SRC)), (WRITER).append_s64((VALUE))) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (found_unsigned_integer((VALUE), (SRC)), (WRITER).append_u64((VALUE))) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (found_float((VALUE), (SRC)), (WRITER).append_double((VALUE))) +#else +#define INVALID_NUMBER(SRC) (NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (WRITER).append_s64((VALUE)) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (WRITER).append_u64((VALUE)) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (WRITER).append_double((VALUE)) +#endif + +namespace { + +// Convert a mantissa, an exponent and a sign bit into an ieee64 double. +// The real_exponent needs to be in [0, 2046] (technically real_exponent = 2047 would be acceptable). +// The mantissa should be in [0,1<<53). The bit at index (1ULL << 52) while be zeroed. +simdjson_inline double to_double(uint64_t mantissa, uint64_t real_exponent, bool negative) { + double d; + mantissa &= ~(1ULL << 52); + mantissa |= real_exponent << 52; + mantissa |= ((static_cast(negative)) << 63); + std::memcpy(&d, &mantissa, sizeof(d)); + return d; +} + +// Attempts to compute i * 10^(power) exactly; and if "negative" is +// true, negate the result. +// This function will only work in some cases, when it does not work, success is +// set to false. This should work *most of the time* (like 99% of the time). +// We assume that power is in the [smallest_power, +// largest_power] interval: the caller is responsible for this check. +simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative, double &d) { + // we start with a fast path + // It was described in + // Clinger WD. How to read floating point numbers accurately. + // ACM SIGPLAN Notices. 1990 +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + // We cannot be certain that x/y is rounded to nearest. + if (0 <= power && power <= 22 && i <= 9007199254740991) +#else + if (-22 <= power && power <= 22 && i <= 9007199254740991) +#endif + { + // convert the integer into a double. This is lossless since + // 0 <= i <= 2^53 - 1. + d = double(i); + // + // The general idea is as follows. + // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then + // 1) Both s and p can be represented exactly as 64-bit floating-point + // values + // (binary64). + // 2) Because s and p can be represented exactly as floating-point values, + // then s * p + // and s / p will produce correctly rounded values. + // + if (power < 0) { + d = d / simdjson::internal::power_of_ten[-power]; + } else { + d = d * simdjson::internal::power_of_ten[power]; + } + if (negative) { + d = -d; + } + return true; + } + // When 22 < power && power < 22 + 16, we could + // hope for another, secondary fast path. It was + // described by David M. Gay in "Correctly rounded + // binary-decimal and decimal-binary conversions." (1990) + // If you need to compute i * 10^(22 + x) for x < 16, + // first compute i * 10^x, if you know that result is exact + // (e.g., when i * 10^x < 2^53), + // then you can still proceed and do (i * 10^x) * 10^22. + // Is this worth your time? + // You need 22 < power *and* power < 22 + 16 *and* (i * 10^(x-22) < 2^53) + // for this second fast path to work. + // If you you have 22 < power *and* power < 22 + 16, and then you + // optimistically compute "i * 10^(x-22)", there is still a chance that you + // have wasted your time if i * 10^(x-22) >= 2^53. It makes the use cases of + // this optimization maybe less common than we would like. Source: + // http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + // also used in RapidJSON: https://rapidjson.org/strtod_8h_source.html + + // The fast path has now failed, so we are failing back on the slower path. + + // In the slow path, we need to adjust i so that it is > 1<<63 which is always + // possible, except if i == 0, so we handle i == 0 separately. + if(i == 0) { + d = negative ? -0.0 : 0.0; + return true; + } + + + // The exponent is 1024 + 63 + power + // + floor(log(5**power)/log(2)). + // The 1024 comes from the ieee64 standard. + // The 63 comes from the fact that we use a 64-bit word. + // + // Computing floor(log(5**power)/log(2)) could be + // slow. Instead we use a fast function. + // + // For power in (-400,350), we have that + // (((152170 + 65536) * power ) >> 16); + // is equal to + // floor(log(5**power)/log(2)) + power when power >= 0 + // and it is equal to + // ceil(log(5**-power)/log(2)) + power when power < 0 + // + // The 65536 is (1<<16) and corresponds to + // (65536 * power) >> 16 ---> power + // + // ((152170 * power ) >> 16) is equal to + // floor(log(5**power)/log(2)) + // + // Note that this is not magic: 152170/(1<<16) is + // approximatively equal to log(5)/log(2). + // The 1<<16 value is a power of two; we could use a + // larger power of 2 if we wanted to. + // + int64_t exponent = (((152170 + 65536) * power) >> 16) + 1024 + 63; + + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(i); + i <<= lz; + + + // We are going to need to do some 64-bit arithmetic to get a precise product. + // We use a table lookup approach. + // It is safe because + // power >= smallest_power + // and power <= largest_power + // We recover the mantissa of the power, it has a leading 1. It is always + // rounded down. + // + // We want the most significant 64 bits of the product. We know + // this will be non-zero because the most significant bit of i is + // 1. + const uint32_t index = 2 * uint32_t(power - simdjson::internal::smallest_power); + // Optimization: It may be that materializing the index as a variable might confuse some compilers and prevent effective complex-addressing loads. (Done for code clarity.) + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); + // Both i and power_of_five_128[index] have their most significant bit set to 1 which + // implies that the either the most or the second most significant bit of the product + // is 1. We pack values in this manner for efficiency reasons: it maximizes the use + // we make of the product. It also makes it easy to reason about the product: there + // is 0 or 1 leading zero in the product. + + // Unless the least significant 9 bits of the high (64-bit) part of the full + // product are all 1s, then we know that the most significant 55 bits are + // exact and no further work is needed. Having 55 bits is necessary because + // we need 53 bits for the mantissa but we have to have one rounding bit and + // we can waste a bit if the most significant bit of the product is zero. + if((firstproduct.high & 0x1FF) == 0x1FF) { + // We want to compute i * 5^q, but only care about the top 55 bits at most. + // Consider the scenario where q>=0. Then 5^q may not fit in 64-bits. Doing + // the full computation is wasteful. So we do what is called a "truncated + // multiplication". + // We take the most significant 64-bits, and we put them in + // power_of_five_128[index]. Usually, that's good enough to approximate i * 5^q + // to the desired approximation using one multiplication. Sometimes it does not suffice. + // Then we store the next most significant 64 bits in power_of_five_128[index + 1], and + // then we get a better approximation to i * 5^q. + // + // That's for when q>=0. The logic for q<0 is somewhat similar but it is somewhat + // more complicated. + // + // There is an extra layer of complexity in that we need more than 55 bits of + // accuracy in the round-to-even scenario. + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if(secondproduct.high > firstproduct.low) { firstproduct.high++; } + // As it has been proven by Noble Mushtak and Daniel Lemire in "Fast Number Parsing Without + // Fallback" (https://arxiv.org/abs/2212.06644), at this point we are sure that the product + // is sufficiently accurate, and more computation is not needed. + } + uint64_t lower = firstproduct.low; + uint64_t upper = firstproduct.high; + // The final mantissa should be 53 bits with a leading 1. + // We shift it so that it occupies 54 bits with a leading 1. + /////// + uint64_t upperbit = upper >> 63; + uint64_t mantissa = upper >> (upperbit + 9); + lz += int(1 ^ upperbit); + + // Here we have mantissa < (1<<54). + int64_t real_exponent = exponent - lz; + if (simdjson_unlikely(real_exponent <= 0)) { // we have a subnormal? + // Here have that real_exponent <= 0 so -real_exponent >= 0 + if(-real_exponent + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure. + d = negative ? -0.0 : 0.0; + return true; + } + // next line is safe because -real_exponent + 1 < 0 + mantissa >>= -real_exponent + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0. + mantissa += (mantissa & 1); // round up + mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + real_exponent = (mantissa < (uint64_t(1) << 52)) ? 0 : 1; + d = to_double(mantissa, real_exponent, negative); + return true; + } + // We have to round to even. The "to even" part + // is only a problem when we are right in between two floats + // which we guard against. + // If we have lots of trailing zeros, we may fall right between two + // floating-point values. + // + // The round-to-even cases take the form of a number 2m+1 which is in (2^53,2^54] + // times a power of two. That is, it is right between a number with binary significand + // m and another number with binary significand m+1; and it must be the case + // that it cannot be represented by a float itself. + // + // We must have that w * 10 ^q == (2m+1) * 2^p for some power of two 2^p. + // Recall that 10^q = 5^q * 2^q. + // When q >= 0, we must have that (2m+1) is divible by 5^q, so 5^q <= 2^54. We have that + // 5^23 <= 2^54 and it is the last power of five to qualify, so q <= 23. + // When q<0, we have w >= (2m+1) x 5^{-q}. We must have that w<2^{64} so + // (2m+1) x 5^{-q} < 2^{64}. We have that 2m+1>2^{53}. Hence, we must have + // 2^{53} x 5^{-q} < 2^{64}. + // Hence we have 5^{-q} < 2^{11}$ or q>= -4. + // + // We require lower <= 1 and not lower == 0 because we could not prove that + // that lower == 0 is implied; but we could prove that lower <= 1 is a necessary and sufficient test. + if (simdjson_unlikely((lower <= 1) && (power >= -4) && (power <= 23) && ((mantissa & 3) == 1))) { + if((mantissa << (upperbit + 64 - 53 - 2)) == upper) { + mantissa &= ~1; // flip it so that we do not round up + } + } + + mantissa += mantissa & 1; + mantissa >>= 1; + + // Here we have mantissa < (1<<53), unless there was an overflow + if (mantissa >= (1ULL << 53)) { + ////////// + // This will happen when parsing values such as 7.2057594037927933e+16 + //////// + mantissa = (1ULL << 52); + real_exponent++; + } + mantissa &= ~(1ULL << 52); + // we have to check that real_exponent is in range, otherwise we bail out + if (simdjson_unlikely(real_exponent > 2046)) { + // We have an infinite value!!! We could actually throw an error here if we could. + return false; + } + d = to_double(mantissa, real_exponent, negative); + return true; +} + +// We call a fallback floating-point parser that might be slow. Note +// it will accept JSON numbers, but the JSON spec. is more restrictive so +// before you call parse_float_fallback, you need to have validated the input +// string with the JSON grammar. +// It will return an error (false) if the parsed number is infinite. +// The string parsing itself always succeeds. We know that there is at least +// one digit. +static bool parse_float_fallback(const uint8_t *ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +static bool parse_float_fallback(const uint8_t *ptr, const uint8_t *end_ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr), reinterpret_cast(end_ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +// check quickly whether the next 8 chars are made of digits +// at a glance, it looks better than Mula's +// http://0x80.pl/articles/swar-digits-validate.html +simdjson_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) { + uint64_t val; + // this can read up to 7 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(7 <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be bigger than 7"); + std::memcpy(&val, chars, 8); + // a branchy method might be faster: + // return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030) + // && (( (val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0 ) == + // 0x3030303030303030); + return (((val & 0xF0F0F0F0F0F0F0F0) | + (((val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4)) == + 0x3333333333333333); +} + +template +SIMDJSON_NO_SANITIZE_UNDEFINED // We deliberately allow overflow here and check later +simdjson_inline bool parse_digit(const uint8_t c, I &i) { + const uint8_t digit = static_cast(c - '0'); + if (digit > 9) { + return false; + } + // PERF NOTE: multiplication by 10 is cheaper than arbitrary integer multiplication + i = 10 * i + digit; // might overflow, we will handle the overflow later + return true; +} + +simdjson_inline error_code parse_decimal_after_separator(simdjson_unused const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) { + // we continue with the fiction that we have an integer. If the + // floating point number is representable as x * 10^z for some integer + // z that fits in 53 bits, then we will be able to convert back the + // the integer into a float in a lossless manner. + const uint8_t *const first_after_period = p; + +#ifdef SIMDJSON_SWAR_NUMBER_PARSING +#if SIMDJSON_SWAR_NUMBER_PARSING + // this helps if we have lots of decimals! + // this turns out to be frequent enough. + if (is_made_of_eight_digits_fast(p)) { + i = i * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + } +#endif // SIMDJSON_SWAR_NUMBER_PARSING +#endif // #ifdef SIMDJSON_SWAR_NUMBER_PARSING + // Unrolling the first digit makes a small difference on some implementations (e.g. westmere) + if (parse_digit(*p, i)) { ++p; } + while (parse_digit(*p, i)) { p++; } + exponent = first_after_period - p; + // Decimal without digits (123.) is illegal + if (exponent == 0) { + return INVALID_NUMBER(src); + } + return SUCCESS; +} + +simdjson_inline error_code parse_exponent(simdjson_unused const uint8_t *const src, const uint8_t *&p, int64_t &exponent) { + // Exp Sign: -123.456e[-]78 + bool neg_exp = ('-' == *p); + if (neg_exp || '+' == *p) { p++; } // Skip + as well + + // Exponent: -123.456e-[78] + auto start_exp = p; + int64_t exp_number = 0; + while (parse_digit(*p, exp_number)) { ++p; } + // It is possible for parse_digit to overflow. + // In particular, it could overflow to INT64_MIN, and we cannot do - INT64_MIN. + // Thus we *must* check for possible overflow before we negate exp_number. + + // Performance notes: it may seem like combining the two "simdjson_unlikely checks" below into + // a single simdjson_unlikely path would be faster. The reasoning is sound, but the compiler may + // not oblige and may, in fact, generate two distinct paths in any case. It might be + // possible to do uint64_t(p - start_exp - 1) >= 18 but it could end up trading off + // instructions for a simdjson_likely branch, an unconclusive gain. + + // If there were no digits, it's an error. + if (simdjson_unlikely(p == start_exp)) { + return INVALID_NUMBER(src); + } + // We have a valid positive exponent in exp_number at this point, except that + // it may have overflowed. + + // If there were more than 18 digits, we may have overflowed the integer. We have to do + // something!!!! + if (simdjson_unlikely(p > start_exp+18)) { + // Skip leading zeroes: 1e000000000000000000001 is technically valid and doesn't overflow + while (*start_exp == '0') { start_exp++; } + // 19 digits could overflow int64_t and is kind of absurd anyway. We don't + // support exponents smaller than -999,999,999,999,999,999 and bigger + // than 999,999,999,999,999,999. + // We can truncate. + // Note that 999999999999999999 is assuredly too large. The maximal ieee64 value before + // infinity is ~1.8e308. The smallest subnormal is ~5e-324. So, actually, we could + // truncate at 324. + // Note that there is no reason to fail per se at this point in time. + // E.g., 0e999999999999999999999 is a fine number. + if (p > start_exp+18) { exp_number = 999999999999999999; } + } + // At this point, we know that exp_number is a sane, positive, signed integer. + // It is <= 999,999,999,999,999,999. As long as 'exponent' is in + // [-8223372036854775808, 8223372036854775808], we won't overflow. Because 'exponent' + // is bounded in magnitude by the size of the JSON input, we are fine in this universe. + // To sum it up: the next line should never overflow. + exponent += (neg_exp ? -exp_number : exp_number); + return SUCCESS; +} + +simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t digit_count) { + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + const uint8_t *start = start_digits; + while ((*start == '0') || (*start == '.')) { ++start; } + // we over-decrement by one when there is a '.' + return digit_count - size_t(start - start_digits); +} + +} // unnamed namespace + +/** @private */ +static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) { + if (parse_float_fallback(src, answer)) { + return SUCCESS; + } + return INVALID_NUMBER(src); +} + +/** @private */ +template +simdjson_inline error_code write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer) { + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon in practice. + // + // 9999999999999999999 < 2**64 so we can accommodate 19 digits. + // If we have a decimal separator, then digit_count - 1 is the number of digits, but we + // may not have a decimal separator! + if (simdjson_unlikely(digit_count > 19 && significant_digits(start_digits, digit_count) > 19)) { + // Ok, chances are good that we had an overflow! + // this is almost never going to get called!!! + // we start anew, going slowly!!! + // This will happen in the following examples: + // 10000000000000000000000000000000000000000000e+308 + // 3.1415926535897932384626433832795028841971693993751 + // + // NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer + // reference to it, it would force it to be stored in memory, preventing the compiler from + // picking it apart and putting into registers. i.e. if we pass it as reference, + // it gets slow. + double d; + error_code error = slow_float_parsing(src, &d); + writer.append_double(d); + return error; + } + // NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other + // way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331 + // To future reader: we'd love if someone found a better way, or at least could explain this result! + if (simdjson_unlikely(exponent < simdjson::internal::smallest_power) || (exponent > simdjson::internal::largest_power)) { + // + // Important: smallest_power is such that it leads to a zero value. + // Observe that 18446744073709551615e-343 == 0, i.e. (2**64 - 1) e -343 is zero + // so something x 10^-343 goes to zero, but not so with something x 10^-342. + static_assert(simdjson::internal::smallest_power <= -342, "smallest_power is not small enough"); + // + if((exponent < simdjson::internal::smallest_power) || (i == 0)) { + // E.g. Parse "-0.0e-999" into the same value as "-0.0". See https://en.wikipedia.org/wiki/Signed_zero + WRITE_DOUBLE(negative ? -0.0 : 0.0, src, writer); + return SUCCESS; + } else { // (exponent > largest_power) and (i != 0) + // We have, for sure, an infinite value and simdjson refuses to parse infinite values. + return INVALID_NUMBER(src); + } + } + double d; + if (!compute_float_64(exponent, i, negative, d)) { + // we are almost never going to get here. + if (!parse_float_fallback(src, &d)) { return INVALID_NUMBER(src); } + } + WRITE_DOUBLE(d, src, writer); + return SUCCESS; +} + +// for performance analysis, it is sometimes useful to skip parsing +#ifdef SIMDJSON_SKIPNUMBERPARSING + +template +simdjson_inline error_code parse_number(const uint8_t *const, W &writer) { + writer.append_s64(0); // always write zero + return SUCCESS; // always succeeds +} + +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { return number_type::signed_integer; } +#else + +// parse the number at src +// define JSON_TEST_NUMBERS for unit testing +// +// It is assumed that the number is followed by a structural ({,},],[) character +// or a white space character. If that is not the case (e.g., when the JSON +// document is made of a single number), then it is necessary to copy the +// content and append a space before calling this function. +// +// Our objective is accurate parsing (ULP of 0) at high speed. +template +simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) { + + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + if (digit_count == 0 || ('0' == *start_digits && digit_count > 1)) { return INVALID_NUMBER(src); } + + // + // Handle floats if there is a . or e (or both) + // + int64_t exponent = 0; + bool is_float = false; + if ('.' == *p) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) ); + digit_count = int(p - start_digits); // used later to guard against overflows + } + if (('e' == *p) || ('E' == *p)) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_exponent(src, p, exponent) ); + } + if (is_float) { + const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p); + SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) ); + if (dirty_end) { return INVALID_NUMBER(src); } + return SUCCESS; + } + + // The longest negative 64-bit number is 19 digits. + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + size_t longest_digit_count = negative ? 19 : 20; + if (digit_count > longest_digit_count) { return INVALID_NUMBER(src); } + if (digit_count == longest_digit_count) { + if (negative) { + // Anything negative above INT64_MAX+1 is invalid + if (i > uint64_t(INT64_MAX)+1) { return INVALID_NUMBER(src); } + WRITE_INTEGER(~i+1, src, writer); + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + } else if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INVALID_NUMBER(src); } + } + + // Write unsigned if it doesn't fit in a signed integer. + if (i > uint64_t(INT64_MAX)) { + WRITE_UNSIGNED(i, src, writer); + } else { + WRITE_INTEGER(negative ? (~i+1) : i, src, writer); + } + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; +} + +// Inlineable functions +namespace { + +// This table can be used to characterize the final character of an integer +// string. For JSON structural character and allowable white space characters, +// we return SUCCESS. For 'e', '.' and 'E', we return INCORRECT_TYPE. Otherwise +// we return NUMBER_ERROR. +// Optimization note: we could easily reduce the size of the table by half (to 128) +// at the cost of an extra branch. +// Optimization note: we want the values to use at most 8 bits (not, e.g., 32 bits): +static_assert(error_code(uint8_t(NUMBER_ERROR))== NUMBER_ERROR, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(SUCCESS))== SUCCESS, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(INCORRECT_TYPE))== INCORRECT_TYPE, "bad NUMBER_ERROR cast"); + +const uint8_t integer_string_finisher[256] = { + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, INCORRECT_TYPE, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, SUCCESS, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR}; + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + + +// Parse any number from 0 to 18,446,744,073,709,551,615 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src, const uint8_t * const src_end) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if ((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { + const uint8_t *p = src + 1; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (*p != '"') { return NUMBER_ERROR; } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + // Note: we use src[1] and not src[0] because src[0] is the quote character in this + // instance. + if (src[1] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src, const uint8_t * const src_end) noexcept { + // + // Check for minus sign + // + if(src == src_end) { return NUMBER_ERROR; } + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = src; + uint64_t i = 0; + while (parse_digit(*src, i)) { src++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(src - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*src)) { + // return (*src == '.' || *src == 'e' || *src == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(*src != '"') { return NUMBER_ERROR; } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { + return (*src == '-'); +} + +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { return true; } + return false; +} + +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { + // We have an integer. + // If the number is negative and valid, it must be a signed integer. + if(negative) { return number_type::signed_integer; } + // We want values larger or equal to 9223372036854775808 to be unsigned + // integers, and the other values to be signed integers. + int digit_count = int(p - src); + if(digit_count >= 19) { + const uint8_t * smaller_big_integer = reinterpret_cast("9223372036854775808"); + if((digit_count >= 20) || (memcmp(src, smaller_big_integer, 19) >= 0)) { + return number_type::unsigned_integer; + } + } + return number_type::signed_integer; + } + // Hopefully, we have 'e' or 'E' or '.'. + return number_type::floating_point_number; +} + +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src, const uint8_t * const src_end) noexcept { + if(src == src_end) { return NUMBER_ERROR; } + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + if(p == src_end) { return NUMBER_ERROR; } + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while ((p != src_end) && parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely((p != src_end) && (*p == '.'))) { + p++; + const uint8_t *start_decimal_digits = p; + if ((p == src_end) || !parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = start_digits-src > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if ((p != src_end) && (*p == 'e' || *p == 'E')) { + p++; + if(p == src_end) { return NUMBER_ERROR; } + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while ((p != src_end) && parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (*p != '"') { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +} // unnamed namespace +#endif // SIMDJSON_SKIPNUMBERPARSING + +} // namespace numberparsing + +inline std::ostream& operator<<(std::ostream& out, number_type type) noexcept { + switch (type) { + case number_type::signed_integer: out << "integer in [-9223372036854775808,9223372036854775808)"; break; + case number_type::unsigned_integer: out << "unsigned integer in [9223372036854775808,18446744073709551616)"; break; + case number_type::floating_point_number: out << "floating-point number (binary64)"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_NUMBERPARSING_H +/* end file simdjson/generic/numberparsing.h for fallback */ + +/* including simdjson/generic/implementation_simdjson_result_base-inl.h for fallback: #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { + +// +// internal::implementation_simdjson_result_base inline implementation +// + +template +simdjson_inline void implementation_simdjson_result_base::tie(T &value, error_code &error) && noexcept { + error = this->second; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +simdjson_warn_unused simdjson_inline error_code implementation_simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; +} + +template +simdjson_inline error_code implementation_simdjson_result_base::error() const noexcept { + return this->second; +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& implementation_simdjson_result_base::value() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline T&& implementation_simdjson_result_base::take_value() && noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& implementation_simdjson_result_base::value_unsafe() const& noexcept { + return this->first; +} + +template +simdjson_inline T& implementation_simdjson_result_base::value_unsafe() & noexcept { + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value_unsafe() && noexcept { + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value, error_code error) noexcept + : first{std::forward(value)}, second{error} {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(error_code error) noexcept + : implementation_simdjson_result_base(T{}, error) {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value) noexcept + : implementation_simdjson_result_base(std::forward(value), SUCCESS) {} + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H +/* end file simdjson/generic/implementation_simdjson_result_base-inl.h for fallback */ +/* end file simdjson/generic/amalgamated.h for fallback */ +/* including simdjson/fallback/end.h: #include "simdjson/fallback/end.h" */ +/* begin file simdjson/fallback/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +/* undefining SIMDJSON_IMPLEMENTATION from "fallback" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/fallback/end.h */ + +#endif // SIMDJSON_FALLBACK_H +/* end file simdjson/fallback.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(haswell) +/* including simdjson/haswell.h: #include "simdjson/haswell.h" */ +/* begin file simdjson/haswell.h */ +#ifndef SIMDJSON_HASWELL_H +#define SIMDJSON_HASWELL_H + +/* including simdjson/haswell/begin.h: #include "simdjson/haswell/begin.h" */ +/* begin file simdjson/haswell/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "haswell" */ +#define SIMDJSON_IMPLEMENTATION haswell + +/* including simdjson/haswell/base.h: #include "simdjson/haswell/base.h" */ +/* begin file simdjson/haswell/base.h */ +#ifndef SIMDJSON_HASWELL_BASE_H +#define SIMDJSON_HASWELL_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_HASWELL +namespace simdjson { +/** + * Implementation for Haswell (Intel AVX2). + */ +namespace haswell { + +class implementation; + +namespace { +namespace simd { +template struct simd8; +template struct simd8x64; +} // namespace simd +} // unnamed namespace + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_BASE_H +/* end file simdjson/haswell/base.h */ +/* including simdjson/haswell/intrinsics.h: #include "simdjson/haswell/intrinsics.h" */ +/* begin file simdjson/haswell/intrinsics.h */ +#ifndef SIMDJSON_HASWELL_INTRINSICS_H +#define SIMDJSON_HASWELL_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + * e.g., if __AVX2__ is set... in turn, we normally set these + * macros by compiling against the corresponding architecture + * (e.g., arch:AVX2, -mavx2, etc.) which compiles the whole + * software with these advanced instructions. In simdjson, we + * want to compile the whole program for a generic target, + * and only target our specific kernels. As a workaround, + * we directly include the needed headers. These headers would + * normally guard against such usage, but we carefully included + * (or ) before, so the headers + * are fooled. + */ +#include // for _blsr_u64 +#include // for __lzcnt64 +#include // for most things (AVX2, AVX512, _popcnt64) +#include +#include +#include +#include +#include // for _mm_clmulepi64_si128 +// unfortunately, we may not get _blsr_u64, but, thankfully, clang +// has it as a macro. +#ifndef _blsr_u64 +// we roll our own +#define _blsr_u64(n) ((n - 1) & n) +#endif // _blsr_u64 +#endif // SIMDJSON_CLANG_VISUAL_STUDIO + +static_assert(sizeof(__m256i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for haswell kernel."); + +#endif // SIMDJSON_HASWELL_INTRINSICS_H +/* end file simdjson/haswell/intrinsics.h */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_HASWELL +SIMDJSON_TARGET_REGION("avx2,bmi,pclmul,lzcnt,popcnt") +#endif + +/* including simdjson/haswell/bitmanipulation.h: #include "simdjson/haswell/bitmanipulation.h" */ +/* begin file simdjson/haswell/bitmanipulation.h */ +#ifndef SIMDJSON_HASWELL_BITMANIPULATION_H +#define SIMDJSON_HASWELL_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/bitmask.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return (int)_tzcnt_u64(input_num); +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + //////// + // You might expect the next line to be equivalent to + // return (int)_tzcnt_u64(input_num); + // but the generated code differs and might be less efficient? + //////// + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return _blsr_u64(input_num); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { + return int(_lzcnt_u64(input_num)); +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_BITMANIPULATION_H +/* end file simdjson/haswell/bitmanipulation.h */ +/* including simdjson/haswell/bitmask.h: #include "simdjson/haswell/bitmask.h" */ +/* begin file simdjson/haswell/bitmask.h */ +#ifndef SIMDJSON_HASWELL_BITMASK_H +#define SIMDJSON_HASWELL_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(const uint64_t bitmask) { + // There should be no such thing with a processor supporting avx2 + // but not clmul. + __m128i all_ones = _mm_set1_epi8('\xFF'); + __m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0ULL, bitmask), all_ones, 0); + return _mm_cvtsi128_si64(result); +} + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_BITMASK_H +/* end file simdjson/haswell/bitmask.h */ +/* including simdjson/haswell/numberparsing_defs.h: #include "simdjson/haswell/numberparsing_defs.h" */ +/* begin file simdjson/haswell/numberparsing_defs.h */ +#ifndef SIMDJSON_HASWELL_NUMBERPARSING_DEFS_H +#define SIMDJSON_HASWELL_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace numberparsing { + +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + // this actually computes *16* values so we are being wasteful. + const __m128i ascii0 = _mm_set1_epi8('0'); + const __m128i mul_1_10 = + _mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1); + const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1); + const __m128i mul_1_10000 = + _mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1); + const __m128i input = _mm_sub_epi8( + _mm_loadu_si128(reinterpret_cast(chars)), ascii0); + const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10); + const __m128i t2 = _mm_madd_epi16(t1, mul_1_100); + const __m128i t3 = _mm_packus_epi32(t2, t2); + const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000); + return _mm_cvtsi128_si32( + t4); // only captures the sum of the first 8 digits, drop the rest +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace haswell +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_HASWELL_NUMBERPARSING_DEFS_H +/* end file simdjson/haswell/numberparsing_defs.h */ +/* including simdjson/haswell/simd.h: #include "simdjson/haswell/simd.h" */ +/* begin file simdjson/haswell/simd.h */ +#ifndef SIMDJSON_HASWELL_SIMD_H +#define SIMDJSON_HASWELL_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace simd { + + // Forward-declared so they can be used by splat and friends. + template + struct base { + __m256i value; + + // Zero constructor + simdjson_inline base() : value{__m256i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m256i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m256i&() const { return this->value; } + simdjson_inline operator __m256i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm256_or_si256(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm256_and_si256(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm256_xor_si256(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm256_andnot_si256(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + // Forward-declared so they can be used by splat and friends. + template + struct simd8; + + template> + struct base8: base> { + typedef uint32_t bitmask_t; + typedef uint64_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m256i _value) : base>(_value) {} + + friend simdjson_really_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return _mm256_cmpeq_epi8(lhs, rhs); } + + static const int SIZE = sizeof(base::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return _mm256_alignr_epi8(*this, _mm256_permute2x128_si256(prev_chunk, *this, 0x21), 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm256_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m256i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { return _mm256_movemask_epi8(*this); } + simdjson_inline bool any() const { return !_mm256_testz_si256(*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm256_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm256_setzero_si256(); } + static simdjson_inline simd8 load(const T values[32]) { + return _mm256_loadu_si256(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m256i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[32]) const { return _mm256_storeu_si256(reinterpret_cast<__m256i *>(dst), *this); } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm256_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm256_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm256_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 32 - count_ones(mask) bytes of the result are significant but 32 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint32_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in four steps, first 8 bytes and then second 8 bytes... + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // second least significant 8 bits + uint8_t mask3 = uint8_t(mask >> 16); // ... + uint8_t mask4 = uint8_t(mask >> 24); // ... + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + __m256i shufmask = _mm256_set_epi64x(thintable_epi8[mask4], thintable_epi8[mask3], + thintable_epi8[mask2], thintable_epi8[mask1]); + // we increment by 0x08 the second half of the mask and so forth + shufmask = + _mm256_add_epi8(shufmask, _mm256_set_epi32(0x18181818, 0x18181818, + 0x10101010, 0x10101010, 0x08080808, 0x08080808, 0, 0)); + // this is the version "nearly pruned" + __m256i pruned = _mm256_shuffle_epi8(*this, shufmask); + // we still need to put the pieces back together. + // we compute the popcount of the first words: + int pop1 = BitsSetTable256mul2[mask1]; + int pop3 = BitsSetTable256mul2[mask3]; + + // then load the corresponding mask + // could be done with _mm256_loadu2_m128i but many standard libraries omit this intrinsic. + __m256i v256 = _mm256_castsi128_si256( + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop1 * 8))); + __m256i compactmask = _mm256_insertf128_si256(v256, + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop3 * 8)), 1); + __m256i almostthere = _mm256_shuffle_epi8(pruned, compactmask); + // We just need to write out the result. + // This is the tricky bit that is hard to do + // if we want to return a SIMD register, since there + // is no single-instruction approach to recombine + // the two 128-bit lanes with an offset. + __m128i v128; + v128 = _mm256_castsi256_si128(almostthere); + _mm_storeu_si128( reinterpret_cast<__m128i *>(output), v128); + v128 = _mm256_extractf128_si256(almostthere, 1); + _mm_storeu_si128( reinterpret_cast<__m128i *>(output + 16 - count_ones(mask & 0xFFFF)), v128); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m256i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t values[32]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15, + int8_t v16, int8_t v17, int8_t v18, int8_t v19, int8_t v20, int8_t v21, int8_t v22, int8_t v23, + int8_t v24, int8_t v25, int8_t v26, int8_t v27, int8_t v28, int8_t v29, int8_t v30, int8_t v31 + ) : simd8(_mm256_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v16,v17,v18,v19,v20,v21,v22,v23, + v24,v25,v26,v27,v28,v29,v30,v31 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm256_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm256_min_epi8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return _mm256_cmpgt_epi8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm256_cmpgt_epi8(other, *this); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m256i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t values[32]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15, + uint8_t v16, uint8_t v17, uint8_t v18, uint8_t v19, uint8_t v20, uint8_t v21, uint8_t v22, uint8_t v23, + uint8_t v24, uint8_t v25, uint8_t v26, uint8_t v27, uint8_t v28, uint8_t v29, uint8_t v30, uint8_t v31 + ) : simd8(_mm256_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v16,v17,v18,v19,v20,v21,v22,v23, + v24,v25,v26,v27,v28,v29,v30,v31 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm256_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm256_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm256_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm256_min_epu8(other, *this); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline simd8 operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline simd8 operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->lt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return *this == uint8_t(0); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + simdjson_inline bool is_ascii() const { return _mm256_movemask_epi8(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { return _mm256_testz_si256(*this, *this); } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return _mm256_testz_si256(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm256_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm256_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline int get_bit() const { return _mm256_movemask_epi8(_mm256_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 2, "Haswell kernel should use two registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1) : chunks{chunk0, chunk1} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+32)} {} + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + uint32_t mask1 = uint32_t(mask); + uint32_t mask2 = uint32_t(mask >> 32); + this->chunks[0].compress(mask1, output); + this->chunks[1].compress(mask2, output + 32 - count_ones(mask1)); + return 64 - count_ones(mask); + } + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r_lo = uint32_t(this->chunks[0].to_bitmask()); + uint64_t r_hi = this->chunks[1].to_bitmask(); + return r_lo | (r_hi << 32); + } + + simdjson_inline simd8 reduce_or() const { + return this->chunks[0] | this->chunks[1]; + } + + simdjson_inline simd8x64 bit_or(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] | mask, + this->chunks[1] | mask + ); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64( + this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1] + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_SIMD_H +/* end file simdjson/haswell/simd.h */ +/* including simdjson/haswell/stringparsing_defs.h: #include "simdjson/haswell/stringparsing_defs.h" */ +/* begin file simdjson/haswell/stringparsing_defs.h */ +#ifndef SIMDJSON_HASWELL_STRINGPARSING_DEFS_H +#define SIMDJSON_HASWELL_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/simd.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return ((quote_bits - 1) & bs_bits) != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 15 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v(src); + // store to dest unconditionally - we can overwrite the bits we don't like later + v.store(dst); + return { + static_cast((v == '\\').to_bitmask()), // bs_bits + static_cast((v == '"').to_bitmask()), // quote_bits + }; +} + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_STRINGPARSING_DEFS_H +/* end file simdjson/haswell/stringparsing_defs.h */ +/* end file simdjson/haswell/begin.h */ +/* including simdjson/generic/amalgamated.h for haswell: #include "simdjson/generic/amalgamated.h" */ +/* begin file simdjson/generic/amalgamated.h for haswell */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_DEPENDENCIES_H) +#error simdjson/generic/dependencies.h must be included before simdjson/generic/amalgamated.h! +#endif + +/* including simdjson/generic/base.h for haswell: #include "simdjson/generic/base.h" */ +/* begin file simdjson/generic/base.h for haswell */ +#ifndef SIMDJSON_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): // If we haven't got an implementation yet, we're in the editor, editing a generic file! Just */ +/* amalgamation skipped (editor-only): // use the most advanced one we can so the most possible stuff can be tested. */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation_detection.h" */ +/* amalgamation skipped (editor-only): #if SIMDJSON_IMPLEMENTATION_ICELAKE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_HASWELL */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_WESTMERE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_ARM64 */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_PPC64 */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_FALLBACK */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/begin.h" */ +/* amalgamation skipped (editor-only): #else */ +/* amalgamation skipped (editor-only): #error "All possible implementations (including fallback) have been disabled! simdjson will not run." */ +/* amalgamation skipped (editor-only): #endif */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { + +struct open_container; +class dom_parser_implementation; + +/** + * The type of a JSON number + */ +enum class number_type { + floating_point_number=1, /// a binary64 number + signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + unsigned_integer /// a positive integer larger or equal to 1<<63 +}; + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_BASE_H +/* end file simdjson/generic/base.h for haswell */ +/* including simdjson/generic/jsoncharutils.h for haswell: #include "simdjson/generic/jsoncharutils.h" */ +/* begin file simdjson/generic/jsoncharutils.h for haswell */ +#ifndef SIMDJSON_GENERIC_JSONCHARUTILS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_JSONCHARUTILS_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/jsoncharutils_tables.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace jsoncharutils { + +// return non-zero if not a structural or whitespace char +// zero otherwise +simdjson_inline uint32_t is_not_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace_negated[c]; +} + +simdjson_inline uint32_t is_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace[c]; +} + +// returns a value with the high 16 bits set if not valid +// otherwise returns the conversion of the 4 hex digits at src into the bottom +// 16 bits of the 32-bit return register +// +// see +// https://lemire.me/blog/2019/04/17/parsing-short-hexadecimal-strings-efficiently/ +static inline uint32_t hex_to_u32_nocheck( + const uint8_t *src) { // strictly speaking, static inline is a C-ism + uint32_t v1 = internal::digit_to_val32[630 + src[0]]; + uint32_t v2 = internal::digit_to_val32[420 + src[1]]; + uint32_t v3 = internal::digit_to_val32[210 + src[2]]; + uint32_t v4 = internal::digit_to_val32[0 + src[3]]; + return v1 | v2 | v3 | v4; +} + +// given a code point cp, writes to c +// the utf-8 code, outputting the length in +// bytes, if the length is zero, the code point +// is invalid +// +// This can possibly be made faster using pdep +// and clz and table lookups, but JSON documents +// have few escaped code points, and the following +// function looks cheap. +// +// Note: we assume that surrogates are treated separately +// +simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) { + if (cp <= 0x7F) { + c[0] = uint8_t(cp); + return 1; // ascii + } + if (cp <= 0x7FF) { + c[0] = uint8_t((cp >> 6) + 192); + c[1] = uint8_t((cp & 63) + 128); + return 2; // universal plane + // Surrogates are treated elsewhere... + //} //else if (0xd800 <= cp && cp <= 0xdfff) { + // return 0; // surrogates // could put assert here + } else if (cp <= 0xFFFF) { + c[0] = uint8_t((cp >> 12) + 224); + c[1] = uint8_t(((cp >> 6) & 63) + 128); + c[2] = uint8_t((cp & 63) + 128); + return 3; + } else if (cp <= 0x10FFFF) { // if you know you have a valid code point, this + // is not needed + c[0] = uint8_t((cp >> 18) + 240); + c[1] = uint8_t(((cp >> 12) & 63) + 128); + c[2] = uint8_t(((cp >> 6) & 63) + 128); + c[3] = uint8_t((cp & 63) + 128); + return 4; + } + // will return 0 when the code point was too large. + return 0; // bad r +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +} // namespace jsoncharutils +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_JSONCHARUTILS_H +/* end file simdjson/generic/jsoncharutils.h for haswell */ +/* including simdjson/generic/atomparsing.h for haswell: #include "simdjson/generic/atomparsing.h" */ +/* begin file simdjson/generic/atomparsing.h for haswell */ +#ifndef SIMDJSON_GENERIC_ATOMPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ATOMPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace haswell { +namespace { +/// @private +namespace atomparsing { + +// The string_to_uint32 is exclusively used to map literal strings to 32-bit values. +// We use memcpy instead of a pointer cast to avoid undefined behaviors since we cannot +// be certain that the character pointer will be properly aligned. +// You might think that using memcpy makes this function expensive, but you'd be wrong. +// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false"); +// to the compile-time constant 1936482662. +simdjson_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; } + + +// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive. +// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about. +simdjson_warn_unused +simdjson_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) { + uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++) + static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes"); + std::memcpy(&srcval, src, sizeof(uint32_t)); + return srcval ^ string_to_uint32(atom); +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src) { + return (str4ncmp(src, "true") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_true_atom(src); } + else if (len == 4) { return !str4ncmp(src, "true"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src) { + return (str4ncmp(src+1, "alse") | jsoncharutils::is_not_structural_or_whitespace(src[5])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src, size_t len) { + if (len > 5) { return is_valid_false_atom(src); } + else if (len == 5) { return !str4ncmp(src+1, "alse"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src) { + return (str4ncmp(src, "null") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_null_atom(src); } + else if (len == 4) { return !str4ncmp(src, "null"); } + else { return false; } +} + +} // namespace atomparsing +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ATOMPARSING_H +/* end file simdjson/generic/atomparsing.h for haswell */ +/* including simdjson/generic/dom_parser_implementation.h for haswell: #include "simdjson/generic/dom_parser_implementation.h" */ +/* begin file simdjson/generic/dom_parser_implementation.h for haswell */ +#ifndef SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { + +// expectation: sizeof(open_container) = 64/8. +struct open_container { + uint32_t tape_index; // where, on the tape, does the scope ([,{) begins + uint32_t count; // how many elements in the scope +}; // struct open_container + +static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits"); + +class dom_parser_implementation final : public internal::dom_parser_implementation { +public: + /** Tape location of each open { or [ */ + std::unique_ptr open_containers{}; + /** Whether each open container is a [ or { */ + std::unique_ptr is_array{}; + /** Buffer passed to stage 1 */ + const uint8_t *buf{}; + /** Length passed to stage 1 */ + size_t len{0}; + /** Document passed to stage 2 */ + dom::document *doc{}; + + inline dom_parser_implementation() noexcept; + inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; + inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; + dom_parser_implementation(const dom_parser_implementation &) = delete; + dom_parser_implementation &operator=(const dom_parser_implementation &) = delete; + + simdjson_warn_unused error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage1(const uint8_t *buf, size_t len, stage1_mode partial) noexcept final; + simdjson_warn_unused error_code stage2(dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage2_next(dom::document &doc) noexcept final; + simdjson_warn_unused uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept final; + simdjson_warn_unused uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept final; + inline simdjson_warn_unused error_code set_capacity(size_t capacity) noexcept final; + inline simdjson_warn_unused error_code set_max_depth(size_t max_depth) noexcept final; +private: + simdjson_inline simdjson_warn_unused error_code set_capacity_stage1(size_t capacity); + +}; + +} // namespace haswell +} // namespace simdjson + +namespace simdjson { +namespace haswell { + +inline dom_parser_implementation::dom_parser_implementation() noexcept = default; +inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; +inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; + +// Leaving these here so they can be inlined if so desired +inline simdjson_warn_unused error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept { + if(capacity > SIMDJSON_MAXSIZE_BYTES) { return CAPACITY; } + // Stage 1 index output + size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7; + structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] ); + if (!structural_indexes) { _capacity = 0; return MEMALLOC; } + structural_indexes[0] = 0; + n_structural_indexes = 0; + + _capacity = capacity; + return SUCCESS; +} + +inline simdjson_warn_unused error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept { + // Stage 2 stacks + open_containers.reset(new (std::nothrow) open_container[max_depth]); + is_array.reset(new (std::nothrow) bool[max_depth]); + if (!is_array || !open_containers) { _max_depth = 0; return MEMALLOC; } + + _max_depth = max_depth; + return SUCCESS; +} + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file simdjson/generic/dom_parser_implementation.h for haswell */ +/* including simdjson/generic/implementation_simdjson_result_base.h for haswell: #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base.h for haswell */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { + +// This is a near copy of include/error.h's implementation_simdjson_result_base, except it doesn't use std::pair +// so we can avoid inlining errors +// TODO reconcile these! +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + * + * This is a base class for implementations that want to add functions to the result type for + * chaining. + * + * Override like: + * + * struct simdjson_result : public internal::implementation_simdjson_result_base { + * simdjson_result() noexcept : internal::implementation_simdjson_result_base() {} + * simdjson_result(error_code error) noexcept : internal::implementation_simdjson_result_base(error) {} + * simdjson_result(T &&value) noexcept : internal::implementation_simdjson_result_base(std::forward(value)) {} + * simdjson_result(T &&value, error_code error) noexcept : internal::implementation_simdjson_result_base(value, error) {} + * // Your extra methods here + * } + * + * Then any method returning simdjson_result will be chainable with your methods. + */ +template +struct implementation_simdjson_result_base { + + /** + * Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline implementation_simdjson_result_base() noexcept = default; + + /** + * Create a new error result. + */ + simdjson_inline implementation_simdjson_result_base(error_code error) noexcept; + + /** + * Create a new successful result. + */ + simdjson_inline implementation_simdjson_result_base(T &&value) noexcept; + + /** + * Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline implementation_simdjson_result_base(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); + + +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T& value_unsafe() & noexcept; + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; +protected: + /** users should never directly access first and second. **/ + T first{}; /** Users should never directly access 'first'. **/ + error_code second{UNINITIALIZED}; /** Users should never directly access 'second'. **/ +}; // struct implementation_simdjson_result_base + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H +/* end file simdjson/generic/implementation_simdjson_result_base.h for haswell */ +/* including simdjson/generic/numberparsing.h for haswell: #include "simdjson/generic/numberparsing.h" */ +/* begin file simdjson/generic/numberparsing.h for haswell */ +#ifndef SIMDJSON_GENERIC_NUMBERPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_NUMBERPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include +#include + +namespace simdjson { +namespace haswell { +namespace numberparsing { + +#ifdef JSON_TEST_NUMBERS +#define INVALID_NUMBER(SRC) (found_invalid_number((SRC)), NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (found_integer((VALUE), (SRC)), (WRITER).append_s64((VALUE))) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (found_unsigned_integer((VALUE), (SRC)), (WRITER).append_u64((VALUE))) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (found_float((VALUE), (SRC)), (WRITER).append_double((VALUE))) +#else +#define INVALID_NUMBER(SRC) (NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (WRITER).append_s64((VALUE)) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (WRITER).append_u64((VALUE)) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (WRITER).append_double((VALUE)) +#endif + +namespace { + +// Convert a mantissa, an exponent and a sign bit into an ieee64 double. +// The real_exponent needs to be in [0, 2046] (technically real_exponent = 2047 would be acceptable). +// The mantissa should be in [0,1<<53). The bit at index (1ULL << 52) while be zeroed. +simdjson_inline double to_double(uint64_t mantissa, uint64_t real_exponent, bool negative) { + double d; + mantissa &= ~(1ULL << 52); + mantissa |= real_exponent << 52; + mantissa |= ((static_cast(negative)) << 63); + std::memcpy(&d, &mantissa, sizeof(d)); + return d; +} + +// Attempts to compute i * 10^(power) exactly; and if "negative" is +// true, negate the result. +// This function will only work in some cases, when it does not work, success is +// set to false. This should work *most of the time* (like 99% of the time). +// We assume that power is in the [smallest_power, +// largest_power] interval: the caller is responsible for this check. +simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative, double &d) { + // we start with a fast path + // It was described in + // Clinger WD. How to read floating point numbers accurately. + // ACM SIGPLAN Notices. 1990 +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + // We cannot be certain that x/y is rounded to nearest. + if (0 <= power && power <= 22 && i <= 9007199254740991) +#else + if (-22 <= power && power <= 22 && i <= 9007199254740991) +#endif + { + // convert the integer into a double. This is lossless since + // 0 <= i <= 2^53 - 1. + d = double(i); + // + // The general idea is as follows. + // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then + // 1) Both s and p can be represented exactly as 64-bit floating-point + // values + // (binary64). + // 2) Because s and p can be represented exactly as floating-point values, + // then s * p + // and s / p will produce correctly rounded values. + // + if (power < 0) { + d = d / simdjson::internal::power_of_ten[-power]; + } else { + d = d * simdjson::internal::power_of_ten[power]; + } + if (negative) { + d = -d; + } + return true; + } + // When 22 < power && power < 22 + 16, we could + // hope for another, secondary fast path. It was + // described by David M. Gay in "Correctly rounded + // binary-decimal and decimal-binary conversions." (1990) + // If you need to compute i * 10^(22 + x) for x < 16, + // first compute i * 10^x, if you know that result is exact + // (e.g., when i * 10^x < 2^53), + // then you can still proceed and do (i * 10^x) * 10^22. + // Is this worth your time? + // You need 22 < power *and* power < 22 + 16 *and* (i * 10^(x-22) < 2^53) + // for this second fast path to work. + // If you you have 22 < power *and* power < 22 + 16, and then you + // optimistically compute "i * 10^(x-22)", there is still a chance that you + // have wasted your time if i * 10^(x-22) >= 2^53. It makes the use cases of + // this optimization maybe less common than we would like. Source: + // http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + // also used in RapidJSON: https://rapidjson.org/strtod_8h_source.html + + // The fast path has now failed, so we are failing back on the slower path. + + // In the slow path, we need to adjust i so that it is > 1<<63 which is always + // possible, except if i == 0, so we handle i == 0 separately. + if(i == 0) { + d = negative ? -0.0 : 0.0; + return true; + } + + + // The exponent is 1024 + 63 + power + // + floor(log(5**power)/log(2)). + // The 1024 comes from the ieee64 standard. + // The 63 comes from the fact that we use a 64-bit word. + // + // Computing floor(log(5**power)/log(2)) could be + // slow. Instead we use a fast function. + // + // For power in (-400,350), we have that + // (((152170 + 65536) * power ) >> 16); + // is equal to + // floor(log(5**power)/log(2)) + power when power >= 0 + // and it is equal to + // ceil(log(5**-power)/log(2)) + power when power < 0 + // + // The 65536 is (1<<16) and corresponds to + // (65536 * power) >> 16 ---> power + // + // ((152170 * power ) >> 16) is equal to + // floor(log(5**power)/log(2)) + // + // Note that this is not magic: 152170/(1<<16) is + // approximatively equal to log(5)/log(2). + // The 1<<16 value is a power of two; we could use a + // larger power of 2 if we wanted to. + // + int64_t exponent = (((152170 + 65536) * power) >> 16) + 1024 + 63; + + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(i); + i <<= lz; + + + // We are going to need to do some 64-bit arithmetic to get a precise product. + // We use a table lookup approach. + // It is safe because + // power >= smallest_power + // and power <= largest_power + // We recover the mantissa of the power, it has a leading 1. It is always + // rounded down. + // + // We want the most significant 64 bits of the product. We know + // this will be non-zero because the most significant bit of i is + // 1. + const uint32_t index = 2 * uint32_t(power - simdjson::internal::smallest_power); + // Optimization: It may be that materializing the index as a variable might confuse some compilers and prevent effective complex-addressing loads. (Done for code clarity.) + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); + // Both i and power_of_five_128[index] have their most significant bit set to 1 which + // implies that the either the most or the second most significant bit of the product + // is 1. We pack values in this manner for efficiency reasons: it maximizes the use + // we make of the product. It also makes it easy to reason about the product: there + // is 0 or 1 leading zero in the product. + + // Unless the least significant 9 bits of the high (64-bit) part of the full + // product are all 1s, then we know that the most significant 55 bits are + // exact and no further work is needed. Having 55 bits is necessary because + // we need 53 bits for the mantissa but we have to have one rounding bit and + // we can waste a bit if the most significant bit of the product is zero. + if((firstproduct.high & 0x1FF) == 0x1FF) { + // We want to compute i * 5^q, but only care about the top 55 bits at most. + // Consider the scenario where q>=0. Then 5^q may not fit in 64-bits. Doing + // the full computation is wasteful. So we do what is called a "truncated + // multiplication". + // We take the most significant 64-bits, and we put them in + // power_of_five_128[index]. Usually, that's good enough to approximate i * 5^q + // to the desired approximation using one multiplication. Sometimes it does not suffice. + // Then we store the next most significant 64 bits in power_of_five_128[index + 1], and + // then we get a better approximation to i * 5^q. + // + // That's for when q>=0. The logic for q<0 is somewhat similar but it is somewhat + // more complicated. + // + // There is an extra layer of complexity in that we need more than 55 bits of + // accuracy in the round-to-even scenario. + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if(secondproduct.high > firstproduct.low) { firstproduct.high++; } + // As it has been proven by Noble Mushtak and Daniel Lemire in "Fast Number Parsing Without + // Fallback" (https://arxiv.org/abs/2212.06644), at this point we are sure that the product + // is sufficiently accurate, and more computation is not needed. + } + uint64_t lower = firstproduct.low; + uint64_t upper = firstproduct.high; + // The final mantissa should be 53 bits with a leading 1. + // We shift it so that it occupies 54 bits with a leading 1. + /////// + uint64_t upperbit = upper >> 63; + uint64_t mantissa = upper >> (upperbit + 9); + lz += int(1 ^ upperbit); + + // Here we have mantissa < (1<<54). + int64_t real_exponent = exponent - lz; + if (simdjson_unlikely(real_exponent <= 0)) { // we have a subnormal? + // Here have that real_exponent <= 0 so -real_exponent >= 0 + if(-real_exponent + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure. + d = negative ? -0.0 : 0.0; + return true; + } + // next line is safe because -real_exponent + 1 < 0 + mantissa >>= -real_exponent + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0. + mantissa += (mantissa & 1); // round up + mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + real_exponent = (mantissa < (uint64_t(1) << 52)) ? 0 : 1; + d = to_double(mantissa, real_exponent, negative); + return true; + } + // We have to round to even. The "to even" part + // is only a problem when we are right in between two floats + // which we guard against. + // If we have lots of trailing zeros, we may fall right between two + // floating-point values. + // + // The round-to-even cases take the form of a number 2m+1 which is in (2^53,2^54] + // times a power of two. That is, it is right between a number with binary significand + // m and another number with binary significand m+1; and it must be the case + // that it cannot be represented by a float itself. + // + // We must have that w * 10 ^q == (2m+1) * 2^p for some power of two 2^p. + // Recall that 10^q = 5^q * 2^q. + // When q >= 0, we must have that (2m+1) is divible by 5^q, so 5^q <= 2^54. We have that + // 5^23 <= 2^54 and it is the last power of five to qualify, so q <= 23. + // When q<0, we have w >= (2m+1) x 5^{-q}. We must have that w<2^{64} so + // (2m+1) x 5^{-q} < 2^{64}. We have that 2m+1>2^{53}. Hence, we must have + // 2^{53} x 5^{-q} < 2^{64}. + // Hence we have 5^{-q} < 2^{11}$ or q>= -4. + // + // We require lower <= 1 and not lower == 0 because we could not prove that + // that lower == 0 is implied; but we could prove that lower <= 1 is a necessary and sufficient test. + if (simdjson_unlikely((lower <= 1) && (power >= -4) && (power <= 23) && ((mantissa & 3) == 1))) { + if((mantissa << (upperbit + 64 - 53 - 2)) == upper) { + mantissa &= ~1; // flip it so that we do not round up + } + } + + mantissa += mantissa & 1; + mantissa >>= 1; + + // Here we have mantissa < (1<<53), unless there was an overflow + if (mantissa >= (1ULL << 53)) { + ////////// + // This will happen when parsing values such as 7.2057594037927933e+16 + //////// + mantissa = (1ULL << 52); + real_exponent++; + } + mantissa &= ~(1ULL << 52); + // we have to check that real_exponent is in range, otherwise we bail out + if (simdjson_unlikely(real_exponent > 2046)) { + // We have an infinite value!!! We could actually throw an error here if we could. + return false; + } + d = to_double(mantissa, real_exponent, negative); + return true; +} + +// We call a fallback floating-point parser that might be slow. Note +// it will accept JSON numbers, but the JSON spec. is more restrictive so +// before you call parse_float_fallback, you need to have validated the input +// string with the JSON grammar. +// It will return an error (false) if the parsed number is infinite. +// The string parsing itself always succeeds. We know that there is at least +// one digit. +static bool parse_float_fallback(const uint8_t *ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +static bool parse_float_fallback(const uint8_t *ptr, const uint8_t *end_ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr), reinterpret_cast(end_ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +// check quickly whether the next 8 chars are made of digits +// at a glance, it looks better than Mula's +// http://0x80.pl/articles/swar-digits-validate.html +simdjson_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) { + uint64_t val; + // this can read up to 7 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(7 <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be bigger than 7"); + std::memcpy(&val, chars, 8); + // a branchy method might be faster: + // return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030) + // && (( (val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0 ) == + // 0x3030303030303030); + return (((val & 0xF0F0F0F0F0F0F0F0) | + (((val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4)) == + 0x3333333333333333); +} + +template +SIMDJSON_NO_SANITIZE_UNDEFINED // We deliberately allow overflow here and check later +simdjson_inline bool parse_digit(const uint8_t c, I &i) { + const uint8_t digit = static_cast(c - '0'); + if (digit > 9) { + return false; + } + // PERF NOTE: multiplication by 10 is cheaper than arbitrary integer multiplication + i = 10 * i + digit; // might overflow, we will handle the overflow later + return true; +} + +simdjson_inline error_code parse_decimal_after_separator(simdjson_unused const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) { + // we continue with the fiction that we have an integer. If the + // floating point number is representable as x * 10^z for some integer + // z that fits in 53 bits, then we will be able to convert back the + // the integer into a float in a lossless manner. + const uint8_t *const first_after_period = p; + +#ifdef SIMDJSON_SWAR_NUMBER_PARSING +#if SIMDJSON_SWAR_NUMBER_PARSING + // this helps if we have lots of decimals! + // this turns out to be frequent enough. + if (is_made_of_eight_digits_fast(p)) { + i = i * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + } +#endif // SIMDJSON_SWAR_NUMBER_PARSING +#endif // #ifdef SIMDJSON_SWAR_NUMBER_PARSING + // Unrolling the first digit makes a small difference on some implementations (e.g. westmere) + if (parse_digit(*p, i)) { ++p; } + while (parse_digit(*p, i)) { p++; } + exponent = first_after_period - p; + // Decimal without digits (123.) is illegal + if (exponent == 0) { + return INVALID_NUMBER(src); + } + return SUCCESS; +} + +simdjson_inline error_code parse_exponent(simdjson_unused const uint8_t *const src, const uint8_t *&p, int64_t &exponent) { + // Exp Sign: -123.456e[-]78 + bool neg_exp = ('-' == *p); + if (neg_exp || '+' == *p) { p++; } // Skip + as well + + // Exponent: -123.456e-[78] + auto start_exp = p; + int64_t exp_number = 0; + while (parse_digit(*p, exp_number)) { ++p; } + // It is possible for parse_digit to overflow. + // In particular, it could overflow to INT64_MIN, and we cannot do - INT64_MIN. + // Thus we *must* check for possible overflow before we negate exp_number. + + // Performance notes: it may seem like combining the two "simdjson_unlikely checks" below into + // a single simdjson_unlikely path would be faster. The reasoning is sound, but the compiler may + // not oblige and may, in fact, generate two distinct paths in any case. It might be + // possible to do uint64_t(p - start_exp - 1) >= 18 but it could end up trading off + // instructions for a simdjson_likely branch, an unconclusive gain. + + // If there were no digits, it's an error. + if (simdjson_unlikely(p == start_exp)) { + return INVALID_NUMBER(src); + } + // We have a valid positive exponent in exp_number at this point, except that + // it may have overflowed. + + // If there were more than 18 digits, we may have overflowed the integer. We have to do + // something!!!! + if (simdjson_unlikely(p > start_exp+18)) { + // Skip leading zeroes: 1e000000000000000000001 is technically valid and doesn't overflow + while (*start_exp == '0') { start_exp++; } + // 19 digits could overflow int64_t and is kind of absurd anyway. We don't + // support exponents smaller than -999,999,999,999,999,999 and bigger + // than 999,999,999,999,999,999. + // We can truncate. + // Note that 999999999999999999 is assuredly too large. The maximal ieee64 value before + // infinity is ~1.8e308. The smallest subnormal is ~5e-324. So, actually, we could + // truncate at 324. + // Note that there is no reason to fail per se at this point in time. + // E.g., 0e999999999999999999999 is a fine number. + if (p > start_exp+18) { exp_number = 999999999999999999; } + } + // At this point, we know that exp_number is a sane, positive, signed integer. + // It is <= 999,999,999,999,999,999. As long as 'exponent' is in + // [-8223372036854775808, 8223372036854775808], we won't overflow. Because 'exponent' + // is bounded in magnitude by the size of the JSON input, we are fine in this universe. + // To sum it up: the next line should never overflow. + exponent += (neg_exp ? -exp_number : exp_number); + return SUCCESS; +} + +simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t digit_count) { + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + const uint8_t *start = start_digits; + while ((*start == '0') || (*start == '.')) { ++start; } + // we over-decrement by one when there is a '.' + return digit_count - size_t(start - start_digits); +} + +} // unnamed namespace + +/** @private */ +static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) { + if (parse_float_fallback(src, answer)) { + return SUCCESS; + } + return INVALID_NUMBER(src); +} + +/** @private */ +template +simdjson_inline error_code write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer) { + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon in practice. + // + // 9999999999999999999 < 2**64 so we can accommodate 19 digits. + // If we have a decimal separator, then digit_count - 1 is the number of digits, but we + // may not have a decimal separator! + if (simdjson_unlikely(digit_count > 19 && significant_digits(start_digits, digit_count) > 19)) { + // Ok, chances are good that we had an overflow! + // this is almost never going to get called!!! + // we start anew, going slowly!!! + // This will happen in the following examples: + // 10000000000000000000000000000000000000000000e+308 + // 3.1415926535897932384626433832795028841971693993751 + // + // NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer + // reference to it, it would force it to be stored in memory, preventing the compiler from + // picking it apart and putting into registers. i.e. if we pass it as reference, + // it gets slow. + double d; + error_code error = slow_float_parsing(src, &d); + writer.append_double(d); + return error; + } + // NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other + // way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331 + // To future reader: we'd love if someone found a better way, or at least could explain this result! + if (simdjson_unlikely(exponent < simdjson::internal::smallest_power) || (exponent > simdjson::internal::largest_power)) { + // + // Important: smallest_power is such that it leads to a zero value. + // Observe that 18446744073709551615e-343 == 0, i.e. (2**64 - 1) e -343 is zero + // so something x 10^-343 goes to zero, but not so with something x 10^-342. + static_assert(simdjson::internal::smallest_power <= -342, "smallest_power is not small enough"); + // + if((exponent < simdjson::internal::smallest_power) || (i == 0)) { + // E.g. Parse "-0.0e-999" into the same value as "-0.0". See https://en.wikipedia.org/wiki/Signed_zero + WRITE_DOUBLE(negative ? -0.0 : 0.0, src, writer); + return SUCCESS; + } else { // (exponent > largest_power) and (i != 0) + // We have, for sure, an infinite value and simdjson refuses to parse infinite values. + return INVALID_NUMBER(src); + } + } + double d; + if (!compute_float_64(exponent, i, negative, d)) { + // we are almost never going to get here. + if (!parse_float_fallback(src, &d)) { return INVALID_NUMBER(src); } + } + WRITE_DOUBLE(d, src, writer); + return SUCCESS; +} + +// for performance analysis, it is sometimes useful to skip parsing +#ifdef SIMDJSON_SKIPNUMBERPARSING + +template +simdjson_inline error_code parse_number(const uint8_t *const, W &writer) { + writer.append_s64(0); // always write zero + return SUCCESS; // always succeeds +} + +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { return number_type::signed_integer; } +#else + +// parse the number at src +// define JSON_TEST_NUMBERS for unit testing +// +// It is assumed that the number is followed by a structural ({,},],[) character +// or a white space character. If that is not the case (e.g., when the JSON +// document is made of a single number), then it is necessary to copy the +// content and append a space before calling this function. +// +// Our objective is accurate parsing (ULP of 0) at high speed. +template +simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) { + + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + if (digit_count == 0 || ('0' == *start_digits && digit_count > 1)) { return INVALID_NUMBER(src); } + + // + // Handle floats if there is a . or e (or both) + // + int64_t exponent = 0; + bool is_float = false; + if ('.' == *p) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) ); + digit_count = int(p - start_digits); // used later to guard against overflows + } + if (('e' == *p) || ('E' == *p)) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_exponent(src, p, exponent) ); + } + if (is_float) { + const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p); + SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) ); + if (dirty_end) { return INVALID_NUMBER(src); } + return SUCCESS; + } + + // The longest negative 64-bit number is 19 digits. + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + size_t longest_digit_count = negative ? 19 : 20; + if (digit_count > longest_digit_count) { return INVALID_NUMBER(src); } + if (digit_count == longest_digit_count) { + if (negative) { + // Anything negative above INT64_MAX+1 is invalid + if (i > uint64_t(INT64_MAX)+1) { return INVALID_NUMBER(src); } + WRITE_INTEGER(~i+1, src, writer); + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + } else if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INVALID_NUMBER(src); } + } + + // Write unsigned if it doesn't fit in a signed integer. + if (i > uint64_t(INT64_MAX)) { + WRITE_UNSIGNED(i, src, writer); + } else { + WRITE_INTEGER(negative ? (~i+1) : i, src, writer); + } + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; +} + +// Inlineable functions +namespace { + +// This table can be used to characterize the final character of an integer +// string. For JSON structural character and allowable white space characters, +// we return SUCCESS. For 'e', '.' and 'E', we return INCORRECT_TYPE. Otherwise +// we return NUMBER_ERROR. +// Optimization note: we could easily reduce the size of the table by half (to 128) +// at the cost of an extra branch. +// Optimization note: we want the values to use at most 8 bits (not, e.g., 32 bits): +static_assert(error_code(uint8_t(NUMBER_ERROR))== NUMBER_ERROR, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(SUCCESS))== SUCCESS, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(INCORRECT_TYPE))== INCORRECT_TYPE, "bad NUMBER_ERROR cast"); + +const uint8_t integer_string_finisher[256] = { + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, INCORRECT_TYPE, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, SUCCESS, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR}; + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + + +// Parse any number from 0 to 18,446,744,073,709,551,615 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src, const uint8_t * const src_end) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if ((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { + const uint8_t *p = src + 1; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (*p != '"') { return NUMBER_ERROR; } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + // Note: we use src[1] and not src[0] because src[0] is the quote character in this + // instance. + if (src[1] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src, const uint8_t * const src_end) noexcept { + // + // Check for minus sign + // + if(src == src_end) { return NUMBER_ERROR; } + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = src; + uint64_t i = 0; + while (parse_digit(*src, i)) { src++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(src - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*src)) { + // return (*src == '.' || *src == 'e' || *src == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(*src != '"') { return NUMBER_ERROR; } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { + return (*src == '-'); +} + +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { return true; } + return false; +} + +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { + // We have an integer. + // If the number is negative and valid, it must be a signed integer. + if(negative) { return number_type::signed_integer; } + // We want values larger or equal to 9223372036854775808 to be unsigned + // integers, and the other values to be signed integers. + int digit_count = int(p - src); + if(digit_count >= 19) { + const uint8_t * smaller_big_integer = reinterpret_cast("9223372036854775808"); + if((digit_count >= 20) || (memcmp(src, smaller_big_integer, 19) >= 0)) { + return number_type::unsigned_integer; + } + } + return number_type::signed_integer; + } + // Hopefully, we have 'e' or 'E' or '.'. + return number_type::floating_point_number; +} + +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src, const uint8_t * const src_end) noexcept { + if(src == src_end) { return NUMBER_ERROR; } + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + if(p == src_end) { return NUMBER_ERROR; } + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while ((p != src_end) && parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely((p != src_end) && (*p == '.'))) { + p++; + const uint8_t *start_decimal_digits = p; + if ((p == src_end) || !parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = start_digits-src > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if ((p != src_end) && (*p == 'e' || *p == 'E')) { + p++; + if(p == src_end) { return NUMBER_ERROR; } + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while ((p != src_end) && parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (*p != '"') { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +} // unnamed namespace +#endif // SIMDJSON_SKIPNUMBERPARSING + +} // namespace numberparsing + +inline std::ostream& operator<<(std::ostream& out, number_type type) noexcept { + switch (type) { + case number_type::signed_integer: out << "integer in [-9223372036854775808,9223372036854775808)"; break; + case number_type::unsigned_integer: out << "unsigned integer in [9223372036854775808,18446744073709551616)"; break; + case number_type::floating_point_number: out << "floating-point number (binary64)"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_NUMBERPARSING_H +/* end file simdjson/generic/numberparsing.h for haswell */ + +/* including simdjson/generic/implementation_simdjson_result_base-inl.h for haswell: #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { + +// +// internal::implementation_simdjson_result_base inline implementation +// + +template +simdjson_inline void implementation_simdjson_result_base::tie(T &value, error_code &error) && noexcept { + error = this->second; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +simdjson_warn_unused simdjson_inline error_code implementation_simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; +} + +template +simdjson_inline error_code implementation_simdjson_result_base::error() const noexcept { + return this->second; +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& implementation_simdjson_result_base::value() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline T&& implementation_simdjson_result_base::take_value() && noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& implementation_simdjson_result_base::value_unsafe() const& noexcept { + return this->first; +} + +template +simdjson_inline T& implementation_simdjson_result_base::value_unsafe() & noexcept { + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value_unsafe() && noexcept { + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value, error_code error) noexcept + : first{std::forward(value)}, second{error} {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(error_code error) noexcept + : implementation_simdjson_result_base(T{}, error) {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value) noexcept + : implementation_simdjson_result_base(std::forward(value), SUCCESS) {} + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H +/* end file simdjson/generic/implementation_simdjson_result_base-inl.h for haswell */ +/* end file simdjson/generic/amalgamated.h for haswell */ +/* including simdjson/haswell/end.h: #include "simdjson/haswell/end.h" */ +/* begin file simdjson/haswell/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_HASWELL +SIMDJSON_UNTARGET_REGION +#endif + +/* undefining SIMDJSON_IMPLEMENTATION from "haswell" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/haswell/end.h */ + +#endif // SIMDJSON_HASWELL_H +/* end file simdjson/haswell.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(icelake) +/* including simdjson/icelake.h: #include "simdjson/icelake.h" */ +/* begin file simdjson/icelake.h */ +#ifndef SIMDJSON_ICELAKE_H +#define SIMDJSON_ICELAKE_H + +/* including simdjson/icelake/begin.h: #include "simdjson/icelake/begin.h" */ +/* begin file simdjson/icelake/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "icelake" */ +#define SIMDJSON_IMPLEMENTATION icelake +/* including simdjson/icelake/base.h: #include "simdjson/icelake/base.h" */ +/* begin file simdjson/icelake/base.h */ +#ifndef SIMDJSON_ICELAKE_BASE_H +#define SIMDJSON_ICELAKE_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_ICELAKE +namespace simdjson { +/** + * Implementation for Icelake (Intel AVX512). + */ +namespace icelake { + +class implementation; + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_BASE_H +/* end file simdjson/icelake/base.h */ +/* including simdjson/icelake/intrinsics.h: #include "simdjson/icelake/intrinsics.h" */ +/* begin file simdjson/icelake/intrinsics.h */ +#ifndef SIMDJSON_ICELAKE_INTRINSICS_H +#define SIMDJSON_ICELAKE_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + * e.g., if __AVX2__ is set... in turn, we normally set these + * macros by compiling against the corresponding architecture + * (e.g., arch:AVX2, -mavx2, etc.) which compiles the whole + * software with these advanced instructions. In simdjson, we + * want to compile the whole program for a generic target, + * and only target our specific kernels. As a workaround, + * we directly include the needed headers. These headers would + * normally guard against such usage, but we carefully included + * (or ) before, so the headers + * are fooled. + */ +#include // for _blsr_u64 +#include // for __lzcnt64 +#include // for most things (AVX2, AVX512, _popcnt64) +#include +#include +#include +#include +#include // for _mm_clmulepi64_si128 +// Important: we need the AVX-512 headers: +#include +#include +#include +#include +#include +#include +#include +// unfortunately, we may not get _blsr_u64, but, thankfully, clang +// has it as a macro. +#ifndef _blsr_u64 +// we roll our own +#define _blsr_u64(n) ((n - 1) & n) +#endif // _blsr_u64 +#endif // SIMDJSON_CLANG_VISUAL_STUDIO + +static_assert(sizeof(__m512i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for icelake"); + +#endif // SIMDJSON_ICELAKE_INTRINSICS_H +/* end file simdjson/icelake/intrinsics.h */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_ICELAKE +SIMDJSON_TARGET_REGION("avx512f,avx512dq,avx512cd,avx512bw,avx512vbmi,avx512vbmi2,avx512vl,avx2,bmi,pclmul,lzcnt,popcnt") +#endif + +/* including simdjson/icelake/bitmanipulation.h: #include "simdjson/icelake/bitmanipulation.h" */ +/* begin file simdjson/icelake/bitmanipulation.h */ +#ifndef SIMDJSON_ICELAKE_BITMANIPULATION_H +#define SIMDJSON_ICELAKE_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return (int)_tzcnt_u64(input_num); +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + //////// + // You might expect the next line to be equivalent to + // return (int)_tzcnt_u64(input_num); + // but the generated code differs and might be less efficient? + //////// + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return _blsr_u64(input_num); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { + return int(_lzcnt_u64(input_num)); +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_BITMANIPULATION_H +/* end file simdjson/icelake/bitmanipulation.h */ +/* including simdjson/icelake/bitmask.h: #include "simdjson/icelake/bitmask.h" */ +/* begin file simdjson/icelake/bitmask.h */ +#ifndef SIMDJSON_ICELAKE_BITMASK_H +#define SIMDJSON_ICELAKE_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(const uint64_t bitmask) { + // There should be no such thing with a processor supporting avx2 + // but not clmul. + __m128i all_ones = _mm_set1_epi8('\xFF'); + __m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0ULL, bitmask), all_ones, 0); + return _mm_cvtsi128_si64(result); +} + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_BITMASK_H +/* end file simdjson/icelake/bitmask.h */ +/* including simdjson/icelake/simd.h: #include "simdjson/icelake/simd.h" */ +/* begin file simdjson/icelake/simd.h */ +#ifndef SIMDJSON_ICELAKE_SIMD_H +#define SIMDJSON_ICELAKE_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if defined(__GNUC__) && !defined(__clang__) +#if __GNUC__ == 8 +#define SIMDJSON_GCC8 1 +#endif // __GNUC__ == 8 +#endif // defined(__GNUC__) && !defined(__clang__) + +#if SIMDJSON_GCC8 +/** + * GCC 8 fails to provide _mm512_set_epi8. We roll our own. + */ +inline __m512i _mm512_set_epi8(uint8_t a0, uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4, uint8_t a5, uint8_t a6, uint8_t a7, uint8_t a8, uint8_t a9, uint8_t a10, uint8_t a11, uint8_t a12, uint8_t a13, uint8_t a14, uint8_t a15, uint8_t a16, uint8_t a17, uint8_t a18, uint8_t a19, uint8_t a20, uint8_t a21, uint8_t a22, uint8_t a23, uint8_t a24, uint8_t a25, uint8_t a26, uint8_t a27, uint8_t a28, uint8_t a29, uint8_t a30, uint8_t a31, uint8_t a32, uint8_t a33, uint8_t a34, uint8_t a35, uint8_t a36, uint8_t a37, uint8_t a38, uint8_t a39, uint8_t a40, uint8_t a41, uint8_t a42, uint8_t a43, uint8_t a44, uint8_t a45, uint8_t a46, uint8_t a47, uint8_t a48, uint8_t a49, uint8_t a50, uint8_t a51, uint8_t a52, uint8_t a53, uint8_t a54, uint8_t a55, uint8_t a56, uint8_t a57, uint8_t a58, uint8_t a59, uint8_t a60, uint8_t a61, uint8_t a62, uint8_t a63) { + return _mm512_set_epi64(uint64_t(a7) + (uint64_t(a6) << 8) + (uint64_t(a5) << 16) + (uint64_t(a4) << 24) + (uint64_t(a3) << 32) + (uint64_t(a2) << 40) + (uint64_t(a1) << 48) + (uint64_t(a0) << 56), + uint64_t(a15) + (uint64_t(a14) << 8) + (uint64_t(a13) << 16) + (uint64_t(a12) << 24) + (uint64_t(a11) << 32) + (uint64_t(a10) << 40) + (uint64_t(a9) << 48) + (uint64_t(a8) << 56), + uint64_t(a23) + (uint64_t(a22) << 8) + (uint64_t(a21) << 16) + (uint64_t(a20) << 24) + (uint64_t(a19) << 32) + (uint64_t(a18) << 40) + (uint64_t(a17) << 48) + (uint64_t(a16) << 56), + uint64_t(a31) + (uint64_t(a30) << 8) + (uint64_t(a29) << 16) + (uint64_t(a28) << 24) + (uint64_t(a27) << 32) + (uint64_t(a26) << 40) + (uint64_t(a25) << 48) + (uint64_t(a24) << 56), + uint64_t(a39) + (uint64_t(a38) << 8) + (uint64_t(a37) << 16) + (uint64_t(a36) << 24) + (uint64_t(a35) << 32) + (uint64_t(a34) << 40) + (uint64_t(a33) << 48) + (uint64_t(a32) << 56), + uint64_t(a47) + (uint64_t(a46) << 8) + (uint64_t(a45) << 16) + (uint64_t(a44) << 24) + (uint64_t(a43) << 32) + (uint64_t(a42) << 40) + (uint64_t(a41) << 48) + (uint64_t(a40) << 56), + uint64_t(a55) + (uint64_t(a54) << 8) + (uint64_t(a53) << 16) + (uint64_t(a52) << 24) + (uint64_t(a51) << 32) + (uint64_t(a50) << 40) + (uint64_t(a49) << 48) + (uint64_t(a48) << 56), + uint64_t(a63) + (uint64_t(a62) << 8) + (uint64_t(a61) << 16) + (uint64_t(a60) << 24) + (uint64_t(a59) << 32) + (uint64_t(a58) << 40) + (uint64_t(a57) << 48) + (uint64_t(a56) << 56)); +} +#endif // SIMDJSON_GCC8 + + + +namespace simdjson { +namespace icelake { +namespace { +namespace simd { + + // Forward-declared so they can be used by splat and friends. + template + struct base { + __m512i value; + + // Zero constructor + simdjson_inline base() : value{__m512i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m512i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m512i&() const { return this->value; } + simdjson_inline operator __m512i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm512_or_si512(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm512_and_si512(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm512_xor_si512(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm512_andnot_si512(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + // Forward-declared so they can be used by splat and friends. + template + struct simd8; + + template> + struct base8: base> { + typedef uint32_t bitmask_t; + typedef uint64_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m512i _value) : base>(_value) {} + + friend simdjson_really_inline uint64_t operator==(const simd8 lhs, const simd8 rhs) { + return _mm512_cmpeq_epi8_mask(lhs, rhs); + } + + static const int SIZE = sizeof(base::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + // workaround for compilers unable to figure out that 16 - N is a constant (GCC 8) + constexpr int shift = 16 - N; + return _mm512_alignr_epi8(*this, _mm512_permutex2var_epi64(prev_chunk, _mm512_set_epi64(13, 12, 11, 10, 9, 8, 7, 6), *this), shift); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm512_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m512i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + simdjson_inline bool any() const { return !!_mm512_test_epi8_mask (*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm512_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm512_setzero_si512(); } + static simdjson_inline simd8 load(const T values[64]) { + return _mm512_loadu_si512(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m512i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[64]) const { return _mm512_storeu_si512(reinterpret_cast<__m512i *>(dst), *this); } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm512_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm512_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm512_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 32 - count_ones(mask) bytes of the result are significant but 32 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint64_t mask, L * output) const { + _mm512_mask_compressstoreu_epi8 (output,~mask,*this); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m512i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t values[64]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15, + int8_t v16, int8_t v17, int8_t v18, int8_t v19, int8_t v20, int8_t v21, int8_t v22, int8_t v23, + int8_t v24, int8_t v25, int8_t v26, int8_t v27, int8_t v28, int8_t v29, int8_t v30, int8_t v31, + int8_t v32, int8_t v33, int8_t v34, int8_t v35, int8_t v36, int8_t v37, int8_t v38, int8_t v39, + int8_t v40, int8_t v41, int8_t v42, int8_t v43, int8_t v44, int8_t v45, int8_t v46, int8_t v47, + int8_t v48, int8_t v49, int8_t v50, int8_t v51, int8_t v52, int8_t v53, int8_t v54, int8_t v55, + int8_t v56, int8_t v57, int8_t v58, int8_t v59, int8_t v60, int8_t v61, int8_t v62, int8_t v63 + ) : simd8(_mm512_set_epi8( + v63, v62, v61, v60, v59, v58, v57, v56, + v55, v54, v53, v52, v51, v50, v49, v48, + v47, v46, v45, v44, v43, v42, v41, v40, + v39, v38, v37, v36, v35, v34, v33, v32, + v31, v30, v29, v28, v27, v26, v25, v24, + v23, v22, v21, v20, v19, v18, v17, v16, + v15, v14, v13, v12, v11, v10, v9, v8, + v7, v6, v5, v4, v3, v2, v1, v0 + )) {} + + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm512_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm512_min_epi8(*this, other); } + + simdjson_inline simd8 operator>(const simd8 other) const { return _mm512_maskz_abs_epi8(_mm512_cmpgt_epi8_mask(*this, other),_mm512_set1_epi8(uint8_t(0x80))); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm512_maskz_abs_epi8(_mm512_cmpgt_epi8_mask(other, *this),_mm512_set1_epi8(uint8_t(0x80))); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m512i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t values[64]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15, + uint8_t v16, uint8_t v17, uint8_t v18, uint8_t v19, uint8_t v20, uint8_t v21, uint8_t v22, uint8_t v23, + uint8_t v24, uint8_t v25, uint8_t v26, uint8_t v27, uint8_t v28, uint8_t v29, uint8_t v30, uint8_t v31, + uint8_t v32, uint8_t v33, uint8_t v34, uint8_t v35, uint8_t v36, uint8_t v37, uint8_t v38, uint8_t v39, + uint8_t v40, uint8_t v41, uint8_t v42, uint8_t v43, uint8_t v44, uint8_t v45, uint8_t v46, uint8_t v47, + uint8_t v48, uint8_t v49, uint8_t v50, uint8_t v51, uint8_t v52, uint8_t v53, uint8_t v54, uint8_t v55, + uint8_t v56, uint8_t v57, uint8_t v58, uint8_t v59, uint8_t v60, uint8_t v61, uint8_t v62, uint8_t v63 + ) : simd8(_mm512_set_epi8( + v63, v62, v61, v60, v59, v58, v57, v56, + v55, v54, v53, v52, v51, v50, v49, v48, + v47, v46, v45, v44, v43, v42, v41, v40, + v39, v38, v37, v36, v35, v34, v33, v32, + v31, v30, v29, v28, v27, v26, v25, v24, + v23, v22, v21, v20, v19, v18, v17, v16, + v15, v14, v13, v12, v11, v10, v9, v8, + v7, v6, v5, v4, v3, v2, v1, v0 + )) {} + + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm512_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm512_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm512_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm512_min_epu8(other, *this); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline uint64_t operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline uint64_t operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->lt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return _mm512_mask_blend_epi8(*this == uint8_t(0), _mm512_set1_epi8(0), _mm512_set1_epi8(-1)); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + + simdjson_inline bool is_ascii() const { return _mm512_movepi8_mask(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { + return !_mm512_test_epi8_mask(*this, *this); + } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return !_mm512_test_epi8_mask(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm512_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm512_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline uint64_t get_bit() const { return _mm512_movepi8_mask(_mm512_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 1, "Icelake kernel should use one register per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1) : chunks{chunk0, chunk1} {} + simdjson_inline simd8x64(const simd8 chunk0) : chunks{chunk0} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr)} {} + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + this->chunks[0].compress(mask, output); + return 64 - count_ones(mask); + } + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + } + + simdjson_inline simd8 reduce_or() const { + return this->chunks[0]; + } + + simdjson_inline simd8x64 bit_or(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] | mask + ); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return this->chunks[0] == mask; + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return this->chunks[0] == other.chunks[0]; + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return this->chunks[0] <= mask; + } + }; // struct simd8x64 + +} // namespace simd + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_SIMD_H +/* end file simdjson/icelake/simd.h */ +/* including simdjson/icelake/stringparsing_defs.h: #include "simdjson/icelake/stringparsing_defs.h" */ +/* begin file simdjson/icelake/stringparsing_defs.h */ +#ifndef SIMDJSON_ICELAKE_STRINGPARSING_DEFS_H +#define SIMDJSON_ICELAKE_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/simd.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 64; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return ((quote_bits - 1) & bs_bits) != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint64_t bs_bits; + uint64_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 15 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v(src); + // store to dest unconditionally - we can overwrite the bits we don't like later + v.store(dst); + return { + static_cast(v == '\\'), // bs_bits + static_cast(v == '"'), // quote_bits + }; +} + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_STRINGPARSING_DEFS_H +/* end file simdjson/icelake/stringparsing_defs.h */ +/* including simdjson/icelake/numberparsing_defs.h: #include "simdjson/icelake/numberparsing_defs.h" */ +/* begin file simdjson/icelake/numberparsing_defs.h */ +#ifndef SIMDJSON_ICELAKE_NUMBERPARSING_DEFS_H +#define SIMDJSON_ICELAKE_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace numberparsing { + +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + // this actually computes *16* values so we are being wasteful. + const __m128i ascii0 = _mm_set1_epi8('0'); + const __m128i mul_1_10 = + _mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1); + const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1); + const __m128i mul_1_10000 = + _mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1); + const __m128i input = _mm_sub_epi8( + _mm_loadu_si128(reinterpret_cast(chars)), ascii0); + const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10); + const __m128i t2 = _mm_madd_epi16(t1, mul_1_100); + const __m128i t3 = _mm_packus_epi32(t2, t2); + const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000); + return _mm_cvtsi128_si32( + t4); // only captures the sum of the first 8 digits, drop the rest +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace icelake +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_ICELAKE_NUMBERPARSING_DEFS_H +/* end file simdjson/icelake/numberparsing_defs.h */ +/* end file simdjson/icelake/begin.h */ +/* including simdjson/generic/amalgamated.h for icelake: #include "simdjson/generic/amalgamated.h" */ +/* begin file simdjson/generic/amalgamated.h for icelake */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_DEPENDENCIES_H) +#error simdjson/generic/dependencies.h must be included before simdjson/generic/amalgamated.h! +#endif + +/* including simdjson/generic/base.h for icelake: #include "simdjson/generic/base.h" */ +/* begin file simdjson/generic/base.h for icelake */ +#ifndef SIMDJSON_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): // If we haven't got an implementation yet, we're in the editor, editing a generic file! Just */ +/* amalgamation skipped (editor-only): // use the most advanced one we can so the most possible stuff can be tested. */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation_detection.h" */ +/* amalgamation skipped (editor-only): #if SIMDJSON_IMPLEMENTATION_ICELAKE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_HASWELL */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_WESTMERE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_ARM64 */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_PPC64 */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_FALLBACK */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/begin.h" */ +/* amalgamation skipped (editor-only): #else */ +/* amalgamation skipped (editor-only): #error "All possible implementations (including fallback) have been disabled! simdjson will not run." */ +/* amalgamation skipped (editor-only): #endif */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { + +struct open_container; +class dom_parser_implementation; + +/** + * The type of a JSON number + */ +enum class number_type { + floating_point_number=1, /// a binary64 number + signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + unsigned_integer /// a positive integer larger or equal to 1<<63 +}; + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_BASE_H +/* end file simdjson/generic/base.h for icelake */ +/* including simdjson/generic/jsoncharutils.h for icelake: #include "simdjson/generic/jsoncharutils.h" */ +/* begin file simdjson/generic/jsoncharutils.h for icelake */ +#ifndef SIMDJSON_GENERIC_JSONCHARUTILS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_JSONCHARUTILS_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/jsoncharutils_tables.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { +namespace jsoncharutils { + +// return non-zero if not a structural or whitespace char +// zero otherwise +simdjson_inline uint32_t is_not_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace_negated[c]; +} + +simdjson_inline uint32_t is_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace[c]; +} + +// returns a value with the high 16 bits set if not valid +// otherwise returns the conversion of the 4 hex digits at src into the bottom +// 16 bits of the 32-bit return register +// +// see +// https://lemire.me/blog/2019/04/17/parsing-short-hexadecimal-strings-efficiently/ +static inline uint32_t hex_to_u32_nocheck( + const uint8_t *src) { // strictly speaking, static inline is a C-ism + uint32_t v1 = internal::digit_to_val32[630 + src[0]]; + uint32_t v2 = internal::digit_to_val32[420 + src[1]]; + uint32_t v3 = internal::digit_to_val32[210 + src[2]]; + uint32_t v4 = internal::digit_to_val32[0 + src[3]]; + return v1 | v2 | v3 | v4; +} + +// given a code point cp, writes to c +// the utf-8 code, outputting the length in +// bytes, if the length is zero, the code point +// is invalid +// +// This can possibly be made faster using pdep +// and clz and table lookups, but JSON documents +// have few escaped code points, and the following +// function looks cheap. +// +// Note: we assume that surrogates are treated separately +// +simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) { + if (cp <= 0x7F) { + c[0] = uint8_t(cp); + return 1; // ascii + } + if (cp <= 0x7FF) { + c[0] = uint8_t((cp >> 6) + 192); + c[1] = uint8_t((cp & 63) + 128); + return 2; // universal plane + // Surrogates are treated elsewhere... + //} //else if (0xd800 <= cp && cp <= 0xdfff) { + // return 0; // surrogates // could put assert here + } else if (cp <= 0xFFFF) { + c[0] = uint8_t((cp >> 12) + 224); + c[1] = uint8_t(((cp >> 6) & 63) + 128); + c[2] = uint8_t((cp & 63) + 128); + return 3; + } else if (cp <= 0x10FFFF) { // if you know you have a valid code point, this + // is not needed + c[0] = uint8_t((cp >> 18) + 240); + c[1] = uint8_t(((cp >> 12) & 63) + 128); + c[2] = uint8_t(((cp >> 6) & 63) + 128); + c[3] = uint8_t((cp & 63) + 128); + return 4; + } + // will return 0 when the code point was too large. + return 0; // bad r +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +} // namespace jsoncharutils +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_JSONCHARUTILS_H +/* end file simdjson/generic/jsoncharutils.h for icelake */ +/* including simdjson/generic/atomparsing.h for icelake: #include "simdjson/generic/atomparsing.h" */ +/* begin file simdjson/generic/atomparsing.h for icelake */ +#ifndef SIMDJSON_GENERIC_ATOMPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ATOMPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace icelake { +namespace { +/// @private +namespace atomparsing { + +// The string_to_uint32 is exclusively used to map literal strings to 32-bit values. +// We use memcpy instead of a pointer cast to avoid undefined behaviors since we cannot +// be certain that the character pointer will be properly aligned. +// You might think that using memcpy makes this function expensive, but you'd be wrong. +// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false"); +// to the compile-time constant 1936482662. +simdjson_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; } + + +// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive. +// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about. +simdjson_warn_unused +simdjson_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) { + uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++) + static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes"); + std::memcpy(&srcval, src, sizeof(uint32_t)); + return srcval ^ string_to_uint32(atom); +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src) { + return (str4ncmp(src, "true") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_true_atom(src); } + else if (len == 4) { return !str4ncmp(src, "true"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src) { + return (str4ncmp(src+1, "alse") | jsoncharutils::is_not_structural_or_whitespace(src[5])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src, size_t len) { + if (len > 5) { return is_valid_false_atom(src); } + else if (len == 5) { return !str4ncmp(src+1, "alse"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src) { + return (str4ncmp(src, "null") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_null_atom(src); } + else if (len == 4) { return !str4ncmp(src, "null"); } + else { return false; } +} + +} // namespace atomparsing +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ATOMPARSING_H +/* end file simdjson/generic/atomparsing.h for icelake */ +/* including simdjson/generic/dom_parser_implementation.h for icelake: #include "simdjson/generic/dom_parser_implementation.h" */ +/* begin file simdjson/generic/dom_parser_implementation.h for icelake */ +#ifndef SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { + +// expectation: sizeof(open_container) = 64/8. +struct open_container { + uint32_t tape_index; // where, on the tape, does the scope ([,{) begins + uint32_t count; // how many elements in the scope +}; // struct open_container + +static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits"); + +class dom_parser_implementation final : public internal::dom_parser_implementation { +public: + /** Tape location of each open { or [ */ + std::unique_ptr open_containers{}; + /** Whether each open container is a [ or { */ + std::unique_ptr is_array{}; + /** Buffer passed to stage 1 */ + const uint8_t *buf{}; + /** Length passed to stage 1 */ + size_t len{0}; + /** Document passed to stage 2 */ + dom::document *doc{}; + + inline dom_parser_implementation() noexcept; + inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; + inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; + dom_parser_implementation(const dom_parser_implementation &) = delete; + dom_parser_implementation &operator=(const dom_parser_implementation &) = delete; + + simdjson_warn_unused error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage1(const uint8_t *buf, size_t len, stage1_mode partial) noexcept final; + simdjson_warn_unused error_code stage2(dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage2_next(dom::document &doc) noexcept final; + simdjson_warn_unused uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept final; + simdjson_warn_unused uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept final; + inline simdjson_warn_unused error_code set_capacity(size_t capacity) noexcept final; + inline simdjson_warn_unused error_code set_max_depth(size_t max_depth) noexcept final; +private: + simdjson_inline simdjson_warn_unused error_code set_capacity_stage1(size_t capacity); + +}; + +} // namespace icelake +} // namespace simdjson + +namespace simdjson { +namespace icelake { + +inline dom_parser_implementation::dom_parser_implementation() noexcept = default; +inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; +inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; + +// Leaving these here so they can be inlined if so desired +inline simdjson_warn_unused error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept { + if(capacity > SIMDJSON_MAXSIZE_BYTES) { return CAPACITY; } + // Stage 1 index output + size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7; + structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] ); + if (!structural_indexes) { _capacity = 0; return MEMALLOC; } + structural_indexes[0] = 0; + n_structural_indexes = 0; + + _capacity = capacity; + return SUCCESS; +} + +inline simdjson_warn_unused error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept { + // Stage 2 stacks + open_containers.reset(new (std::nothrow) open_container[max_depth]); + is_array.reset(new (std::nothrow) bool[max_depth]); + if (!is_array || !open_containers) { _max_depth = 0; return MEMALLOC; } + + _max_depth = max_depth; + return SUCCESS; +} + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file simdjson/generic/dom_parser_implementation.h for icelake */ +/* including simdjson/generic/implementation_simdjson_result_base.h for icelake: #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base.h for icelake */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { + +// This is a near copy of include/error.h's implementation_simdjson_result_base, except it doesn't use std::pair +// so we can avoid inlining errors +// TODO reconcile these! +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + * + * This is a base class for implementations that want to add functions to the result type for + * chaining. + * + * Override like: + * + * struct simdjson_result : public internal::implementation_simdjson_result_base { + * simdjson_result() noexcept : internal::implementation_simdjson_result_base() {} + * simdjson_result(error_code error) noexcept : internal::implementation_simdjson_result_base(error) {} + * simdjson_result(T &&value) noexcept : internal::implementation_simdjson_result_base(std::forward(value)) {} + * simdjson_result(T &&value, error_code error) noexcept : internal::implementation_simdjson_result_base(value, error) {} + * // Your extra methods here + * } + * + * Then any method returning simdjson_result will be chainable with your methods. + */ +template +struct implementation_simdjson_result_base { + + /** + * Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline implementation_simdjson_result_base() noexcept = default; + + /** + * Create a new error result. + */ + simdjson_inline implementation_simdjson_result_base(error_code error) noexcept; + + /** + * Create a new successful result. + */ + simdjson_inline implementation_simdjson_result_base(T &&value) noexcept; + + /** + * Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline implementation_simdjson_result_base(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); + + +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T& value_unsafe() & noexcept; + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; +protected: + /** users should never directly access first and second. **/ + T first{}; /** Users should never directly access 'first'. **/ + error_code second{UNINITIALIZED}; /** Users should never directly access 'second'. **/ +}; // struct implementation_simdjson_result_base + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H +/* end file simdjson/generic/implementation_simdjson_result_base.h for icelake */ +/* including simdjson/generic/numberparsing.h for icelake: #include "simdjson/generic/numberparsing.h" */ +/* begin file simdjson/generic/numberparsing.h for icelake */ +#ifndef SIMDJSON_GENERIC_NUMBERPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_NUMBERPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include +#include + +namespace simdjson { +namespace icelake { +namespace numberparsing { + +#ifdef JSON_TEST_NUMBERS +#define INVALID_NUMBER(SRC) (found_invalid_number((SRC)), NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (found_integer((VALUE), (SRC)), (WRITER).append_s64((VALUE))) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (found_unsigned_integer((VALUE), (SRC)), (WRITER).append_u64((VALUE))) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (found_float((VALUE), (SRC)), (WRITER).append_double((VALUE))) +#else +#define INVALID_NUMBER(SRC) (NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (WRITER).append_s64((VALUE)) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (WRITER).append_u64((VALUE)) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (WRITER).append_double((VALUE)) +#endif + +namespace { + +// Convert a mantissa, an exponent and a sign bit into an ieee64 double. +// The real_exponent needs to be in [0, 2046] (technically real_exponent = 2047 would be acceptable). +// The mantissa should be in [0,1<<53). The bit at index (1ULL << 52) while be zeroed. +simdjson_inline double to_double(uint64_t mantissa, uint64_t real_exponent, bool negative) { + double d; + mantissa &= ~(1ULL << 52); + mantissa |= real_exponent << 52; + mantissa |= ((static_cast(negative)) << 63); + std::memcpy(&d, &mantissa, sizeof(d)); + return d; +} + +// Attempts to compute i * 10^(power) exactly; and if "negative" is +// true, negate the result. +// This function will only work in some cases, when it does not work, success is +// set to false. This should work *most of the time* (like 99% of the time). +// We assume that power is in the [smallest_power, +// largest_power] interval: the caller is responsible for this check. +simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative, double &d) { + // we start with a fast path + // It was described in + // Clinger WD. How to read floating point numbers accurately. + // ACM SIGPLAN Notices. 1990 +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + // We cannot be certain that x/y is rounded to nearest. + if (0 <= power && power <= 22 && i <= 9007199254740991) +#else + if (-22 <= power && power <= 22 && i <= 9007199254740991) +#endif + { + // convert the integer into a double. This is lossless since + // 0 <= i <= 2^53 - 1. + d = double(i); + // + // The general idea is as follows. + // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then + // 1) Both s and p can be represented exactly as 64-bit floating-point + // values + // (binary64). + // 2) Because s and p can be represented exactly as floating-point values, + // then s * p + // and s / p will produce correctly rounded values. + // + if (power < 0) { + d = d / simdjson::internal::power_of_ten[-power]; + } else { + d = d * simdjson::internal::power_of_ten[power]; + } + if (negative) { + d = -d; + } + return true; + } + // When 22 < power && power < 22 + 16, we could + // hope for another, secondary fast path. It was + // described by David M. Gay in "Correctly rounded + // binary-decimal and decimal-binary conversions." (1990) + // If you need to compute i * 10^(22 + x) for x < 16, + // first compute i * 10^x, if you know that result is exact + // (e.g., when i * 10^x < 2^53), + // then you can still proceed and do (i * 10^x) * 10^22. + // Is this worth your time? + // You need 22 < power *and* power < 22 + 16 *and* (i * 10^(x-22) < 2^53) + // for this second fast path to work. + // If you you have 22 < power *and* power < 22 + 16, and then you + // optimistically compute "i * 10^(x-22)", there is still a chance that you + // have wasted your time if i * 10^(x-22) >= 2^53. It makes the use cases of + // this optimization maybe less common than we would like. Source: + // http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + // also used in RapidJSON: https://rapidjson.org/strtod_8h_source.html + + // The fast path has now failed, so we are failing back on the slower path. + + // In the slow path, we need to adjust i so that it is > 1<<63 which is always + // possible, except if i == 0, so we handle i == 0 separately. + if(i == 0) { + d = negative ? -0.0 : 0.0; + return true; + } + + + // The exponent is 1024 + 63 + power + // + floor(log(5**power)/log(2)). + // The 1024 comes from the ieee64 standard. + // The 63 comes from the fact that we use a 64-bit word. + // + // Computing floor(log(5**power)/log(2)) could be + // slow. Instead we use a fast function. + // + // For power in (-400,350), we have that + // (((152170 + 65536) * power ) >> 16); + // is equal to + // floor(log(5**power)/log(2)) + power when power >= 0 + // and it is equal to + // ceil(log(5**-power)/log(2)) + power when power < 0 + // + // The 65536 is (1<<16) and corresponds to + // (65536 * power) >> 16 ---> power + // + // ((152170 * power ) >> 16) is equal to + // floor(log(5**power)/log(2)) + // + // Note that this is not magic: 152170/(1<<16) is + // approximatively equal to log(5)/log(2). + // The 1<<16 value is a power of two; we could use a + // larger power of 2 if we wanted to. + // + int64_t exponent = (((152170 + 65536) * power) >> 16) + 1024 + 63; + + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(i); + i <<= lz; + + + // We are going to need to do some 64-bit arithmetic to get a precise product. + // We use a table lookup approach. + // It is safe because + // power >= smallest_power + // and power <= largest_power + // We recover the mantissa of the power, it has a leading 1. It is always + // rounded down. + // + // We want the most significant 64 bits of the product. We know + // this will be non-zero because the most significant bit of i is + // 1. + const uint32_t index = 2 * uint32_t(power - simdjson::internal::smallest_power); + // Optimization: It may be that materializing the index as a variable might confuse some compilers and prevent effective complex-addressing loads. (Done for code clarity.) + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); + // Both i and power_of_five_128[index] have their most significant bit set to 1 which + // implies that the either the most or the second most significant bit of the product + // is 1. We pack values in this manner for efficiency reasons: it maximizes the use + // we make of the product. It also makes it easy to reason about the product: there + // is 0 or 1 leading zero in the product. + + // Unless the least significant 9 bits of the high (64-bit) part of the full + // product are all 1s, then we know that the most significant 55 bits are + // exact and no further work is needed. Having 55 bits is necessary because + // we need 53 bits for the mantissa but we have to have one rounding bit and + // we can waste a bit if the most significant bit of the product is zero. + if((firstproduct.high & 0x1FF) == 0x1FF) { + // We want to compute i * 5^q, but only care about the top 55 bits at most. + // Consider the scenario where q>=0. Then 5^q may not fit in 64-bits. Doing + // the full computation is wasteful. So we do what is called a "truncated + // multiplication". + // We take the most significant 64-bits, and we put them in + // power_of_five_128[index]. Usually, that's good enough to approximate i * 5^q + // to the desired approximation using one multiplication. Sometimes it does not suffice. + // Then we store the next most significant 64 bits in power_of_five_128[index + 1], and + // then we get a better approximation to i * 5^q. + // + // That's for when q>=0. The logic for q<0 is somewhat similar but it is somewhat + // more complicated. + // + // There is an extra layer of complexity in that we need more than 55 bits of + // accuracy in the round-to-even scenario. + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if(secondproduct.high > firstproduct.low) { firstproduct.high++; } + // As it has been proven by Noble Mushtak and Daniel Lemire in "Fast Number Parsing Without + // Fallback" (https://arxiv.org/abs/2212.06644), at this point we are sure that the product + // is sufficiently accurate, and more computation is not needed. + } + uint64_t lower = firstproduct.low; + uint64_t upper = firstproduct.high; + // The final mantissa should be 53 bits with a leading 1. + // We shift it so that it occupies 54 bits with a leading 1. + /////// + uint64_t upperbit = upper >> 63; + uint64_t mantissa = upper >> (upperbit + 9); + lz += int(1 ^ upperbit); + + // Here we have mantissa < (1<<54). + int64_t real_exponent = exponent - lz; + if (simdjson_unlikely(real_exponent <= 0)) { // we have a subnormal? + // Here have that real_exponent <= 0 so -real_exponent >= 0 + if(-real_exponent + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure. + d = negative ? -0.0 : 0.0; + return true; + } + // next line is safe because -real_exponent + 1 < 0 + mantissa >>= -real_exponent + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0. + mantissa += (mantissa & 1); // round up + mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + real_exponent = (mantissa < (uint64_t(1) << 52)) ? 0 : 1; + d = to_double(mantissa, real_exponent, negative); + return true; + } + // We have to round to even. The "to even" part + // is only a problem when we are right in between two floats + // which we guard against. + // If we have lots of trailing zeros, we may fall right between two + // floating-point values. + // + // The round-to-even cases take the form of a number 2m+1 which is in (2^53,2^54] + // times a power of two. That is, it is right between a number with binary significand + // m and another number with binary significand m+1; and it must be the case + // that it cannot be represented by a float itself. + // + // We must have that w * 10 ^q == (2m+1) * 2^p for some power of two 2^p. + // Recall that 10^q = 5^q * 2^q. + // When q >= 0, we must have that (2m+1) is divible by 5^q, so 5^q <= 2^54. We have that + // 5^23 <= 2^54 and it is the last power of five to qualify, so q <= 23. + // When q<0, we have w >= (2m+1) x 5^{-q}. We must have that w<2^{64} so + // (2m+1) x 5^{-q} < 2^{64}. We have that 2m+1>2^{53}. Hence, we must have + // 2^{53} x 5^{-q} < 2^{64}. + // Hence we have 5^{-q} < 2^{11}$ or q>= -4. + // + // We require lower <= 1 and not lower == 0 because we could not prove that + // that lower == 0 is implied; but we could prove that lower <= 1 is a necessary and sufficient test. + if (simdjson_unlikely((lower <= 1) && (power >= -4) && (power <= 23) && ((mantissa & 3) == 1))) { + if((mantissa << (upperbit + 64 - 53 - 2)) == upper) { + mantissa &= ~1; // flip it so that we do not round up + } + } + + mantissa += mantissa & 1; + mantissa >>= 1; + + // Here we have mantissa < (1<<53), unless there was an overflow + if (mantissa >= (1ULL << 53)) { + ////////// + // This will happen when parsing values such as 7.2057594037927933e+16 + //////// + mantissa = (1ULL << 52); + real_exponent++; + } + mantissa &= ~(1ULL << 52); + // we have to check that real_exponent is in range, otherwise we bail out + if (simdjson_unlikely(real_exponent > 2046)) { + // We have an infinite value!!! We could actually throw an error here if we could. + return false; + } + d = to_double(mantissa, real_exponent, negative); + return true; +} + +// We call a fallback floating-point parser that might be slow. Note +// it will accept JSON numbers, but the JSON spec. is more restrictive so +// before you call parse_float_fallback, you need to have validated the input +// string with the JSON grammar. +// It will return an error (false) if the parsed number is infinite. +// The string parsing itself always succeeds. We know that there is at least +// one digit. +static bool parse_float_fallback(const uint8_t *ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +static bool parse_float_fallback(const uint8_t *ptr, const uint8_t *end_ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr), reinterpret_cast(end_ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +// check quickly whether the next 8 chars are made of digits +// at a glance, it looks better than Mula's +// http://0x80.pl/articles/swar-digits-validate.html +simdjson_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) { + uint64_t val; + // this can read up to 7 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(7 <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be bigger than 7"); + std::memcpy(&val, chars, 8); + // a branchy method might be faster: + // return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030) + // && (( (val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0 ) == + // 0x3030303030303030); + return (((val & 0xF0F0F0F0F0F0F0F0) | + (((val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4)) == + 0x3333333333333333); +} + +template +SIMDJSON_NO_SANITIZE_UNDEFINED // We deliberately allow overflow here and check later +simdjson_inline bool parse_digit(const uint8_t c, I &i) { + const uint8_t digit = static_cast(c - '0'); + if (digit > 9) { + return false; + } + // PERF NOTE: multiplication by 10 is cheaper than arbitrary integer multiplication + i = 10 * i + digit; // might overflow, we will handle the overflow later + return true; +} + +simdjson_inline error_code parse_decimal_after_separator(simdjson_unused const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) { + // we continue with the fiction that we have an integer. If the + // floating point number is representable as x * 10^z for some integer + // z that fits in 53 bits, then we will be able to convert back the + // the integer into a float in a lossless manner. + const uint8_t *const first_after_period = p; + +#ifdef SIMDJSON_SWAR_NUMBER_PARSING +#if SIMDJSON_SWAR_NUMBER_PARSING + // this helps if we have lots of decimals! + // this turns out to be frequent enough. + if (is_made_of_eight_digits_fast(p)) { + i = i * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + } +#endif // SIMDJSON_SWAR_NUMBER_PARSING +#endif // #ifdef SIMDJSON_SWAR_NUMBER_PARSING + // Unrolling the first digit makes a small difference on some implementations (e.g. westmere) + if (parse_digit(*p, i)) { ++p; } + while (parse_digit(*p, i)) { p++; } + exponent = first_after_period - p; + // Decimal without digits (123.) is illegal + if (exponent == 0) { + return INVALID_NUMBER(src); + } + return SUCCESS; +} + +simdjson_inline error_code parse_exponent(simdjson_unused const uint8_t *const src, const uint8_t *&p, int64_t &exponent) { + // Exp Sign: -123.456e[-]78 + bool neg_exp = ('-' == *p); + if (neg_exp || '+' == *p) { p++; } // Skip + as well + + // Exponent: -123.456e-[78] + auto start_exp = p; + int64_t exp_number = 0; + while (parse_digit(*p, exp_number)) { ++p; } + // It is possible for parse_digit to overflow. + // In particular, it could overflow to INT64_MIN, and we cannot do - INT64_MIN. + // Thus we *must* check for possible overflow before we negate exp_number. + + // Performance notes: it may seem like combining the two "simdjson_unlikely checks" below into + // a single simdjson_unlikely path would be faster. The reasoning is sound, but the compiler may + // not oblige and may, in fact, generate two distinct paths in any case. It might be + // possible to do uint64_t(p - start_exp - 1) >= 18 but it could end up trading off + // instructions for a simdjson_likely branch, an unconclusive gain. + + // If there were no digits, it's an error. + if (simdjson_unlikely(p == start_exp)) { + return INVALID_NUMBER(src); + } + // We have a valid positive exponent in exp_number at this point, except that + // it may have overflowed. + + // If there were more than 18 digits, we may have overflowed the integer. We have to do + // something!!!! + if (simdjson_unlikely(p > start_exp+18)) { + // Skip leading zeroes: 1e000000000000000000001 is technically valid and doesn't overflow + while (*start_exp == '0') { start_exp++; } + // 19 digits could overflow int64_t and is kind of absurd anyway. We don't + // support exponents smaller than -999,999,999,999,999,999 and bigger + // than 999,999,999,999,999,999. + // We can truncate. + // Note that 999999999999999999 is assuredly too large. The maximal ieee64 value before + // infinity is ~1.8e308. The smallest subnormal is ~5e-324. So, actually, we could + // truncate at 324. + // Note that there is no reason to fail per se at this point in time. + // E.g., 0e999999999999999999999 is a fine number. + if (p > start_exp+18) { exp_number = 999999999999999999; } + } + // At this point, we know that exp_number is a sane, positive, signed integer. + // It is <= 999,999,999,999,999,999. As long as 'exponent' is in + // [-8223372036854775808, 8223372036854775808], we won't overflow. Because 'exponent' + // is bounded in magnitude by the size of the JSON input, we are fine in this universe. + // To sum it up: the next line should never overflow. + exponent += (neg_exp ? -exp_number : exp_number); + return SUCCESS; +} + +simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t digit_count) { + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + const uint8_t *start = start_digits; + while ((*start == '0') || (*start == '.')) { ++start; } + // we over-decrement by one when there is a '.' + return digit_count - size_t(start - start_digits); +} + +} // unnamed namespace + +/** @private */ +static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) { + if (parse_float_fallback(src, answer)) { + return SUCCESS; + } + return INVALID_NUMBER(src); +} + +/** @private */ +template +simdjson_inline error_code write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer) { + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon in practice. + // + // 9999999999999999999 < 2**64 so we can accommodate 19 digits. + // If we have a decimal separator, then digit_count - 1 is the number of digits, but we + // may not have a decimal separator! + if (simdjson_unlikely(digit_count > 19 && significant_digits(start_digits, digit_count) > 19)) { + // Ok, chances are good that we had an overflow! + // this is almost never going to get called!!! + // we start anew, going slowly!!! + // This will happen in the following examples: + // 10000000000000000000000000000000000000000000e+308 + // 3.1415926535897932384626433832795028841971693993751 + // + // NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer + // reference to it, it would force it to be stored in memory, preventing the compiler from + // picking it apart and putting into registers. i.e. if we pass it as reference, + // it gets slow. + double d; + error_code error = slow_float_parsing(src, &d); + writer.append_double(d); + return error; + } + // NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other + // way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331 + // To future reader: we'd love if someone found a better way, or at least could explain this result! + if (simdjson_unlikely(exponent < simdjson::internal::smallest_power) || (exponent > simdjson::internal::largest_power)) { + // + // Important: smallest_power is such that it leads to a zero value. + // Observe that 18446744073709551615e-343 == 0, i.e. (2**64 - 1) e -343 is zero + // so something x 10^-343 goes to zero, but not so with something x 10^-342. + static_assert(simdjson::internal::smallest_power <= -342, "smallest_power is not small enough"); + // + if((exponent < simdjson::internal::smallest_power) || (i == 0)) { + // E.g. Parse "-0.0e-999" into the same value as "-0.0". See https://en.wikipedia.org/wiki/Signed_zero + WRITE_DOUBLE(negative ? -0.0 : 0.0, src, writer); + return SUCCESS; + } else { // (exponent > largest_power) and (i != 0) + // We have, for sure, an infinite value and simdjson refuses to parse infinite values. + return INVALID_NUMBER(src); + } + } + double d; + if (!compute_float_64(exponent, i, negative, d)) { + // we are almost never going to get here. + if (!parse_float_fallback(src, &d)) { return INVALID_NUMBER(src); } + } + WRITE_DOUBLE(d, src, writer); + return SUCCESS; +} + +// for performance analysis, it is sometimes useful to skip parsing +#ifdef SIMDJSON_SKIPNUMBERPARSING + +template +simdjson_inline error_code parse_number(const uint8_t *const, W &writer) { + writer.append_s64(0); // always write zero + return SUCCESS; // always succeeds +} + +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { return number_type::signed_integer; } +#else + +// parse the number at src +// define JSON_TEST_NUMBERS for unit testing +// +// It is assumed that the number is followed by a structural ({,},],[) character +// or a white space character. If that is not the case (e.g., when the JSON +// document is made of a single number), then it is necessary to copy the +// content and append a space before calling this function. +// +// Our objective is accurate parsing (ULP of 0) at high speed. +template +simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) { + + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + if (digit_count == 0 || ('0' == *start_digits && digit_count > 1)) { return INVALID_NUMBER(src); } + + // + // Handle floats if there is a . or e (or both) + // + int64_t exponent = 0; + bool is_float = false; + if ('.' == *p) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) ); + digit_count = int(p - start_digits); // used later to guard against overflows + } + if (('e' == *p) || ('E' == *p)) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_exponent(src, p, exponent) ); + } + if (is_float) { + const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p); + SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) ); + if (dirty_end) { return INVALID_NUMBER(src); } + return SUCCESS; + } + + // The longest negative 64-bit number is 19 digits. + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + size_t longest_digit_count = negative ? 19 : 20; + if (digit_count > longest_digit_count) { return INVALID_NUMBER(src); } + if (digit_count == longest_digit_count) { + if (negative) { + // Anything negative above INT64_MAX+1 is invalid + if (i > uint64_t(INT64_MAX)+1) { return INVALID_NUMBER(src); } + WRITE_INTEGER(~i+1, src, writer); + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + } else if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INVALID_NUMBER(src); } + } + + // Write unsigned if it doesn't fit in a signed integer. + if (i > uint64_t(INT64_MAX)) { + WRITE_UNSIGNED(i, src, writer); + } else { + WRITE_INTEGER(negative ? (~i+1) : i, src, writer); + } + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; +} + +// Inlineable functions +namespace { + +// This table can be used to characterize the final character of an integer +// string. For JSON structural character and allowable white space characters, +// we return SUCCESS. For 'e', '.' and 'E', we return INCORRECT_TYPE. Otherwise +// we return NUMBER_ERROR. +// Optimization note: we could easily reduce the size of the table by half (to 128) +// at the cost of an extra branch. +// Optimization note: we want the values to use at most 8 bits (not, e.g., 32 bits): +static_assert(error_code(uint8_t(NUMBER_ERROR))== NUMBER_ERROR, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(SUCCESS))== SUCCESS, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(INCORRECT_TYPE))== INCORRECT_TYPE, "bad NUMBER_ERROR cast"); + +const uint8_t integer_string_finisher[256] = { + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, INCORRECT_TYPE, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, SUCCESS, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR}; + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + + +// Parse any number from 0 to 18,446,744,073,709,551,615 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src, const uint8_t * const src_end) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if ((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { + const uint8_t *p = src + 1; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (*p != '"') { return NUMBER_ERROR; } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + // Note: we use src[1] and not src[0] because src[0] is the quote character in this + // instance. + if (src[1] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src, const uint8_t * const src_end) noexcept { + // + // Check for minus sign + // + if(src == src_end) { return NUMBER_ERROR; } + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = src; + uint64_t i = 0; + while (parse_digit(*src, i)) { src++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(src - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*src)) { + // return (*src == '.' || *src == 'e' || *src == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(*src != '"') { return NUMBER_ERROR; } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { + return (*src == '-'); +} + +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { return true; } + return false; +} + +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { + // We have an integer. + // If the number is negative and valid, it must be a signed integer. + if(negative) { return number_type::signed_integer; } + // We want values larger or equal to 9223372036854775808 to be unsigned + // integers, and the other values to be signed integers. + int digit_count = int(p - src); + if(digit_count >= 19) { + const uint8_t * smaller_big_integer = reinterpret_cast("9223372036854775808"); + if((digit_count >= 20) || (memcmp(src, smaller_big_integer, 19) >= 0)) { + return number_type::unsigned_integer; + } + } + return number_type::signed_integer; + } + // Hopefully, we have 'e' or 'E' or '.'. + return number_type::floating_point_number; +} + +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src, const uint8_t * const src_end) noexcept { + if(src == src_end) { return NUMBER_ERROR; } + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + if(p == src_end) { return NUMBER_ERROR; } + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while ((p != src_end) && parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely((p != src_end) && (*p == '.'))) { + p++; + const uint8_t *start_decimal_digits = p; + if ((p == src_end) || !parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = start_digits-src > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if ((p != src_end) && (*p == 'e' || *p == 'E')) { + p++; + if(p == src_end) { return NUMBER_ERROR; } + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while ((p != src_end) && parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (*p != '"') { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +} // unnamed namespace +#endif // SIMDJSON_SKIPNUMBERPARSING + +} // namespace numberparsing + +inline std::ostream& operator<<(std::ostream& out, number_type type) noexcept { + switch (type) { + case number_type::signed_integer: out << "integer in [-9223372036854775808,9223372036854775808)"; break; + case number_type::unsigned_integer: out << "unsigned integer in [9223372036854775808,18446744073709551616)"; break; + case number_type::floating_point_number: out << "floating-point number (binary64)"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_NUMBERPARSING_H +/* end file simdjson/generic/numberparsing.h for icelake */ + +/* including simdjson/generic/implementation_simdjson_result_base-inl.h for icelake: #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { + +// +// internal::implementation_simdjson_result_base inline implementation +// + +template +simdjson_inline void implementation_simdjson_result_base::tie(T &value, error_code &error) && noexcept { + error = this->second; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +simdjson_warn_unused simdjson_inline error_code implementation_simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; +} + +template +simdjson_inline error_code implementation_simdjson_result_base::error() const noexcept { + return this->second; +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& implementation_simdjson_result_base::value() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline T&& implementation_simdjson_result_base::take_value() && noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& implementation_simdjson_result_base::value_unsafe() const& noexcept { + return this->first; +} + +template +simdjson_inline T& implementation_simdjson_result_base::value_unsafe() & noexcept { + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value_unsafe() && noexcept { + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value, error_code error) noexcept + : first{std::forward(value)}, second{error} {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(error_code error) noexcept + : implementation_simdjson_result_base(T{}, error) {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value) noexcept + : implementation_simdjson_result_base(std::forward(value), SUCCESS) {} + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H +/* end file simdjson/generic/implementation_simdjson_result_base-inl.h for icelake */ +/* end file simdjson/generic/amalgamated.h for icelake */ +/* including simdjson/icelake/end.h: #include "simdjson/icelake/end.h" */ +/* begin file simdjson/icelake/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_ICELAKE +SIMDJSON_UNTARGET_REGION +#endif + +/* undefining SIMDJSON_IMPLEMENTATION from "icelake" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/icelake/end.h */ + +#endif // SIMDJSON_ICELAKE_H +/* end file simdjson/icelake.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(ppc64) +/* including simdjson/ppc64.h: #include "simdjson/ppc64.h" */ +/* begin file simdjson/ppc64.h */ +#ifndef SIMDJSON_PPC64_H +#define SIMDJSON_PPC64_H + +/* including simdjson/ppc64/begin.h: #include "simdjson/ppc64/begin.h" */ +/* begin file simdjson/ppc64/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "ppc64" */ +#define SIMDJSON_IMPLEMENTATION ppc64 +/* including simdjson/ppc64/base.h: #include "simdjson/ppc64/base.h" */ +/* begin file simdjson/ppc64/base.h */ +#ifndef SIMDJSON_PPC64_BASE_H +#define SIMDJSON_PPC64_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Implementation for ALTIVEC (PPC64). + */ +namespace ppc64 { + +class implementation; + +namespace { +namespace simd { +template struct simd8; +template struct simd8x64; +} // namespace simd +} // unnamed namespace + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_BASE_H +/* end file simdjson/ppc64/base.h */ +/* including simdjson/ppc64/intrinsics.h: #include "simdjson/ppc64/intrinsics.h" */ +/* begin file simdjson/ppc64/intrinsics.h */ +#ifndef SIMDJSON_PPC64_INTRINSICS_H +#define SIMDJSON_PPC64_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This should be the correct header whether +// you use visual studio or other compilers. +#include + +// These are defined by altivec.h in GCC toolchain, it is safe to undef them. +#ifdef bool +#undef bool +#endif + +#ifdef vector +#undef vector +#endif + +static_assert(sizeof(__vector unsigned char) <= simdjson::SIMDJSON_PADDING, "insufficient padding for ppc64"); + +#endif // SIMDJSON_PPC64_INTRINSICS_H +/* end file simdjson/ppc64/intrinsics.h */ +/* including simdjson/ppc64/bitmanipulation.h: #include "simdjson/ppc64/bitmanipulation.h" */ +/* begin file simdjson/ppc64/bitmanipulation.h */ +#ifndef SIMDJSON_PPC64_BITMANIPULATION_H +#define SIMDJSON_PPC64_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num - 1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline int count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num); // Visual Studio wants two underscores +} +#else +simdjson_inline int count_ones(uint64_t input_num) { + return __builtin_popcountll(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + *result = value1 + value2; + return *result < value1; +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_BITMANIPULATION_H +/* end file simdjson/ppc64/bitmanipulation.h */ +/* including simdjson/ppc64/bitmask.h: #include "simdjson/ppc64/bitmask.h" */ +/* begin file simdjson/ppc64/bitmask.h */ +#ifndef SIMDJSON_PPC64_BITMASK_H +#define SIMDJSON_PPC64_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is +// encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(uint64_t bitmask) { + // You can use the version below, however gcc sometimes miscompiles + // vec_pmsum_be, it happens somewhere around between 8 and 9th version. + // The performance boost was not noticeable, falling back to a usual + // implementation. + // __vector unsigned long long all_ones = {~0ull, ~0ull}; + // __vector unsigned long long mask = {bitmask, 0}; + // // Clang and GCC return different values for pmsum for ull so cast it to one. + // // Generally it is not specified by ALTIVEC ISA what is returned by + // // vec_pmsum_be. + // #if defined(__LITTLE_ENDIAN__) + // return (uint64_t)(((__vector unsigned long long)vec_pmsum_be(all_ones, mask))[0]); + // #else + // return (uint64_t)(((__vector unsigned long long)vec_pmsum_be(all_ones, mask))[1]); + // #endif + bitmask ^= bitmask << 1; + bitmask ^= bitmask << 2; + bitmask ^= bitmask << 4; + bitmask ^= bitmask << 8; + bitmask ^= bitmask << 16; + bitmask ^= bitmask << 32; + return bitmask; +} + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif +/* end file simdjson/ppc64/bitmask.h */ +/* including simdjson/ppc64/numberparsing_defs.h: #include "simdjson/ppc64/numberparsing_defs.h" */ +/* begin file simdjson/ppc64/numberparsing_defs.h */ +#ifndef SIMDJSON_PPC64_NUMBERPARSING_DEFS_H +#define SIMDJSON_PPC64_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +#if defined(__linux__) +#include +#elif defined(__FreeBSD__) +#include +#endif + +namespace simdjson { +namespace ppc64 { +namespace numberparsing { + +// we don't have appropriate instructions, so let us use a scalar function +// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + uint64_t val; + std::memcpy(&val, chars, sizeof(uint64_t)); +#ifdef __BIG_ENDIAN__ +#if defined(__linux__) + val = bswap_64(val); +#elif defined(__FreeBSD__) + val = bswap64(val); +#endif +#endif + val = (val & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8; + val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16; + return uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32); +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace ppc64 +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_PPC64_NUMBERPARSING_DEFS_H +/* end file simdjson/ppc64/numberparsing_defs.h */ +/* including simdjson/ppc64/simd.h: #include "simdjson/ppc64/simd.h" */ +/* begin file simdjson/ppc64/simd.h */ +#ifndef SIMDJSON_PPC64_SIMD_H +#define SIMDJSON_PPC64_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace ppc64 { +namespace { +namespace simd { + +using __m128i = __vector unsigned char; + +template struct base { + __m128i value; + + // Zero constructor + simdjson_inline base() : value{__m128i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m128i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m128i &() const { + return this->value; + } + simdjson_inline operator __m128i &() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { + return vec_or(this->value, (__m128i)other); + } + simdjson_inline Child operator&(const Child other) const { + return vec_and(this->value, (__m128i)other); + } + simdjson_inline Child operator^(const Child other) const { + return vec_xor(this->value, (__m128i)other); + } + simdjson_inline Child bit_andnot(const Child other) const { + return vec_andc(this->value, (__m128i)other); + } + simdjson_inline Child &operator|=(const Child other) { + auto this_cast = static_cast(this); + *this_cast = *this_cast | other; + return *this_cast; + } + simdjson_inline Child &operator&=(const Child other) { + auto this_cast = static_cast(this); + *this_cast = *this_cast & other; + return *this_cast; + } + simdjson_inline Child &operator^=(const Child other) { + auto this_cast = static_cast(this); + *this_cast = *this_cast ^ other; + return *this_cast; + } +}; + +template > +struct base8 : base> { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m128i _value) : base>(_value) {} + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { + return (__m128i)vec_cmpeq(lhs.value, (__m128i)rhs); + } + + static const int SIZE = sizeof(base>::value); + + template + simdjson_inline simd8 prev(simd8 prev_chunk) const { + __m128i chunk = this->value; +#ifdef __LITTLE_ENDIAN__ + chunk = (__m128i)vec_reve(this->value); + prev_chunk = (__m128i)vec_reve((__m128i)prev_chunk); +#endif + chunk = (__m128i)vec_sld((__m128i)prev_chunk, (__m128i)chunk, 16 - N); +#ifdef __LITTLE_ENDIAN__ + chunk = (__m128i)vec_reve((__m128i)chunk); +#endif + return chunk; + } +}; + +// SIMD byte mask type (returned by things like eq and gt) +template <> struct simd8 : base8 { + static simdjson_inline simd8 splat(bool _value) { + return (__m128i)vec_splats((unsigned char)(-(!!_value))); + } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m128i _value) + : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) + : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { + __vector unsigned long long result; + const __m128i perm_mask = {0x78, 0x70, 0x68, 0x60, 0x58, 0x50, 0x48, 0x40, + 0x38, 0x30, 0x28, 0x20, 0x18, 0x10, 0x08, 0x00}; + + result = ((__vector unsigned long long)vec_vbpermq((__m128i)this->value, + (__m128i)perm_mask)); +#ifdef __LITTLE_ENDIAN__ + return static_cast(result[1]); +#else + return static_cast(result[0]); +#endif + } + simdjson_inline bool any() const { + return !vec_all_eq(this->value, (__m128i)vec_splats(0)); + } + simdjson_inline simd8 operator~() const { + return this->value ^ (__m128i)splat(true); + } +}; + +template struct base8_numeric : base8 { + static simdjson_inline simd8 splat(T value) { + (void)value; + return (__m128i)vec_splats(value); + } + static simdjson_inline simd8 zero() { return splat(0); } + static simdjson_inline simd8 load(const T values[16]) { + return (__m128i)(vec_vsx_ld(0, reinterpret_cast(values))); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16(T v0, T v1, T v2, T v3, T v4, + T v5, T v6, T v7, T v8, T v9, + T v10, T v11, T v12, T v13, + T v14, T v15) { + return simd8(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m128i _value) + : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[16]) const { + vec_vsx_st(this->value, 0, reinterpret_cast<__m128i *>(dst)); + } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { + return (__m128i)((__m128i)this->value + (__m128i)other); + } + simdjson_inline simd8 operator-(const simd8 other) const { + return (__m128i)((__m128i)this->value - (__m128i)other); + } + simdjson_inline simd8 &operator+=(const simd8 other) { + *this = *this + other; + return *static_cast *>(this); + } + simdjson_inline simd8 &operator-=(const simd8 other) { + *this = *this - other; + return *static_cast *>(this); + } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior + // for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return (__m128i)vec_perm((__m128i)lookup_table, (__m128i)lookup_table, this->value); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted + // as a bitset). Passing a 0 value for mask would be equivalent to writing out + // every byte to output. Only the first 16 - count_ones(mask) bytes of the + // result are significant but 16 bytes get written. Design consideration: it + // seems like a function with the signature simd8 compress(uint32_t mask) + // would be sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L *output) const { + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + using internal::thintable_epi8; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. +#ifdef __LITTLE_ENDIAN__ + __m128i shufmask = (__m128i)(__vector unsigned long long){ + thintable_epi8[mask1], thintable_epi8[mask2]}; +#else + __m128i shufmask = (__m128i)(__vector unsigned long long){ + thintable_epi8[mask2], thintable_epi8[mask1]}; + shufmask = (__m128i)vec_reve((__m128i)shufmask); +#endif + // we increment by 0x08 the second half of the mask + shufmask = ((__m128i)shufmask) + + ((__m128i)(__vector int){0, 0, 0x08080808, 0x08080808}); + + // this is the version "nearly pruned" + __m128i pruned = vec_perm(this->value, this->value, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + __m128i compactmask = + vec_vsx_ld(0, reinterpret_cast(pshufb_combine_table + pop1 * 8)); + __m128i answer = vec_perm(pruned, (__m128i)vec_splats(0), compactmask); + vec_vsx_st(answer, 0, reinterpret_cast<__m128i *>(output)); + } + + template + simdjson_inline simd8 + lookup_16(L replace0, L replace1, L replace2, L replace3, L replace4, + L replace5, L replace6, L replace7, L replace8, L replace9, + L replace10, L replace11, L replace12, L replace13, L replace14, + L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, replace4, replace5, replace6, + replace7, replace8, replace9, replace10, replace11, replace12, + replace13, replace14, replace15)); + } +}; + +// Signed bytes +template <> struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) + : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t *values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8(int8_t v0, int8_t v1, int8_t v2, int8_t v3, + int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, + int8_t v12, int8_t v13, int8_t v14, int8_t v15) + : simd8((__m128i)(__vector signed char){v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, + v15}) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 + repeat_16(int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, + int8_t v6, int8_t v7, int8_t v8, int8_t v9, int8_t v10, int8_t v11, + int8_t v12, int8_t v13, int8_t v14, int8_t v15) { + return simd8(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); + } + + // Order-sensitive comparisons + simdjson_inline simd8 + max_val(const simd8 other) const { + return (__m128i)vec_max((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } + simdjson_inline simd8 + min_val(const simd8 other) const { + return (__m128i)vec_min((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } + simdjson_inline simd8 + operator>(const simd8 other) const { + return (__m128i)vec_cmpgt((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } + simdjson_inline simd8 + operator<(const simd8 other) const { + return (__m128i)vec_cmplt((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } +}; + +// Unsigned bytes +template <> struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) + : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t *values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline + simd8(uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, + uint8_t v6, uint8_t v7, uint8_t v8, uint8_t v9, uint8_t v10, + uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15) + : simd8((__m128i){v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15}) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 + repeat_16(uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, + uint8_t v5, uint8_t v6, uint8_t v7, uint8_t v8, uint8_t v9, + uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, + uint8_t v15) { + return simd8(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); + } + + // Saturated math + simdjson_inline simd8 + saturating_add(const simd8 other) const { + return (__m128i)vec_adds(this->value, (__m128i)other); + } + simdjson_inline simd8 + saturating_sub(const simd8 other) const { + return (__m128i)vec_subs(this->value, (__m128i)other); + } + + // Order-specific operations + simdjson_inline simd8 + max_val(const simd8 other) const { + return (__m128i)vec_max(this->value, (__m128i)other); + } + simdjson_inline simd8 + min_val(const simd8 other) const { + return (__m128i)vec_min(this->value, (__m128i)other); + } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 + gt_bits(const simd8 other) const { + return this->saturating_sub(other); + } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 + lt_bits(const simd8 other) const { + return other.saturating_sub(*this); + } + simdjson_inline simd8 + operator<=(const simd8 other) const { + return other.max_val(*this) == other; + } + simdjson_inline simd8 + operator>=(const simd8 other) const { + return other.min_val(*this) == other; + } + simdjson_inline simd8 + operator>(const simd8 other) const { + return this->gt_bits(other).any_bits_set(); + } + simdjson_inline simd8 + operator<(const simd8 other) const { + return this->gt_bits(other).any_bits_set(); + } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { + return (__m128i)vec_cmpeq(this->value, (__m128i)vec_splats(uint8_t(0))); + } + simdjson_inline simd8 bits_not_set(simd8 bits) const { + return (*this & bits).bits_not_set(); + } + simdjson_inline simd8 any_bits_set() const { + return ~this->bits_not_set(); + } + simdjson_inline simd8 any_bits_set(simd8 bits) const { + return ~this->bits_not_set(bits); + } + simdjson_inline bool bits_not_set_anywhere() const { + return vec_all_eq(this->value, (__m128i)vec_splats(0)); + } + simdjson_inline bool any_bits_set_anywhere() const { + return !bits_not_set_anywhere(); + } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { + return vec_all_eq(vec_and(this->value, (__m128i)bits), + (__m128i)vec_splats(0)); + } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { + return !bits_not_set_anywhere(bits); + } + template simdjson_inline simd8 shr() const { + return simd8( + (__m128i)vec_sr(this->value, (__m128i)vec_splat_u8(N))); + } + template simdjson_inline simd8 shl() const { + return simd8( + (__m128i)vec_sl(this->value, (__m128i)vec_splat_u8(N))); + } +}; + +template struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, + "PPC64 kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64 &o) = delete; // no copy allowed + simd8x64 & + operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, + const simd8 chunk2, const simd8 chunk3) + : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) + : chunks{simd8::load(ptr), simd8::load(ptr + 16), + simd8::load(ptr + 32), simd8::load(ptr + 48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr + sizeof(simd8) * 0); + this->chunks[1].store(ptr + sizeof(simd8) * 1); + this->chunks[2].store(ptr + sizeof(simd8) * 2); + this->chunks[3].store(ptr + sizeof(simd8) * 3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | + (this->chunks[2] | this->chunks[3]); + } + + simdjson_inline uint64_t compress(uint64_t mask, T *output) const { + this->chunks[0].compress(uint16_t(mask), output); + this->chunks[1].compress(uint16_t(mask >> 16), + output + 16 - count_ones(mask & 0xFFFF)); + this->chunks[2].compress(uint16_t(mask >> 32), + output + 32 - count_ones(mask & 0xFFFFFFFF)); + this->chunks[3].compress(uint16_t(mask >> 48), + output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); + return 64 - count_ones(mask); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r0 = uint32_t(this->chunks[0].to_bitmask()); + uint64_t r1 = this->chunks[1].to_bitmask(); + uint64_t r2 = this->chunks[2].to_bitmask(); + uint64_t r3 = this->chunks[3].to_bitmask(); + return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64(this->chunks[0] == mask, this->chunks[1] == mask, + this->chunks[2] == mask, this->chunks[3] == mask) + .to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64(this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1], + this->chunks[2] == other.chunks[2], + this->chunks[3] == other.chunks[3]) + .to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64(this->chunks[0] <= mask, this->chunks[1] <= mask, + this->chunks[2] <= mask, this->chunks[3] <= mask) + .to_bitmask(); + } +}; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_SIMD_INPUT_H +/* end file simdjson/ppc64/simd.h */ +/* including simdjson/ppc64/stringparsing_defs.h: #include "simdjson/ppc64/stringparsing_defs.h" */ +/* begin file simdjson/ppc64/stringparsing_defs.h */ +#ifndef SIMDJSON_PPC64_STRINGPARSING_DEFS_H +#define SIMDJSON_PPC64_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/simd.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote + copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { + return ((bs_bits - 1) & quote_bits) != 0; + } + simdjson_inline bool has_backslash() { return bs_bits != 0; } + simdjson_inline int quote_index() { + return trailing_zeroes(quote_bits); + } + simdjson_inline int backslash_index() { + return trailing_zeroes(bs_bits); + } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote +backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 31 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), + "backslash and quote finder must process fewer than " + "SIMDJSON_PADDING bytes"); + simd8 v0(src); + simd8 v1(src + sizeof(v0)); + v0.store(dst); + v1.store(dst + sizeof(v0)); + + // Getting a 64-bit bitmask is much cheaper than multiple 16-bit bitmasks on + // PPC; therefore, we smash them together into a 64-byte mask and get the + // bitmask from there. + uint64_t bs_and_quote = + simd8x64(v0 == '\\', v1 == '\\', v0 == '"', v1 == '"').to_bitmask(); + return { + uint32_t(bs_and_quote), // bs_bits + uint32_t(bs_and_quote >> 32) // quote_bits + }; +} + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_STRINGPARSING_DEFS_H +/* end file simdjson/ppc64/stringparsing_defs.h */ + +#define SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT 1 +/* end file simdjson/ppc64/begin.h */ +/* including simdjson/generic/amalgamated.h for ppc64: #include "simdjson/generic/amalgamated.h" */ +/* begin file simdjson/generic/amalgamated.h for ppc64 */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_DEPENDENCIES_H) +#error simdjson/generic/dependencies.h must be included before simdjson/generic/amalgamated.h! +#endif + +/* including simdjson/generic/base.h for ppc64: #include "simdjson/generic/base.h" */ +/* begin file simdjson/generic/base.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): // If we haven't got an implementation yet, we're in the editor, editing a generic file! Just */ +/* amalgamation skipped (editor-only): // use the most advanced one we can so the most possible stuff can be tested. */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation_detection.h" */ +/* amalgamation skipped (editor-only): #if SIMDJSON_IMPLEMENTATION_ICELAKE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_HASWELL */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_WESTMERE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_ARM64 */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_PPC64 */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_FALLBACK */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/begin.h" */ +/* amalgamation skipped (editor-only): #else */ +/* amalgamation skipped (editor-only): #error "All possible implementations (including fallback) have been disabled! simdjson will not run." */ +/* amalgamation skipped (editor-only): #endif */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { + +struct open_container; +class dom_parser_implementation; + +/** + * The type of a JSON number + */ +enum class number_type { + floating_point_number=1, /// a binary64 number + signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + unsigned_integer /// a positive integer larger or equal to 1<<63 +}; + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_BASE_H +/* end file simdjson/generic/base.h for ppc64 */ +/* including simdjson/generic/jsoncharutils.h for ppc64: #include "simdjson/generic/jsoncharutils.h" */ +/* begin file simdjson/generic/jsoncharutils.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_JSONCHARUTILS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_JSONCHARUTILS_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/jsoncharutils_tables.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { +namespace jsoncharutils { + +// return non-zero if not a structural or whitespace char +// zero otherwise +simdjson_inline uint32_t is_not_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace_negated[c]; +} + +simdjson_inline uint32_t is_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace[c]; +} + +// returns a value with the high 16 bits set if not valid +// otherwise returns the conversion of the 4 hex digits at src into the bottom +// 16 bits of the 32-bit return register +// +// see +// https://lemire.me/blog/2019/04/17/parsing-short-hexadecimal-strings-efficiently/ +static inline uint32_t hex_to_u32_nocheck( + const uint8_t *src) { // strictly speaking, static inline is a C-ism + uint32_t v1 = internal::digit_to_val32[630 + src[0]]; + uint32_t v2 = internal::digit_to_val32[420 + src[1]]; + uint32_t v3 = internal::digit_to_val32[210 + src[2]]; + uint32_t v4 = internal::digit_to_val32[0 + src[3]]; + return v1 | v2 | v3 | v4; +} + +// given a code point cp, writes to c +// the utf-8 code, outputting the length in +// bytes, if the length is zero, the code point +// is invalid +// +// This can possibly be made faster using pdep +// and clz and table lookups, but JSON documents +// have few escaped code points, and the following +// function looks cheap. +// +// Note: we assume that surrogates are treated separately +// +simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) { + if (cp <= 0x7F) { + c[0] = uint8_t(cp); + return 1; // ascii + } + if (cp <= 0x7FF) { + c[0] = uint8_t((cp >> 6) + 192); + c[1] = uint8_t((cp & 63) + 128); + return 2; // universal plane + // Surrogates are treated elsewhere... + //} //else if (0xd800 <= cp && cp <= 0xdfff) { + // return 0; // surrogates // could put assert here + } else if (cp <= 0xFFFF) { + c[0] = uint8_t((cp >> 12) + 224); + c[1] = uint8_t(((cp >> 6) & 63) + 128); + c[2] = uint8_t((cp & 63) + 128); + return 3; + } else if (cp <= 0x10FFFF) { // if you know you have a valid code point, this + // is not needed + c[0] = uint8_t((cp >> 18) + 240); + c[1] = uint8_t(((cp >> 12) & 63) + 128); + c[2] = uint8_t(((cp >> 6) & 63) + 128); + c[3] = uint8_t((cp & 63) + 128); + return 4; + } + // will return 0 when the code point was too large. + return 0; // bad r +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +} // namespace jsoncharutils +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_JSONCHARUTILS_H +/* end file simdjson/generic/jsoncharutils.h for ppc64 */ +/* including simdjson/generic/atomparsing.h for ppc64: #include "simdjson/generic/atomparsing.h" */ +/* begin file simdjson/generic/atomparsing.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ATOMPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ATOMPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace ppc64 { +namespace { +/// @private +namespace atomparsing { + +// The string_to_uint32 is exclusively used to map literal strings to 32-bit values. +// We use memcpy instead of a pointer cast to avoid undefined behaviors since we cannot +// be certain that the character pointer will be properly aligned. +// You might think that using memcpy makes this function expensive, but you'd be wrong. +// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false"); +// to the compile-time constant 1936482662. +simdjson_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; } + + +// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive. +// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about. +simdjson_warn_unused +simdjson_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) { + uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++) + static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes"); + std::memcpy(&srcval, src, sizeof(uint32_t)); + return srcval ^ string_to_uint32(atom); +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src) { + return (str4ncmp(src, "true") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_true_atom(src); } + else if (len == 4) { return !str4ncmp(src, "true"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src) { + return (str4ncmp(src+1, "alse") | jsoncharutils::is_not_structural_or_whitespace(src[5])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src, size_t len) { + if (len > 5) { return is_valid_false_atom(src); } + else if (len == 5) { return !str4ncmp(src+1, "alse"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src) { + return (str4ncmp(src, "null") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_null_atom(src); } + else if (len == 4) { return !str4ncmp(src, "null"); } + else { return false; } +} + +} // namespace atomparsing +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ATOMPARSING_H +/* end file simdjson/generic/atomparsing.h for ppc64 */ +/* including simdjson/generic/dom_parser_implementation.h for ppc64: #include "simdjson/generic/dom_parser_implementation.h" */ +/* begin file simdjson/generic/dom_parser_implementation.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { + +// expectation: sizeof(open_container) = 64/8. +struct open_container { + uint32_t tape_index; // where, on the tape, does the scope ([,{) begins + uint32_t count; // how many elements in the scope +}; // struct open_container + +static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits"); + +class dom_parser_implementation final : public internal::dom_parser_implementation { +public: + /** Tape location of each open { or [ */ + std::unique_ptr open_containers{}; + /** Whether each open container is a [ or { */ + std::unique_ptr is_array{}; + /** Buffer passed to stage 1 */ + const uint8_t *buf{}; + /** Length passed to stage 1 */ + size_t len{0}; + /** Document passed to stage 2 */ + dom::document *doc{}; + + inline dom_parser_implementation() noexcept; + inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; + inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; + dom_parser_implementation(const dom_parser_implementation &) = delete; + dom_parser_implementation &operator=(const dom_parser_implementation &) = delete; + + simdjson_warn_unused error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage1(const uint8_t *buf, size_t len, stage1_mode partial) noexcept final; + simdjson_warn_unused error_code stage2(dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage2_next(dom::document &doc) noexcept final; + simdjson_warn_unused uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept final; + simdjson_warn_unused uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept final; + inline simdjson_warn_unused error_code set_capacity(size_t capacity) noexcept final; + inline simdjson_warn_unused error_code set_max_depth(size_t max_depth) noexcept final; +private: + simdjson_inline simdjson_warn_unused error_code set_capacity_stage1(size_t capacity); + +}; + +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { +namespace ppc64 { + +inline dom_parser_implementation::dom_parser_implementation() noexcept = default; +inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; +inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; + +// Leaving these here so they can be inlined if so desired +inline simdjson_warn_unused error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept { + if(capacity > SIMDJSON_MAXSIZE_BYTES) { return CAPACITY; } + // Stage 1 index output + size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7; + structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] ); + if (!structural_indexes) { _capacity = 0; return MEMALLOC; } + structural_indexes[0] = 0; + n_structural_indexes = 0; + + _capacity = capacity; + return SUCCESS; +} + +inline simdjson_warn_unused error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept { + // Stage 2 stacks + open_containers.reset(new (std::nothrow) open_container[max_depth]); + is_array.reset(new (std::nothrow) bool[max_depth]); + if (!is_array || !open_containers) { _max_depth = 0; return MEMALLOC; } + + _max_depth = max_depth; + return SUCCESS; +} + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file simdjson/generic/dom_parser_implementation.h for ppc64 */ +/* including simdjson/generic/implementation_simdjson_result_base.h for ppc64: #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { + +// This is a near copy of include/error.h's implementation_simdjson_result_base, except it doesn't use std::pair +// so we can avoid inlining errors +// TODO reconcile these! +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + * + * This is a base class for implementations that want to add functions to the result type for + * chaining. + * + * Override like: + * + * struct simdjson_result : public internal::implementation_simdjson_result_base { + * simdjson_result() noexcept : internal::implementation_simdjson_result_base() {} + * simdjson_result(error_code error) noexcept : internal::implementation_simdjson_result_base(error) {} + * simdjson_result(T &&value) noexcept : internal::implementation_simdjson_result_base(std::forward(value)) {} + * simdjson_result(T &&value, error_code error) noexcept : internal::implementation_simdjson_result_base(value, error) {} + * // Your extra methods here + * } + * + * Then any method returning simdjson_result will be chainable with your methods. + */ +template +struct implementation_simdjson_result_base { + + /** + * Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline implementation_simdjson_result_base() noexcept = default; + + /** + * Create a new error result. + */ + simdjson_inline implementation_simdjson_result_base(error_code error) noexcept; + + /** + * Create a new successful result. + */ + simdjson_inline implementation_simdjson_result_base(T &&value) noexcept; + + /** + * Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline implementation_simdjson_result_base(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); + + +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T& value_unsafe() & noexcept; + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; +protected: + /** users should never directly access first and second. **/ + T first{}; /** Users should never directly access 'first'. **/ + error_code second{UNINITIALIZED}; /** Users should never directly access 'second'. **/ +}; // struct implementation_simdjson_result_base + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H +/* end file simdjson/generic/implementation_simdjson_result_base.h for ppc64 */ +/* including simdjson/generic/numberparsing.h for ppc64: #include "simdjson/generic/numberparsing.h" */ +/* begin file simdjson/generic/numberparsing.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_NUMBERPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_NUMBERPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include +#include + +namespace simdjson { +namespace ppc64 { +namespace numberparsing { + +#ifdef JSON_TEST_NUMBERS +#define INVALID_NUMBER(SRC) (found_invalid_number((SRC)), NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (found_integer((VALUE), (SRC)), (WRITER).append_s64((VALUE))) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (found_unsigned_integer((VALUE), (SRC)), (WRITER).append_u64((VALUE))) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (found_float((VALUE), (SRC)), (WRITER).append_double((VALUE))) +#else +#define INVALID_NUMBER(SRC) (NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (WRITER).append_s64((VALUE)) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (WRITER).append_u64((VALUE)) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (WRITER).append_double((VALUE)) +#endif + +namespace { + +// Convert a mantissa, an exponent and a sign bit into an ieee64 double. +// The real_exponent needs to be in [0, 2046] (technically real_exponent = 2047 would be acceptable). +// The mantissa should be in [0,1<<53). The bit at index (1ULL << 52) while be zeroed. +simdjson_inline double to_double(uint64_t mantissa, uint64_t real_exponent, bool negative) { + double d; + mantissa &= ~(1ULL << 52); + mantissa |= real_exponent << 52; + mantissa |= ((static_cast(negative)) << 63); + std::memcpy(&d, &mantissa, sizeof(d)); + return d; +} + +// Attempts to compute i * 10^(power) exactly; and if "negative" is +// true, negate the result. +// This function will only work in some cases, when it does not work, success is +// set to false. This should work *most of the time* (like 99% of the time). +// We assume that power is in the [smallest_power, +// largest_power] interval: the caller is responsible for this check. +simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative, double &d) { + // we start with a fast path + // It was described in + // Clinger WD. How to read floating point numbers accurately. + // ACM SIGPLAN Notices. 1990 +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + // We cannot be certain that x/y is rounded to nearest. + if (0 <= power && power <= 22 && i <= 9007199254740991) +#else + if (-22 <= power && power <= 22 && i <= 9007199254740991) +#endif + { + // convert the integer into a double. This is lossless since + // 0 <= i <= 2^53 - 1. + d = double(i); + // + // The general idea is as follows. + // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then + // 1) Both s and p can be represented exactly as 64-bit floating-point + // values + // (binary64). + // 2) Because s and p can be represented exactly as floating-point values, + // then s * p + // and s / p will produce correctly rounded values. + // + if (power < 0) { + d = d / simdjson::internal::power_of_ten[-power]; + } else { + d = d * simdjson::internal::power_of_ten[power]; + } + if (negative) { + d = -d; + } + return true; + } + // When 22 < power && power < 22 + 16, we could + // hope for another, secondary fast path. It was + // described by David M. Gay in "Correctly rounded + // binary-decimal and decimal-binary conversions." (1990) + // If you need to compute i * 10^(22 + x) for x < 16, + // first compute i * 10^x, if you know that result is exact + // (e.g., when i * 10^x < 2^53), + // then you can still proceed and do (i * 10^x) * 10^22. + // Is this worth your time? + // You need 22 < power *and* power < 22 + 16 *and* (i * 10^(x-22) < 2^53) + // for this second fast path to work. + // If you you have 22 < power *and* power < 22 + 16, and then you + // optimistically compute "i * 10^(x-22)", there is still a chance that you + // have wasted your time if i * 10^(x-22) >= 2^53. It makes the use cases of + // this optimization maybe less common than we would like. Source: + // http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + // also used in RapidJSON: https://rapidjson.org/strtod_8h_source.html + + // The fast path has now failed, so we are failing back on the slower path. + + // In the slow path, we need to adjust i so that it is > 1<<63 which is always + // possible, except if i == 0, so we handle i == 0 separately. + if(i == 0) { + d = negative ? -0.0 : 0.0; + return true; + } + + + // The exponent is 1024 + 63 + power + // + floor(log(5**power)/log(2)). + // The 1024 comes from the ieee64 standard. + // The 63 comes from the fact that we use a 64-bit word. + // + // Computing floor(log(5**power)/log(2)) could be + // slow. Instead we use a fast function. + // + // For power in (-400,350), we have that + // (((152170 + 65536) * power ) >> 16); + // is equal to + // floor(log(5**power)/log(2)) + power when power >= 0 + // and it is equal to + // ceil(log(5**-power)/log(2)) + power when power < 0 + // + // The 65536 is (1<<16) and corresponds to + // (65536 * power) >> 16 ---> power + // + // ((152170 * power ) >> 16) is equal to + // floor(log(5**power)/log(2)) + // + // Note that this is not magic: 152170/(1<<16) is + // approximatively equal to log(5)/log(2). + // The 1<<16 value is a power of two; we could use a + // larger power of 2 if we wanted to. + // + int64_t exponent = (((152170 + 65536) * power) >> 16) + 1024 + 63; + + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(i); + i <<= lz; + + + // We are going to need to do some 64-bit arithmetic to get a precise product. + // We use a table lookup approach. + // It is safe because + // power >= smallest_power + // and power <= largest_power + // We recover the mantissa of the power, it has a leading 1. It is always + // rounded down. + // + // We want the most significant 64 bits of the product. We know + // this will be non-zero because the most significant bit of i is + // 1. + const uint32_t index = 2 * uint32_t(power - simdjson::internal::smallest_power); + // Optimization: It may be that materializing the index as a variable might confuse some compilers and prevent effective complex-addressing loads. (Done for code clarity.) + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); + // Both i and power_of_five_128[index] have their most significant bit set to 1 which + // implies that the either the most or the second most significant bit of the product + // is 1. We pack values in this manner for efficiency reasons: it maximizes the use + // we make of the product. It also makes it easy to reason about the product: there + // is 0 or 1 leading zero in the product. + + // Unless the least significant 9 bits of the high (64-bit) part of the full + // product are all 1s, then we know that the most significant 55 bits are + // exact and no further work is needed. Having 55 bits is necessary because + // we need 53 bits for the mantissa but we have to have one rounding bit and + // we can waste a bit if the most significant bit of the product is zero. + if((firstproduct.high & 0x1FF) == 0x1FF) { + // We want to compute i * 5^q, but only care about the top 55 bits at most. + // Consider the scenario where q>=0. Then 5^q may not fit in 64-bits. Doing + // the full computation is wasteful. So we do what is called a "truncated + // multiplication". + // We take the most significant 64-bits, and we put them in + // power_of_five_128[index]. Usually, that's good enough to approximate i * 5^q + // to the desired approximation using one multiplication. Sometimes it does not suffice. + // Then we store the next most significant 64 bits in power_of_five_128[index + 1], and + // then we get a better approximation to i * 5^q. + // + // That's for when q>=0. The logic for q<0 is somewhat similar but it is somewhat + // more complicated. + // + // There is an extra layer of complexity in that we need more than 55 bits of + // accuracy in the round-to-even scenario. + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if(secondproduct.high > firstproduct.low) { firstproduct.high++; } + // As it has been proven by Noble Mushtak and Daniel Lemire in "Fast Number Parsing Without + // Fallback" (https://arxiv.org/abs/2212.06644), at this point we are sure that the product + // is sufficiently accurate, and more computation is not needed. + } + uint64_t lower = firstproduct.low; + uint64_t upper = firstproduct.high; + // The final mantissa should be 53 bits with a leading 1. + // We shift it so that it occupies 54 bits with a leading 1. + /////// + uint64_t upperbit = upper >> 63; + uint64_t mantissa = upper >> (upperbit + 9); + lz += int(1 ^ upperbit); + + // Here we have mantissa < (1<<54). + int64_t real_exponent = exponent - lz; + if (simdjson_unlikely(real_exponent <= 0)) { // we have a subnormal? + // Here have that real_exponent <= 0 so -real_exponent >= 0 + if(-real_exponent + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure. + d = negative ? -0.0 : 0.0; + return true; + } + // next line is safe because -real_exponent + 1 < 0 + mantissa >>= -real_exponent + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0. + mantissa += (mantissa & 1); // round up + mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + real_exponent = (mantissa < (uint64_t(1) << 52)) ? 0 : 1; + d = to_double(mantissa, real_exponent, negative); + return true; + } + // We have to round to even. The "to even" part + // is only a problem when we are right in between two floats + // which we guard against. + // If we have lots of trailing zeros, we may fall right between two + // floating-point values. + // + // The round-to-even cases take the form of a number 2m+1 which is in (2^53,2^54] + // times a power of two. That is, it is right between a number with binary significand + // m and another number with binary significand m+1; and it must be the case + // that it cannot be represented by a float itself. + // + // We must have that w * 10 ^q == (2m+1) * 2^p for some power of two 2^p. + // Recall that 10^q = 5^q * 2^q. + // When q >= 0, we must have that (2m+1) is divible by 5^q, so 5^q <= 2^54. We have that + // 5^23 <= 2^54 and it is the last power of five to qualify, so q <= 23. + // When q<0, we have w >= (2m+1) x 5^{-q}. We must have that w<2^{64} so + // (2m+1) x 5^{-q} < 2^{64}. We have that 2m+1>2^{53}. Hence, we must have + // 2^{53} x 5^{-q} < 2^{64}. + // Hence we have 5^{-q} < 2^{11}$ or q>= -4. + // + // We require lower <= 1 and not lower == 0 because we could not prove that + // that lower == 0 is implied; but we could prove that lower <= 1 is a necessary and sufficient test. + if (simdjson_unlikely((lower <= 1) && (power >= -4) && (power <= 23) && ((mantissa & 3) == 1))) { + if((mantissa << (upperbit + 64 - 53 - 2)) == upper) { + mantissa &= ~1; // flip it so that we do not round up + } + } + + mantissa += mantissa & 1; + mantissa >>= 1; + + // Here we have mantissa < (1<<53), unless there was an overflow + if (mantissa >= (1ULL << 53)) { + ////////// + // This will happen when parsing values such as 7.2057594037927933e+16 + //////// + mantissa = (1ULL << 52); + real_exponent++; + } + mantissa &= ~(1ULL << 52); + // we have to check that real_exponent is in range, otherwise we bail out + if (simdjson_unlikely(real_exponent > 2046)) { + // We have an infinite value!!! We could actually throw an error here if we could. + return false; + } + d = to_double(mantissa, real_exponent, negative); + return true; +} + +// We call a fallback floating-point parser that might be slow. Note +// it will accept JSON numbers, but the JSON spec. is more restrictive so +// before you call parse_float_fallback, you need to have validated the input +// string with the JSON grammar. +// It will return an error (false) if the parsed number is infinite. +// The string parsing itself always succeeds. We know that there is at least +// one digit. +static bool parse_float_fallback(const uint8_t *ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +static bool parse_float_fallback(const uint8_t *ptr, const uint8_t *end_ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr), reinterpret_cast(end_ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +// check quickly whether the next 8 chars are made of digits +// at a glance, it looks better than Mula's +// http://0x80.pl/articles/swar-digits-validate.html +simdjson_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) { + uint64_t val; + // this can read up to 7 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(7 <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be bigger than 7"); + std::memcpy(&val, chars, 8); + // a branchy method might be faster: + // return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030) + // && (( (val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0 ) == + // 0x3030303030303030); + return (((val & 0xF0F0F0F0F0F0F0F0) | + (((val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4)) == + 0x3333333333333333); +} + +template +SIMDJSON_NO_SANITIZE_UNDEFINED // We deliberately allow overflow here and check later +simdjson_inline bool parse_digit(const uint8_t c, I &i) { + const uint8_t digit = static_cast(c - '0'); + if (digit > 9) { + return false; + } + // PERF NOTE: multiplication by 10 is cheaper than arbitrary integer multiplication + i = 10 * i + digit; // might overflow, we will handle the overflow later + return true; +} + +simdjson_inline error_code parse_decimal_after_separator(simdjson_unused const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) { + // we continue with the fiction that we have an integer. If the + // floating point number is representable as x * 10^z for some integer + // z that fits in 53 bits, then we will be able to convert back the + // the integer into a float in a lossless manner. + const uint8_t *const first_after_period = p; + +#ifdef SIMDJSON_SWAR_NUMBER_PARSING +#if SIMDJSON_SWAR_NUMBER_PARSING + // this helps if we have lots of decimals! + // this turns out to be frequent enough. + if (is_made_of_eight_digits_fast(p)) { + i = i * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + } +#endif // SIMDJSON_SWAR_NUMBER_PARSING +#endif // #ifdef SIMDJSON_SWAR_NUMBER_PARSING + // Unrolling the first digit makes a small difference on some implementations (e.g. westmere) + if (parse_digit(*p, i)) { ++p; } + while (parse_digit(*p, i)) { p++; } + exponent = first_after_period - p; + // Decimal without digits (123.) is illegal + if (exponent == 0) { + return INVALID_NUMBER(src); + } + return SUCCESS; +} + +simdjson_inline error_code parse_exponent(simdjson_unused const uint8_t *const src, const uint8_t *&p, int64_t &exponent) { + // Exp Sign: -123.456e[-]78 + bool neg_exp = ('-' == *p); + if (neg_exp || '+' == *p) { p++; } // Skip + as well + + // Exponent: -123.456e-[78] + auto start_exp = p; + int64_t exp_number = 0; + while (parse_digit(*p, exp_number)) { ++p; } + // It is possible for parse_digit to overflow. + // In particular, it could overflow to INT64_MIN, and we cannot do - INT64_MIN. + // Thus we *must* check for possible overflow before we negate exp_number. + + // Performance notes: it may seem like combining the two "simdjson_unlikely checks" below into + // a single simdjson_unlikely path would be faster. The reasoning is sound, but the compiler may + // not oblige and may, in fact, generate two distinct paths in any case. It might be + // possible to do uint64_t(p - start_exp - 1) >= 18 but it could end up trading off + // instructions for a simdjson_likely branch, an unconclusive gain. + + // If there were no digits, it's an error. + if (simdjson_unlikely(p == start_exp)) { + return INVALID_NUMBER(src); + } + // We have a valid positive exponent in exp_number at this point, except that + // it may have overflowed. + + // If there were more than 18 digits, we may have overflowed the integer. We have to do + // something!!!! + if (simdjson_unlikely(p > start_exp+18)) { + // Skip leading zeroes: 1e000000000000000000001 is technically valid and doesn't overflow + while (*start_exp == '0') { start_exp++; } + // 19 digits could overflow int64_t and is kind of absurd anyway. We don't + // support exponents smaller than -999,999,999,999,999,999 and bigger + // than 999,999,999,999,999,999. + // We can truncate. + // Note that 999999999999999999 is assuredly too large. The maximal ieee64 value before + // infinity is ~1.8e308. The smallest subnormal is ~5e-324. So, actually, we could + // truncate at 324. + // Note that there is no reason to fail per se at this point in time. + // E.g., 0e999999999999999999999 is a fine number. + if (p > start_exp+18) { exp_number = 999999999999999999; } + } + // At this point, we know that exp_number is a sane, positive, signed integer. + // It is <= 999,999,999,999,999,999. As long as 'exponent' is in + // [-8223372036854775808, 8223372036854775808], we won't overflow. Because 'exponent' + // is bounded in magnitude by the size of the JSON input, we are fine in this universe. + // To sum it up: the next line should never overflow. + exponent += (neg_exp ? -exp_number : exp_number); + return SUCCESS; +} + +simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t digit_count) { + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + const uint8_t *start = start_digits; + while ((*start == '0') || (*start == '.')) { ++start; } + // we over-decrement by one when there is a '.' + return digit_count - size_t(start - start_digits); +} + +} // unnamed namespace + +/** @private */ +static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) { + if (parse_float_fallback(src, answer)) { + return SUCCESS; + } + return INVALID_NUMBER(src); +} + +/** @private */ +template +simdjson_inline error_code write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer) { + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon in practice. + // + // 9999999999999999999 < 2**64 so we can accommodate 19 digits. + // If we have a decimal separator, then digit_count - 1 is the number of digits, but we + // may not have a decimal separator! + if (simdjson_unlikely(digit_count > 19 && significant_digits(start_digits, digit_count) > 19)) { + // Ok, chances are good that we had an overflow! + // this is almost never going to get called!!! + // we start anew, going slowly!!! + // This will happen in the following examples: + // 10000000000000000000000000000000000000000000e+308 + // 3.1415926535897932384626433832795028841971693993751 + // + // NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer + // reference to it, it would force it to be stored in memory, preventing the compiler from + // picking it apart and putting into registers. i.e. if we pass it as reference, + // it gets slow. + double d; + error_code error = slow_float_parsing(src, &d); + writer.append_double(d); + return error; + } + // NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other + // way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331 + // To future reader: we'd love if someone found a better way, or at least could explain this result! + if (simdjson_unlikely(exponent < simdjson::internal::smallest_power) || (exponent > simdjson::internal::largest_power)) { + // + // Important: smallest_power is such that it leads to a zero value. + // Observe that 18446744073709551615e-343 == 0, i.e. (2**64 - 1) e -343 is zero + // so something x 10^-343 goes to zero, but not so with something x 10^-342. + static_assert(simdjson::internal::smallest_power <= -342, "smallest_power is not small enough"); + // + if((exponent < simdjson::internal::smallest_power) || (i == 0)) { + // E.g. Parse "-0.0e-999" into the same value as "-0.0". See https://en.wikipedia.org/wiki/Signed_zero + WRITE_DOUBLE(negative ? -0.0 : 0.0, src, writer); + return SUCCESS; + } else { // (exponent > largest_power) and (i != 0) + // We have, for sure, an infinite value and simdjson refuses to parse infinite values. + return INVALID_NUMBER(src); + } + } + double d; + if (!compute_float_64(exponent, i, negative, d)) { + // we are almost never going to get here. + if (!parse_float_fallback(src, &d)) { return INVALID_NUMBER(src); } + } + WRITE_DOUBLE(d, src, writer); + return SUCCESS; +} + +// for performance analysis, it is sometimes useful to skip parsing +#ifdef SIMDJSON_SKIPNUMBERPARSING + +template +simdjson_inline error_code parse_number(const uint8_t *const, W &writer) { + writer.append_s64(0); // always write zero + return SUCCESS; // always succeeds +} + +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { return number_type::signed_integer; } +#else + +// parse the number at src +// define JSON_TEST_NUMBERS for unit testing +// +// It is assumed that the number is followed by a structural ({,},],[) character +// or a white space character. If that is not the case (e.g., when the JSON +// document is made of a single number), then it is necessary to copy the +// content and append a space before calling this function. +// +// Our objective is accurate parsing (ULP of 0) at high speed. +template +simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) { + + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + if (digit_count == 0 || ('0' == *start_digits && digit_count > 1)) { return INVALID_NUMBER(src); } + + // + // Handle floats if there is a . or e (or both) + // + int64_t exponent = 0; + bool is_float = false; + if ('.' == *p) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) ); + digit_count = int(p - start_digits); // used later to guard against overflows + } + if (('e' == *p) || ('E' == *p)) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_exponent(src, p, exponent) ); + } + if (is_float) { + const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p); + SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) ); + if (dirty_end) { return INVALID_NUMBER(src); } + return SUCCESS; + } + + // The longest negative 64-bit number is 19 digits. + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + size_t longest_digit_count = negative ? 19 : 20; + if (digit_count > longest_digit_count) { return INVALID_NUMBER(src); } + if (digit_count == longest_digit_count) { + if (negative) { + // Anything negative above INT64_MAX+1 is invalid + if (i > uint64_t(INT64_MAX)+1) { return INVALID_NUMBER(src); } + WRITE_INTEGER(~i+1, src, writer); + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + } else if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INVALID_NUMBER(src); } + } + + // Write unsigned if it doesn't fit in a signed integer. + if (i > uint64_t(INT64_MAX)) { + WRITE_UNSIGNED(i, src, writer); + } else { + WRITE_INTEGER(negative ? (~i+1) : i, src, writer); + } + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; +} + +// Inlineable functions +namespace { + +// This table can be used to characterize the final character of an integer +// string. For JSON structural character and allowable white space characters, +// we return SUCCESS. For 'e', '.' and 'E', we return INCORRECT_TYPE. Otherwise +// we return NUMBER_ERROR. +// Optimization note: we could easily reduce the size of the table by half (to 128) +// at the cost of an extra branch. +// Optimization note: we want the values to use at most 8 bits (not, e.g., 32 bits): +static_assert(error_code(uint8_t(NUMBER_ERROR))== NUMBER_ERROR, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(SUCCESS))== SUCCESS, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(INCORRECT_TYPE))== INCORRECT_TYPE, "bad NUMBER_ERROR cast"); + +const uint8_t integer_string_finisher[256] = { + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, INCORRECT_TYPE, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, SUCCESS, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR}; + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + + +// Parse any number from 0 to 18,446,744,073,709,551,615 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src, const uint8_t * const src_end) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if ((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { + const uint8_t *p = src + 1; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (*p != '"') { return NUMBER_ERROR; } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + // Note: we use src[1] and not src[0] because src[0] is the quote character in this + // instance. + if (src[1] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src, const uint8_t * const src_end) noexcept { + // + // Check for minus sign + // + if(src == src_end) { return NUMBER_ERROR; } + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = src; + uint64_t i = 0; + while (parse_digit(*src, i)) { src++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(src - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*src)) { + // return (*src == '.' || *src == 'e' || *src == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(*src != '"') { return NUMBER_ERROR; } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { + return (*src == '-'); +} + +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { return true; } + return false; +} + +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { + // We have an integer. + // If the number is negative and valid, it must be a signed integer. + if(negative) { return number_type::signed_integer; } + // We want values larger or equal to 9223372036854775808 to be unsigned + // integers, and the other values to be signed integers. + int digit_count = int(p - src); + if(digit_count >= 19) { + const uint8_t * smaller_big_integer = reinterpret_cast("9223372036854775808"); + if((digit_count >= 20) || (memcmp(src, smaller_big_integer, 19) >= 0)) { + return number_type::unsigned_integer; + } + } + return number_type::signed_integer; + } + // Hopefully, we have 'e' or 'E' or '.'. + return number_type::floating_point_number; +} + +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src, const uint8_t * const src_end) noexcept { + if(src == src_end) { return NUMBER_ERROR; } + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + if(p == src_end) { return NUMBER_ERROR; } + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while ((p != src_end) && parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely((p != src_end) && (*p == '.'))) { + p++; + const uint8_t *start_decimal_digits = p; + if ((p == src_end) || !parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = start_digits-src > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if ((p != src_end) && (*p == 'e' || *p == 'E')) { + p++; + if(p == src_end) { return NUMBER_ERROR; } + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while ((p != src_end) && parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (*p != '"') { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +} // unnamed namespace +#endif // SIMDJSON_SKIPNUMBERPARSING + +} // namespace numberparsing + +inline std::ostream& operator<<(std::ostream& out, number_type type) noexcept { + switch (type) { + case number_type::signed_integer: out << "integer in [-9223372036854775808,9223372036854775808)"; break; + case number_type::unsigned_integer: out << "unsigned integer in [9223372036854775808,18446744073709551616)"; break; + case number_type::floating_point_number: out << "floating-point number (binary64)"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_NUMBERPARSING_H +/* end file simdjson/generic/numberparsing.h for ppc64 */ + +/* including simdjson/generic/implementation_simdjson_result_base-inl.h for ppc64: #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { + +// +// internal::implementation_simdjson_result_base inline implementation +// + +template +simdjson_inline void implementation_simdjson_result_base::tie(T &value, error_code &error) && noexcept { + error = this->second; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +simdjson_warn_unused simdjson_inline error_code implementation_simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; +} + +template +simdjson_inline error_code implementation_simdjson_result_base::error() const noexcept { + return this->second; +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& implementation_simdjson_result_base::value() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline T&& implementation_simdjson_result_base::take_value() && noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& implementation_simdjson_result_base::value_unsafe() const& noexcept { + return this->first; +} + +template +simdjson_inline T& implementation_simdjson_result_base::value_unsafe() & noexcept { + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value_unsafe() && noexcept { + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value, error_code error) noexcept + : first{std::forward(value)}, second{error} {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(error_code error) noexcept + : implementation_simdjson_result_base(T{}, error) {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value) noexcept + : implementation_simdjson_result_base(std::forward(value), SUCCESS) {} + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H +/* end file simdjson/generic/implementation_simdjson_result_base-inl.h for ppc64 */ +/* end file simdjson/generic/amalgamated.h for ppc64 */ +/* including simdjson/ppc64/end.h: #include "simdjson/ppc64/end.h" */ +/* begin file simdjson/ppc64/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#undef SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT +/* undefining SIMDJSON_IMPLEMENTATION from "ppc64" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/ppc64/end.h */ + +#endif // SIMDJSON_PPC64_H +/* end file simdjson/ppc64.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(westmere) +/* including simdjson/westmere.h: #include "simdjson/westmere.h" */ +/* begin file simdjson/westmere.h */ +#ifndef SIMDJSON_WESTMERE_H +#define SIMDJSON_WESTMERE_H + +/* including simdjson/westmere/begin.h: #include "simdjson/westmere/begin.h" */ +/* begin file simdjson/westmere/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "westmere" */ +#define SIMDJSON_IMPLEMENTATION westmere +/* including simdjson/westmere/base.h: #include "simdjson/westmere/base.h" */ +/* begin file simdjson/westmere/base.h */ +#ifndef SIMDJSON_WESTMERE_BASE_H +#define SIMDJSON_WESTMERE_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_WESTMERE +namespace simdjson { +/** + * Implementation for Westmere (Intel SSE4.2). + */ +namespace westmere { + +class implementation; + +namespace { +namespace simd { + +template struct simd8; +template struct simd8x64; + +} // namespace simd +} // unnamed namespace + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BASE_H +/* end file simdjson/westmere/base.h */ +/* including simdjson/westmere/intrinsics.h: #include "simdjson/westmere/intrinsics.h" */ +/* begin file simdjson/westmere/intrinsics.h */ +#ifndef SIMDJSON_WESTMERE_INTRINSICS_H +#define SIMDJSON_WESTMERE_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + */ +#include // for _mm_alignr_epi8 +#include // for _mm_clmulepi64_si128 +#endif + +static_assert(sizeof(__m128i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for westmere"); + +#endif // SIMDJSON_WESTMERE_INTRINSICS_H +/* end file simdjson/westmere/intrinsics.h */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_WESTMERE +SIMDJSON_TARGET_REGION("sse4.2,pclmul,popcnt") +#endif + +/* including simdjson/westmere/bitmanipulation.h: #include "simdjson/westmere/bitmanipulation.h" */ +/* begin file simdjson/westmere/bitmanipulation.h */ +#ifndef SIMDJSON_WESTMERE_BITMANIPULATION_H +#define SIMDJSON_WESTMERE_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num-1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// SIMDJSON_REGULAR_VISUAL_STUDIO +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BITMANIPULATION_H +/* end file simdjson/westmere/bitmanipulation.h */ +/* including simdjson/westmere/bitmask.h: #include "simdjson/westmere/bitmask.h" */ +/* begin file simdjson/westmere/bitmask.h */ +#ifndef SIMDJSON_WESTMERE_BITMASK_H +#define SIMDJSON_WESTMERE_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(const uint64_t bitmask) { + // There should be no such thing with a processing supporting avx2 + // but not clmul. + __m128i all_ones = _mm_set1_epi8('\xFF'); + __m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0ULL, bitmask), all_ones, 0); + return _mm_cvtsi128_si64(result); +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BITMASK_H +/* end file simdjson/westmere/bitmask.h */ +/* including simdjson/westmere/numberparsing_defs.h: #include "simdjson/westmere/numberparsing_defs.h" */ +/* begin file simdjson/westmere/numberparsing_defs.h */ +#ifndef SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H +#define SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H + +/* including simdjson/westmere/base.h: #include "simdjson/westmere/base.h" */ +/* begin file simdjson/westmere/base.h */ +#ifndef SIMDJSON_WESTMERE_BASE_H +#define SIMDJSON_WESTMERE_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_WESTMERE +namespace simdjson { +/** + * Implementation for Westmere (Intel SSE4.2). + */ +namespace westmere { + +class implementation; + +namespace { +namespace simd { + +template struct simd8; +template struct simd8x64; + +} // namespace simd +} // unnamed namespace + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BASE_H +/* end file simdjson/westmere/base.h */ +/* including simdjson/westmere/intrinsics.h: #include "simdjson/westmere/intrinsics.h" */ +/* begin file simdjson/westmere/intrinsics.h */ +#ifndef SIMDJSON_WESTMERE_INTRINSICS_H +#define SIMDJSON_WESTMERE_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + */ +#include // for _mm_alignr_epi8 +#include // for _mm_clmulepi64_si128 +#endif + +static_assert(sizeof(__m128i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for westmere"); + +#endif // SIMDJSON_WESTMERE_INTRINSICS_H +/* end file simdjson/westmere/intrinsics.h */ + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace numberparsing { + +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + // this actually computes *16* values so we are being wasteful. + const __m128i ascii0 = _mm_set1_epi8('0'); + const __m128i mul_1_10 = + _mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1); + const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1); + const __m128i mul_1_10000 = + _mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1); + const __m128i input = _mm_sub_epi8( + _mm_loadu_si128(reinterpret_cast(chars)), ascii0); + const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10); + const __m128i t2 = _mm_madd_epi16(t1, mul_1_100); + const __m128i t3 = _mm_packus_epi32(t2, t2); + const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000); + return _mm_cvtsi128_si32( + t4); // only captures the sum of the first 8 digits, drop the rest +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace westmere +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H +/* end file simdjson/westmere/numberparsing_defs.h */ +/* including simdjson/westmere/simd.h: #include "simdjson/westmere/simd.h" */ +/* begin file simdjson/westmere/simd.h */ +#ifndef SIMDJSON_WESTMERE_SIMD_H +#define SIMDJSON_WESTMERE_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace simd { + + template + struct base { + __m128i value; + + // Zero constructor + simdjson_inline base() : value{__m128i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m128i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m128i&() const { return this->value; } + simdjson_inline operator __m128i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm_or_si128(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm_and_si128(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm_xor_si128(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm_andnot_si128(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + template> + struct base8: base> { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m128i _value) : base>(_value) {} + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return _mm_cmpeq_epi8(lhs, rhs); } + + static const int SIZE = sizeof(base>::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return _mm_alignr_epi8(*this, prev_chunk, 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m128i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { return _mm_movemask_epi8(*this); } + simdjson_inline bool any() const { return !_mm_testz_si128(*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm_setzero_si128(); } + static simdjson_inline simd8 load(const T values[16]) { + return _mm_loadu_si128(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m128i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[16]) const { return _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), *this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 16 - count_ones(mask) bytes of the result are significant but 16 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + __m128i shufmask = _mm_set_epi64x(thintable_epi8[mask2], thintable_epi8[mask1]); + // we increment by 0x08 the second half of the mask + shufmask = + _mm_add_epi8(shufmask, _mm_set_epi32(0x08080808, 0x08080808, 0, 0)); + // this is the version "nearly pruned" + __m128i pruned = _mm_shuffle_epi8(*this, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + __m128i compactmask = + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop1 * 8)); + __m128i answer = _mm_shuffle_epi8(pruned, compactmask); + _mm_storeu_si128(reinterpret_cast<__m128i *>(output), answer); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epi8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return _mm_cmpgt_epi8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm_cmpgt_epi8(other, *this); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epu8(*this, other); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline simd8 operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline simd8 operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return *this == uint8_t(0); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + simdjson_inline bool is_ascii() const { return _mm_movemask_epi8(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { return _mm_testz_si128(*this, *this); } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return _mm_testz_si128(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline int get_bit() const { return _mm_movemask_epi8(_mm_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, "Westmere kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, const simd8 chunk2, const simd8 chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+16), simd8::load(ptr+32), simd8::load(ptr+48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + this->chunks[2].store(ptr+sizeof(simd8)*2); + this->chunks[3].store(ptr+sizeof(simd8)*3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | (this->chunks[2] | this->chunks[3]); + } + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + this->chunks[0].compress(uint16_t(mask), output); + this->chunks[1].compress(uint16_t(mask >> 16), output + 16 - count_ones(mask & 0xFFFF)); + this->chunks[2].compress(uint16_t(mask >> 32), output + 32 - count_ones(mask & 0xFFFFFFFF)); + this->chunks[3].compress(uint16_t(mask >> 48), output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); + return 64 - count_ones(mask); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r0 = uint32_t(this->chunks[0].to_bitmask() ); + uint64_t r1 = this->chunks[1].to_bitmask() ; + uint64_t r2 = this->chunks[2].to_bitmask() ; + uint64_t r3 = this->chunks[3].to_bitmask() ; + return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask, + this->chunks[2] == mask, + this->chunks[3] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64( + this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1], + this->chunks[2] == other.chunks[2], + this->chunks[3] == other.chunks[3] + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask, + this->chunks[2] <= mask, + this->chunks[3] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_SIMD_INPUT_H +/* end file simdjson/westmere/simd.h */ +/* including simdjson/westmere/stringparsing_defs.h: #include "simdjson/westmere/stringparsing_defs.h" */ +/* begin file simdjson/westmere/stringparsing_defs.h */ +#ifndef SIMDJSON_WESTMERE_STRINGPARSING_DEFS_H +#define SIMDJSON_WESTMERE_STRINGPARSING_DEFS_H + +/* including simdjson/westmere/bitmanipulation.h: #include "simdjson/westmere/bitmanipulation.h" */ +/* begin file simdjson/westmere/bitmanipulation.h */ +#ifndef SIMDJSON_WESTMERE_BITMANIPULATION_H +#define SIMDJSON_WESTMERE_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num-1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// SIMDJSON_REGULAR_VISUAL_STUDIO +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BITMANIPULATION_H +/* end file simdjson/westmere/bitmanipulation.h */ +/* including simdjson/westmere/simd.h: #include "simdjson/westmere/simd.h" */ +/* begin file simdjson/westmere/simd.h */ +#ifndef SIMDJSON_WESTMERE_SIMD_H +#define SIMDJSON_WESTMERE_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace simd { + + template + struct base { + __m128i value; + + // Zero constructor + simdjson_inline base() : value{__m128i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m128i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m128i&() const { return this->value; } + simdjson_inline operator __m128i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm_or_si128(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm_and_si128(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm_xor_si128(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm_andnot_si128(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + template> + struct base8: base> { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m128i _value) : base>(_value) {} + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return _mm_cmpeq_epi8(lhs, rhs); } + + static const int SIZE = sizeof(base>::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return _mm_alignr_epi8(*this, prev_chunk, 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m128i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { return _mm_movemask_epi8(*this); } + simdjson_inline bool any() const { return !_mm_testz_si128(*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm_setzero_si128(); } + static simdjson_inline simd8 load(const T values[16]) { + return _mm_loadu_si128(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m128i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[16]) const { return _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), *this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 16 - count_ones(mask) bytes of the result are significant but 16 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + __m128i shufmask = _mm_set_epi64x(thintable_epi8[mask2], thintable_epi8[mask1]); + // we increment by 0x08 the second half of the mask + shufmask = + _mm_add_epi8(shufmask, _mm_set_epi32(0x08080808, 0x08080808, 0, 0)); + // this is the version "nearly pruned" + __m128i pruned = _mm_shuffle_epi8(*this, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + __m128i compactmask = + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop1 * 8)); + __m128i answer = _mm_shuffle_epi8(pruned, compactmask); + _mm_storeu_si128(reinterpret_cast<__m128i *>(output), answer); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epi8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return _mm_cmpgt_epi8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm_cmpgt_epi8(other, *this); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epu8(*this, other); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline simd8 operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline simd8 operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return *this == uint8_t(0); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + simdjson_inline bool is_ascii() const { return _mm_movemask_epi8(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { return _mm_testz_si128(*this, *this); } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return _mm_testz_si128(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline int get_bit() const { return _mm_movemask_epi8(_mm_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, "Westmere kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, const simd8 chunk2, const simd8 chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+16), simd8::load(ptr+32), simd8::load(ptr+48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + this->chunks[2].store(ptr+sizeof(simd8)*2); + this->chunks[3].store(ptr+sizeof(simd8)*3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | (this->chunks[2] | this->chunks[3]); + } + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + this->chunks[0].compress(uint16_t(mask), output); + this->chunks[1].compress(uint16_t(mask >> 16), output + 16 - count_ones(mask & 0xFFFF)); + this->chunks[2].compress(uint16_t(mask >> 32), output + 32 - count_ones(mask & 0xFFFFFFFF)); + this->chunks[3].compress(uint16_t(mask >> 48), output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); + return 64 - count_ones(mask); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r0 = uint32_t(this->chunks[0].to_bitmask() ); + uint64_t r1 = this->chunks[1].to_bitmask() ; + uint64_t r2 = this->chunks[2].to_bitmask() ; + uint64_t r3 = this->chunks[3].to_bitmask() ; + return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask, + this->chunks[2] == mask, + this->chunks[3] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64( + this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1], + this->chunks[2] == other.chunks[2], + this->chunks[3] == other.chunks[3] + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask, + this->chunks[2] <= mask, + this->chunks[3] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_SIMD_INPUT_H +/* end file simdjson/westmere/simd.h */ + +namespace simdjson { +namespace westmere { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return bs_bits != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 31 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v0(src); + simd8 v1(src + 16); + v0.store(dst); + v1.store(dst + 16); + uint64_t bs_and_quote = simd8x64(v0 == '\\', v1 == '\\', v0 == '"', v1 == '"').to_bitmask(); + return { + uint32_t(bs_and_quote), // bs_bits + uint32_t(bs_and_quote >> 32) // quote_bits + }; +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_STRINGPARSING_DEFS_H +/* end file simdjson/westmere/stringparsing_defs.h */ +/* end file simdjson/westmere/begin.h */ +/* including simdjson/generic/amalgamated.h for westmere: #include "simdjson/generic/amalgamated.h" */ +/* begin file simdjson/generic/amalgamated.h for westmere */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_DEPENDENCIES_H) +#error simdjson/generic/dependencies.h must be included before simdjson/generic/amalgamated.h! +#endif + +/* including simdjson/generic/base.h for westmere: #include "simdjson/generic/base.h" */ +/* begin file simdjson/generic/base.h for westmere */ +#ifndef SIMDJSON_GENERIC_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): // If we haven't got an implementation yet, we're in the editor, editing a generic file! Just */ +/* amalgamation skipped (editor-only): // use the most advanced one we can so the most possible stuff can be tested. */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation_detection.h" */ +/* amalgamation skipped (editor-only): #if SIMDJSON_IMPLEMENTATION_ICELAKE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_HASWELL */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_WESTMERE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_ARM64 */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_PPC64 */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/begin.h" */ +/* amalgamation skipped (editor-only): #elif SIMDJSON_IMPLEMENTATION_FALLBACK */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/begin.h" */ +/* amalgamation skipped (editor-only): #else */ +/* amalgamation skipped (editor-only): #error "All possible implementations (including fallback) have been disabled! simdjson will not run." */ +/* amalgamation skipped (editor-only): #endif */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_IMPLEMENTATION */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { + +struct open_container; +class dom_parser_implementation; + +/** + * The type of a JSON number + */ +enum class number_type { + floating_point_number=1, /// a binary64 number + signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + unsigned_integer /// a positive integer larger or equal to 1<<63 +}; + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_BASE_H +/* end file simdjson/generic/base.h for westmere */ +/* including simdjson/generic/jsoncharutils.h for westmere: #include "simdjson/generic/jsoncharutils.h" */ +/* begin file simdjson/generic/jsoncharutils.h for westmere */ +#ifndef SIMDJSON_GENERIC_JSONCHARUTILS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_JSONCHARUTILS_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/jsoncharutils_tables.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace jsoncharutils { + +// return non-zero if not a structural or whitespace char +// zero otherwise +simdjson_inline uint32_t is_not_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace_negated[c]; +} + +simdjson_inline uint32_t is_structural_or_whitespace(uint8_t c) { + return internal::structural_or_whitespace[c]; +} + +// returns a value with the high 16 bits set if not valid +// otherwise returns the conversion of the 4 hex digits at src into the bottom +// 16 bits of the 32-bit return register +// +// see +// https://lemire.me/blog/2019/04/17/parsing-short-hexadecimal-strings-efficiently/ +static inline uint32_t hex_to_u32_nocheck( + const uint8_t *src) { // strictly speaking, static inline is a C-ism + uint32_t v1 = internal::digit_to_val32[630 + src[0]]; + uint32_t v2 = internal::digit_to_val32[420 + src[1]]; + uint32_t v3 = internal::digit_to_val32[210 + src[2]]; + uint32_t v4 = internal::digit_to_val32[0 + src[3]]; + return v1 | v2 | v3 | v4; +} + +// given a code point cp, writes to c +// the utf-8 code, outputting the length in +// bytes, if the length is zero, the code point +// is invalid +// +// This can possibly be made faster using pdep +// and clz and table lookups, but JSON documents +// have few escaped code points, and the following +// function looks cheap. +// +// Note: we assume that surrogates are treated separately +// +simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) { + if (cp <= 0x7F) { + c[0] = uint8_t(cp); + return 1; // ascii + } + if (cp <= 0x7FF) { + c[0] = uint8_t((cp >> 6) + 192); + c[1] = uint8_t((cp & 63) + 128); + return 2; // universal plane + // Surrogates are treated elsewhere... + //} //else if (0xd800 <= cp && cp <= 0xdfff) { + // return 0; // surrogates // could put assert here + } else if (cp <= 0xFFFF) { + c[0] = uint8_t((cp >> 12) + 224); + c[1] = uint8_t(((cp >> 6) & 63) + 128); + c[2] = uint8_t((cp & 63) + 128); + return 3; + } else if (cp <= 0x10FFFF) { // if you know you have a valid code point, this + // is not needed + c[0] = uint8_t((cp >> 18) + 240); + c[1] = uint8_t(((cp >> 12) & 63) + 128); + c[2] = uint8_t(((cp >> 6) & 63) + 128); + c[3] = uint8_t((cp & 63) + 128); + return 4; + } + // will return 0 when the code point was too large. + return 0; // bad r +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +} // namespace jsoncharutils +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_JSONCHARUTILS_H +/* end file simdjson/generic/jsoncharutils.h for westmere */ +/* including simdjson/generic/atomparsing.h for westmere: #include "simdjson/generic/atomparsing.h" */ +/* begin file simdjson/generic/atomparsing.h for westmere */ +#ifndef SIMDJSON_GENERIC_ATOMPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ATOMPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace westmere { +namespace { +/// @private +namespace atomparsing { + +// The string_to_uint32 is exclusively used to map literal strings to 32-bit values. +// We use memcpy instead of a pointer cast to avoid undefined behaviors since we cannot +// be certain that the character pointer will be properly aligned. +// You might think that using memcpy makes this function expensive, but you'd be wrong. +// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false"); +// to the compile-time constant 1936482662. +simdjson_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; } + + +// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive. +// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about. +simdjson_warn_unused +simdjson_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) { + uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++) + static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes"); + std::memcpy(&srcval, src, sizeof(uint32_t)); + return srcval ^ string_to_uint32(atom); +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src) { + return (str4ncmp(src, "true") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_true_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_true_atom(src); } + else if (len == 4) { return !str4ncmp(src, "true"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src) { + return (str4ncmp(src+1, "alse") | jsoncharutils::is_not_structural_or_whitespace(src[5])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_false_atom(const uint8_t *src, size_t len) { + if (len > 5) { return is_valid_false_atom(src); } + else if (len == 5) { return !str4ncmp(src+1, "alse"); } + else { return false; } +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src) { + return (str4ncmp(src, "null") | jsoncharutils::is_not_structural_or_whitespace(src[4])) == 0; +} + +simdjson_warn_unused +simdjson_inline bool is_valid_null_atom(const uint8_t *src, size_t len) { + if (len > 4) { return is_valid_null_atom(src); } + else if (len == 4) { return !str4ncmp(src, "null"); } + else { return false; } +} + +} // namespace atomparsing +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ATOMPARSING_H +/* end file simdjson/generic/atomparsing.h for westmere */ +/* including simdjson/generic/dom_parser_implementation.h for westmere: #include "simdjson/generic/dom_parser_implementation.h" */ +/* begin file simdjson/generic/dom_parser_implementation.h for westmere */ +#ifndef SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { + +// expectation: sizeof(open_container) = 64/8. +struct open_container { + uint32_t tape_index; // where, on the tape, does the scope ([,{) begins + uint32_t count; // how many elements in the scope +}; // struct open_container + +static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits"); + +class dom_parser_implementation final : public internal::dom_parser_implementation { +public: + /** Tape location of each open { or [ */ + std::unique_ptr open_containers{}; + /** Whether each open container is a [ or { */ + std::unique_ptr is_array{}; + /** Buffer passed to stage 1 */ + const uint8_t *buf{}; + /** Length passed to stage 1 */ + size_t len{0}; + /** Document passed to stage 2 */ + dom::document *doc{}; + + inline dom_parser_implementation() noexcept; + inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; + inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; + dom_parser_implementation(const dom_parser_implementation &) = delete; + dom_parser_implementation &operator=(const dom_parser_implementation &) = delete; + + simdjson_warn_unused error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage1(const uint8_t *buf, size_t len, stage1_mode partial) noexcept final; + simdjson_warn_unused error_code stage2(dom::document &doc) noexcept final; + simdjson_warn_unused error_code stage2_next(dom::document &doc) noexcept final; + simdjson_warn_unused uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept final; + simdjson_warn_unused uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept final; + inline simdjson_warn_unused error_code set_capacity(size_t capacity) noexcept final; + inline simdjson_warn_unused error_code set_max_depth(size_t max_depth) noexcept final; +private: + simdjson_inline simdjson_warn_unused error_code set_capacity_stage1(size_t capacity); + +}; + +} // namespace westmere +} // namespace simdjson + +namespace simdjson { +namespace westmere { + +inline dom_parser_implementation::dom_parser_implementation() noexcept = default; +inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; +inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; + +// Leaving these here so they can be inlined if so desired +inline simdjson_warn_unused error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept { + if(capacity > SIMDJSON_MAXSIZE_BYTES) { return CAPACITY; } + // Stage 1 index output + size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7; + structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] ); + if (!structural_indexes) { _capacity = 0; return MEMALLOC; } + structural_indexes[0] = 0; + n_structural_indexes = 0; + + _capacity = capacity; + return SUCCESS; +} + +inline simdjson_warn_unused error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept { + // Stage 2 stacks + open_containers.reset(new (std::nothrow) open_container[max_depth]); + is_array.reset(new (std::nothrow) bool[max_depth]); + if (!is_array || !open_containers) { _max_depth = 0; return MEMALLOC; } + + _max_depth = max_depth; + return SUCCESS; +} + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H +/* end file simdjson/generic/dom_parser_implementation.h for westmere */ +/* including simdjson/generic/implementation_simdjson_result_base.h for westmere: #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base.h for westmere */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { + +// This is a near copy of include/error.h's implementation_simdjson_result_base, except it doesn't use std::pair +// so we can avoid inlining errors +// TODO reconcile these! +/** + * The result of a simdjson operation that could fail. + * + * Gives the option of reading error codes, or throwing an exception by casting to the desired result. + * + * This is a base class for implementations that want to add functions to the result type for + * chaining. + * + * Override like: + * + * struct simdjson_result : public internal::implementation_simdjson_result_base { + * simdjson_result() noexcept : internal::implementation_simdjson_result_base() {} + * simdjson_result(error_code error) noexcept : internal::implementation_simdjson_result_base(error) {} + * simdjson_result(T &&value) noexcept : internal::implementation_simdjson_result_base(std::forward(value)) {} + * simdjson_result(T &&value, error_code error) noexcept : internal::implementation_simdjson_result_base(value, error) {} + * // Your extra methods here + * } + * + * Then any method returning simdjson_result will be chainable with your methods. + */ +template +struct implementation_simdjson_result_base { + + /** + * Create a new empty result with error = UNINITIALIZED. + */ + simdjson_inline implementation_simdjson_result_base() noexcept = default; + + /** + * Create a new error result. + */ + simdjson_inline implementation_simdjson_result_base(error_code error) noexcept; + + /** + * Create a new successful result. + */ + simdjson_inline implementation_simdjson_result_base(T &&value) noexcept; + + /** + * Create a new result with both things (use if you don't want to branch when creating the result). + */ + simdjson_inline implementation_simdjson_result_base(T &&value, error_code error) noexcept; + + /** + * Move the value and the error to the provided variables. + * + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. + */ + simdjson_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + simdjson_inline error_code get(T &value) && noexcept; + + /** + * The error. + */ + simdjson_inline error_code error() const noexcept; + +#if SIMDJSON_EXCEPTIONS + + /** + * Get the result value. + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T& value() & noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& value() && noexcept(false); + + /** + * Take the result value (move it). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline T&& take_value() && noexcept(false); + + /** + * Cast to the value (will throw on error). + * + * @throw simdjson_error if there was an error. + */ + simdjson_inline operator T&&() && noexcept(false); + + +#endif // SIMDJSON_EXCEPTIONS + + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline const T& value_unsafe() const& noexcept; + /** + * Get the result value. This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T& value_unsafe() & noexcept; + /** + * Take the result value (move it). This function is safe if and only + * the error() method returns a value that evaluates to false. + */ + simdjson_inline T&& value_unsafe() && noexcept; +protected: + /** users should never directly access first and second. **/ + T first{}; /** Users should never directly access 'first'. **/ + error_code second{UNINITIALIZED}; /** Users should never directly access 'second'. **/ +}; // struct implementation_simdjson_result_base + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H +/* end file simdjson/generic/implementation_simdjson_result_base.h for westmere */ +/* including simdjson/generic/numberparsing.h for westmere: #include "simdjson/generic/numberparsing.h" */ +/* begin file simdjson/generic/numberparsing.h for westmere */ +#ifndef SIMDJSON_GENERIC_NUMBERPARSING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_NUMBERPARSING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/jsoncharutils.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include +#include + +namespace simdjson { +namespace westmere { +namespace numberparsing { + +#ifdef JSON_TEST_NUMBERS +#define INVALID_NUMBER(SRC) (found_invalid_number((SRC)), NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (found_integer((VALUE), (SRC)), (WRITER).append_s64((VALUE))) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (found_unsigned_integer((VALUE), (SRC)), (WRITER).append_u64((VALUE))) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (found_float((VALUE), (SRC)), (WRITER).append_double((VALUE))) +#else +#define INVALID_NUMBER(SRC) (NUMBER_ERROR) +#define WRITE_INTEGER(VALUE, SRC, WRITER) (WRITER).append_s64((VALUE)) +#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (WRITER).append_u64((VALUE)) +#define WRITE_DOUBLE(VALUE, SRC, WRITER) (WRITER).append_double((VALUE)) +#endif + +namespace { + +// Convert a mantissa, an exponent and a sign bit into an ieee64 double. +// The real_exponent needs to be in [0, 2046] (technically real_exponent = 2047 would be acceptable). +// The mantissa should be in [0,1<<53). The bit at index (1ULL << 52) while be zeroed. +simdjson_inline double to_double(uint64_t mantissa, uint64_t real_exponent, bool negative) { + double d; + mantissa &= ~(1ULL << 52); + mantissa |= real_exponent << 52; + mantissa |= ((static_cast(negative)) << 63); + std::memcpy(&d, &mantissa, sizeof(d)); + return d; +} + +// Attempts to compute i * 10^(power) exactly; and if "negative" is +// true, negate the result. +// This function will only work in some cases, when it does not work, success is +// set to false. This should work *most of the time* (like 99% of the time). +// We assume that power is in the [smallest_power, +// largest_power] interval: the caller is responsible for this check. +simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative, double &d) { + // we start with a fast path + // It was described in + // Clinger WD. How to read floating point numbers accurately. + // ACM SIGPLAN Notices. 1990 +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + // We cannot be certain that x/y is rounded to nearest. + if (0 <= power && power <= 22 && i <= 9007199254740991) +#else + if (-22 <= power && power <= 22 && i <= 9007199254740991) +#endif + { + // convert the integer into a double. This is lossless since + // 0 <= i <= 2^53 - 1. + d = double(i); + // + // The general idea is as follows. + // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then + // 1) Both s and p can be represented exactly as 64-bit floating-point + // values + // (binary64). + // 2) Because s and p can be represented exactly as floating-point values, + // then s * p + // and s / p will produce correctly rounded values. + // + if (power < 0) { + d = d / simdjson::internal::power_of_ten[-power]; + } else { + d = d * simdjson::internal::power_of_ten[power]; + } + if (negative) { + d = -d; + } + return true; + } + // When 22 < power && power < 22 + 16, we could + // hope for another, secondary fast path. It was + // described by David M. Gay in "Correctly rounded + // binary-decimal and decimal-binary conversions." (1990) + // If you need to compute i * 10^(22 + x) for x < 16, + // first compute i * 10^x, if you know that result is exact + // (e.g., when i * 10^x < 2^53), + // then you can still proceed and do (i * 10^x) * 10^22. + // Is this worth your time? + // You need 22 < power *and* power < 22 + 16 *and* (i * 10^(x-22) < 2^53) + // for this second fast path to work. + // If you you have 22 < power *and* power < 22 + 16, and then you + // optimistically compute "i * 10^(x-22)", there is still a chance that you + // have wasted your time if i * 10^(x-22) >= 2^53. It makes the use cases of + // this optimization maybe less common than we would like. Source: + // http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + // also used in RapidJSON: https://rapidjson.org/strtod_8h_source.html + + // The fast path has now failed, so we are failing back on the slower path. + + // In the slow path, we need to adjust i so that it is > 1<<63 which is always + // possible, except if i == 0, so we handle i == 0 separately. + if(i == 0) { + d = negative ? -0.0 : 0.0; + return true; + } + + + // The exponent is 1024 + 63 + power + // + floor(log(5**power)/log(2)). + // The 1024 comes from the ieee64 standard. + // The 63 comes from the fact that we use a 64-bit word. + // + // Computing floor(log(5**power)/log(2)) could be + // slow. Instead we use a fast function. + // + // For power in (-400,350), we have that + // (((152170 + 65536) * power ) >> 16); + // is equal to + // floor(log(5**power)/log(2)) + power when power >= 0 + // and it is equal to + // ceil(log(5**-power)/log(2)) + power when power < 0 + // + // The 65536 is (1<<16) and corresponds to + // (65536 * power) >> 16 ---> power + // + // ((152170 * power ) >> 16) is equal to + // floor(log(5**power)/log(2)) + // + // Note that this is not magic: 152170/(1<<16) is + // approximatively equal to log(5)/log(2). + // The 1<<16 value is a power of two; we could use a + // larger power of 2 if we wanted to. + // + int64_t exponent = (((152170 + 65536) * power) >> 16) + 1024 + 63; + + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(i); + i <<= lz; + + + // We are going to need to do some 64-bit arithmetic to get a precise product. + // We use a table lookup approach. + // It is safe because + // power >= smallest_power + // and power <= largest_power + // We recover the mantissa of the power, it has a leading 1. It is always + // rounded down. + // + // We want the most significant 64 bits of the product. We know + // this will be non-zero because the most significant bit of i is + // 1. + const uint32_t index = 2 * uint32_t(power - simdjson::internal::smallest_power); + // Optimization: It may be that materializing the index as a variable might confuse some compilers and prevent effective complex-addressing loads. (Done for code clarity.) + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); + // Both i and power_of_five_128[index] have their most significant bit set to 1 which + // implies that the either the most or the second most significant bit of the product + // is 1. We pack values in this manner for efficiency reasons: it maximizes the use + // we make of the product. It also makes it easy to reason about the product: there + // is 0 or 1 leading zero in the product. + + // Unless the least significant 9 bits of the high (64-bit) part of the full + // product are all 1s, then we know that the most significant 55 bits are + // exact and no further work is needed. Having 55 bits is necessary because + // we need 53 bits for the mantissa but we have to have one rounding bit and + // we can waste a bit if the most significant bit of the product is zero. + if((firstproduct.high & 0x1FF) == 0x1FF) { + // We want to compute i * 5^q, but only care about the top 55 bits at most. + // Consider the scenario where q>=0. Then 5^q may not fit in 64-bits. Doing + // the full computation is wasteful. So we do what is called a "truncated + // multiplication". + // We take the most significant 64-bits, and we put them in + // power_of_five_128[index]. Usually, that's good enough to approximate i * 5^q + // to the desired approximation using one multiplication. Sometimes it does not suffice. + // Then we store the next most significant 64 bits in power_of_five_128[index + 1], and + // then we get a better approximation to i * 5^q. + // + // That's for when q>=0. The logic for q<0 is somewhat similar but it is somewhat + // more complicated. + // + // There is an extra layer of complexity in that we need more than 55 bits of + // accuracy in the round-to-even scenario. + // + // The full_multiplication function computes the 128-bit product of two 64-bit words + // with a returned value of type value128 with a "low component" corresponding to the + // 64-bit least significant bits of the product and with a "high component" corresponding + // to the 64-bit most significant bits of the product. + simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if(secondproduct.high > firstproduct.low) { firstproduct.high++; } + // As it has been proven by Noble Mushtak and Daniel Lemire in "Fast Number Parsing Without + // Fallback" (https://arxiv.org/abs/2212.06644), at this point we are sure that the product + // is sufficiently accurate, and more computation is not needed. + } + uint64_t lower = firstproduct.low; + uint64_t upper = firstproduct.high; + // The final mantissa should be 53 bits with a leading 1. + // We shift it so that it occupies 54 bits with a leading 1. + /////// + uint64_t upperbit = upper >> 63; + uint64_t mantissa = upper >> (upperbit + 9); + lz += int(1 ^ upperbit); + + // Here we have mantissa < (1<<54). + int64_t real_exponent = exponent - lz; + if (simdjson_unlikely(real_exponent <= 0)) { // we have a subnormal? + // Here have that real_exponent <= 0 so -real_exponent >= 0 + if(-real_exponent + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure. + d = negative ? -0.0 : 0.0; + return true; + } + // next line is safe because -real_exponent + 1 < 0 + mantissa >>= -real_exponent + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0. + mantissa += (mantissa & 1); // round up + mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + real_exponent = (mantissa < (uint64_t(1) << 52)) ? 0 : 1; + d = to_double(mantissa, real_exponent, negative); + return true; + } + // We have to round to even. The "to even" part + // is only a problem when we are right in between two floats + // which we guard against. + // If we have lots of trailing zeros, we may fall right between two + // floating-point values. + // + // The round-to-even cases take the form of a number 2m+1 which is in (2^53,2^54] + // times a power of two. That is, it is right between a number with binary significand + // m and another number with binary significand m+1; and it must be the case + // that it cannot be represented by a float itself. + // + // We must have that w * 10 ^q == (2m+1) * 2^p for some power of two 2^p. + // Recall that 10^q = 5^q * 2^q. + // When q >= 0, we must have that (2m+1) is divible by 5^q, so 5^q <= 2^54. We have that + // 5^23 <= 2^54 and it is the last power of five to qualify, so q <= 23. + // When q<0, we have w >= (2m+1) x 5^{-q}. We must have that w<2^{64} so + // (2m+1) x 5^{-q} < 2^{64}. We have that 2m+1>2^{53}. Hence, we must have + // 2^{53} x 5^{-q} < 2^{64}. + // Hence we have 5^{-q} < 2^{11}$ or q>= -4. + // + // We require lower <= 1 and not lower == 0 because we could not prove that + // that lower == 0 is implied; but we could prove that lower <= 1 is a necessary and sufficient test. + if (simdjson_unlikely((lower <= 1) && (power >= -4) && (power <= 23) && ((mantissa & 3) == 1))) { + if((mantissa << (upperbit + 64 - 53 - 2)) == upper) { + mantissa &= ~1; // flip it so that we do not round up + } + } + + mantissa += mantissa & 1; + mantissa >>= 1; + + // Here we have mantissa < (1<<53), unless there was an overflow + if (mantissa >= (1ULL << 53)) { + ////////// + // This will happen when parsing values such as 7.2057594037927933e+16 + //////// + mantissa = (1ULL << 52); + real_exponent++; + } + mantissa &= ~(1ULL << 52); + // we have to check that real_exponent is in range, otherwise we bail out + if (simdjson_unlikely(real_exponent > 2046)) { + // We have an infinite value!!! We could actually throw an error here if we could. + return false; + } + d = to_double(mantissa, real_exponent, negative); + return true; +} + +// We call a fallback floating-point parser that might be slow. Note +// it will accept JSON numbers, but the JSON spec. is more restrictive so +// before you call parse_float_fallback, you need to have validated the input +// string with the JSON grammar. +// It will return an error (false) if the parsed number is infinite. +// The string parsing itself always succeeds. We know that there is at least +// one digit. +static bool parse_float_fallback(const uint8_t *ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +static bool parse_float_fallback(const uint8_t *ptr, const uint8_t *end_ptr, double *outDouble) { + *outDouble = simdjson::internal::from_chars(reinterpret_cast(ptr), reinterpret_cast(end_ptr)); + // We do not accept infinite values. + + // Detecting finite values in a portable manner is ridiculously hard, ideally + // we would want to do: + // return !std::isfinite(*outDouble); + // but that mysteriously fails under legacy/old libc++ libraries, see + // https://github.com/simdjson/simdjson/issues/1286 + // + // Therefore, fall back to this solution (the extra parens are there + // to handle that max may be a macro on windows). + return !(*outDouble > (std::numeric_limits::max)() || *outDouble < std::numeric_limits::lowest()); +} + +// check quickly whether the next 8 chars are made of digits +// at a glance, it looks better than Mula's +// http://0x80.pl/articles/swar-digits-validate.html +simdjson_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) { + uint64_t val; + // this can read up to 7 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(7 <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be bigger than 7"); + std::memcpy(&val, chars, 8); + // a branchy method might be faster: + // return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030) + // && (( (val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0 ) == + // 0x3030303030303030); + return (((val & 0xF0F0F0F0F0F0F0F0) | + (((val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4)) == + 0x3333333333333333); +} + +template +SIMDJSON_NO_SANITIZE_UNDEFINED // We deliberately allow overflow here and check later +simdjson_inline bool parse_digit(const uint8_t c, I &i) { + const uint8_t digit = static_cast(c - '0'); + if (digit > 9) { + return false; + } + // PERF NOTE: multiplication by 10 is cheaper than arbitrary integer multiplication + i = 10 * i + digit; // might overflow, we will handle the overflow later + return true; +} + +simdjson_inline error_code parse_decimal_after_separator(simdjson_unused const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) { + // we continue with the fiction that we have an integer. If the + // floating point number is representable as x * 10^z for some integer + // z that fits in 53 bits, then we will be able to convert back the + // the integer into a float in a lossless manner. + const uint8_t *const first_after_period = p; + +#ifdef SIMDJSON_SWAR_NUMBER_PARSING +#if SIMDJSON_SWAR_NUMBER_PARSING + // this helps if we have lots of decimals! + // this turns out to be frequent enough. + if (is_made_of_eight_digits_fast(p)) { + i = i * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + } +#endif // SIMDJSON_SWAR_NUMBER_PARSING +#endif // #ifdef SIMDJSON_SWAR_NUMBER_PARSING + // Unrolling the first digit makes a small difference on some implementations (e.g. westmere) + if (parse_digit(*p, i)) { ++p; } + while (parse_digit(*p, i)) { p++; } + exponent = first_after_period - p; + // Decimal without digits (123.) is illegal + if (exponent == 0) { + return INVALID_NUMBER(src); + } + return SUCCESS; +} + +simdjson_inline error_code parse_exponent(simdjson_unused const uint8_t *const src, const uint8_t *&p, int64_t &exponent) { + // Exp Sign: -123.456e[-]78 + bool neg_exp = ('-' == *p); + if (neg_exp || '+' == *p) { p++; } // Skip + as well + + // Exponent: -123.456e-[78] + auto start_exp = p; + int64_t exp_number = 0; + while (parse_digit(*p, exp_number)) { ++p; } + // It is possible for parse_digit to overflow. + // In particular, it could overflow to INT64_MIN, and we cannot do - INT64_MIN. + // Thus we *must* check for possible overflow before we negate exp_number. + + // Performance notes: it may seem like combining the two "simdjson_unlikely checks" below into + // a single simdjson_unlikely path would be faster. The reasoning is sound, but the compiler may + // not oblige and may, in fact, generate two distinct paths in any case. It might be + // possible to do uint64_t(p - start_exp - 1) >= 18 but it could end up trading off + // instructions for a simdjson_likely branch, an unconclusive gain. + + // If there were no digits, it's an error. + if (simdjson_unlikely(p == start_exp)) { + return INVALID_NUMBER(src); + } + // We have a valid positive exponent in exp_number at this point, except that + // it may have overflowed. + + // If there were more than 18 digits, we may have overflowed the integer. We have to do + // something!!!! + if (simdjson_unlikely(p > start_exp+18)) { + // Skip leading zeroes: 1e000000000000000000001 is technically valid and doesn't overflow + while (*start_exp == '0') { start_exp++; } + // 19 digits could overflow int64_t and is kind of absurd anyway. We don't + // support exponents smaller than -999,999,999,999,999,999 and bigger + // than 999,999,999,999,999,999. + // We can truncate. + // Note that 999999999999999999 is assuredly too large. The maximal ieee64 value before + // infinity is ~1.8e308. The smallest subnormal is ~5e-324. So, actually, we could + // truncate at 324. + // Note that there is no reason to fail per se at this point in time. + // E.g., 0e999999999999999999999 is a fine number. + if (p > start_exp+18) { exp_number = 999999999999999999; } + } + // At this point, we know that exp_number is a sane, positive, signed integer. + // It is <= 999,999,999,999,999,999. As long as 'exponent' is in + // [-8223372036854775808, 8223372036854775808], we won't overflow. Because 'exponent' + // is bounded in magnitude by the size of the JSON input, we are fine in this universe. + // To sum it up: the next line should never overflow. + exponent += (neg_exp ? -exp_number : exp_number); + return SUCCESS; +} + +simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t digit_count) { + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + const uint8_t *start = start_digits; + while ((*start == '0') || (*start == '.')) { ++start; } + // we over-decrement by one when there is a '.' + return digit_count - size_t(start - start_digits); +} + +} // unnamed namespace + +/** @private */ +static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) { + if (parse_float_fallback(src, answer)) { + return SUCCESS; + } + return INVALID_NUMBER(src); +} + +/** @private */ +template +simdjson_inline error_code write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer) { + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon in practice. + // + // 9999999999999999999 < 2**64 so we can accommodate 19 digits. + // If we have a decimal separator, then digit_count - 1 is the number of digits, but we + // may not have a decimal separator! + if (simdjson_unlikely(digit_count > 19 && significant_digits(start_digits, digit_count) > 19)) { + // Ok, chances are good that we had an overflow! + // this is almost never going to get called!!! + // we start anew, going slowly!!! + // This will happen in the following examples: + // 10000000000000000000000000000000000000000000e+308 + // 3.1415926535897932384626433832795028841971693993751 + // + // NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer + // reference to it, it would force it to be stored in memory, preventing the compiler from + // picking it apart and putting into registers. i.e. if we pass it as reference, + // it gets slow. + double d; + error_code error = slow_float_parsing(src, &d); + writer.append_double(d); + return error; + } + // NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other + // way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331 + // To future reader: we'd love if someone found a better way, or at least could explain this result! + if (simdjson_unlikely(exponent < simdjson::internal::smallest_power) || (exponent > simdjson::internal::largest_power)) { + // + // Important: smallest_power is such that it leads to a zero value. + // Observe that 18446744073709551615e-343 == 0, i.e. (2**64 - 1) e -343 is zero + // so something x 10^-343 goes to zero, but not so with something x 10^-342. + static_assert(simdjson::internal::smallest_power <= -342, "smallest_power is not small enough"); + // + if((exponent < simdjson::internal::smallest_power) || (i == 0)) { + // E.g. Parse "-0.0e-999" into the same value as "-0.0". See https://en.wikipedia.org/wiki/Signed_zero + WRITE_DOUBLE(negative ? -0.0 : 0.0, src, writer); + return SUCCESS; + } else { // (exponent > largest_power) and (i != 0) + // We have, for sure, an infinite value and simdjson refuses to parse infinite values. + return INVALID_NUMBER(src); + } + } + double d; + if (!compute_float_64(exponent, i, negative, d)) { + // we are almost never going to get here. + if (!parse_float_fallback(src, &d)) { return INVALID_NUMBER(src); } + } + WRITE_DOUBLE(d, src, writer); + return SUCCESS; +} + +// for performance analysis, it is sometimes useful to skip parsing +#ifdef SIMDJSON_SKIPNUMBERPARSING + +template +simdjson_inline error_code parse_number(const uint8_t *const, W &writer) { + writer.append_s64(0); // always write zero + return SUCCESS; // always succeeds +} + +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * const src) noexcept { return 0; } +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { return false; } +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { return number_type::signed_integer; } +#else + +// parse the number at src +// define JSON_TEST_NUMBERS for unit testing +// +// It is assumed that the number is followed by a structural ({,},],[) character +// or a white space character. If that is not the case (e.g., when the JSON +// document is made of a single number), then it is necessary to copy the +// content and append a space before calling this function. +// +// Our objective is accurate parsing (ULP of 0) at high speed. +template +simdjson_inline error_code parse_number(const uint8_t *const src, W &writer) { + + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + if (digit_count == 0 || ('0' == *start_digits && digit_count > 1)) { return INVALID_NUMBER(src); } + + // + // Handle floats if there is a . or e (or both) + // + int64_t exponent = 0; + bool is_float = false; + if ('.' == *p) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) ); + digit_count = int(p - start_digits); // used later to guard against overflows + } + if (('e' == *p) || ('E' == *p)) { + is_float = true; + ++p; + SIMDJSON_TRY( parse_exponent(src, p, exponent) ); + } + if (is_float) { + const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p); + SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) ); + if (dirty_end) { return INVALID_NUMBER(src); } + return SUCCESS; + } + + // The longest negative 64-bit number is 19 digits. + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + size_t longest_digit_count = negative ? 19 : 20; + if (digit_count > longest_digit_count) { return INVALID_NUMBER(src); } + if (digit_count == longest_digit_count) { + if (negative) { + // Anything negative above INT64_MAX+1 is invalid + if (i > uint64_t(INT64_MAX)+1) { return INVALID_NUMBER(src); } + WRITE_INTEGER(~i+1, src, writer); + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + } else if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INVALID_NUMBER(src); } + } + + // Write unsigned if it doesn't fit in a signed integer. + if (i > uint64_t(INT64_MAX)) { + WRITE_UNSIGNED(i, src, writer); + } else { + WRITE_INTEGER(negative ? (~i+1) : i, src, writer); + } + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return INVALID_NUMBER(src); } + return SUCCESS; +} + +// Inlineable functions +namespace { + +// This table can be used to characterize the final character of an integer +// string. For JSON structural character and allowable white space characters, +// we return SUCCESS. For 'e', '.' and 'E', we return INCORRECT_TYPE. Otherwise +// we return NUMBER_ERROR. +// Optimization note: we could easily reduce the size of the table by half (to 128) +// at the cost of an extra branch. +// Optimization note: we want the values to use at most 8 bits (not, e.g., 32 bits): +static_assert(error_code(uint8_t(NUMBER_ERROR))== NUMBER_ERROR, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(SUCCESS))== SUCCESS, "bad NUMBER_ERROR cast"); +static_assert(error_code(uint8_t(INCORRECT_TYPE))== INCORRECT_TYPE, "bad NUMBER_ERROR cast"); + +const uint8_t integer_string_finisher[256] = { + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, INCORRECT_TYPE, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, SUCCESS, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, INCORRECT_TYPE, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, SUCCESS, NUMBER_ERROR, + SUCCESS, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, NUMBER_ERROR, + NUMBER_ERROR}; + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + + +// Parse any number from 0 to 18,446,744,073,709,551,615 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_unsigned(const uint8_t * const src, const uint8_t * const src_end) noexcept { + const uint8_t *p = src; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if ((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + if (src[0] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from 0 to 18,446,744,073,709,551,615 +simdjson_unused simdjson_inline simdjson_result parse_unsigned_in_string(const uint8_t * const src) noexcept { + const uint8_t *p = src + 1; + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // The longest positive 64-bit number is 20 digits. + // We do it this way so we don't trigger this branch unless we must. + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > 20)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > 20)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if (*p != '"') { return NUMBER_ERROR; } + + if (digit_count == 20) { + // Positive overflow check: + // - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the + // biggest uint64_t. + // - A 20 digit number starting with 1 is overflow if it is less than INT64_MAX. + // If we got here, it's a 20 digit number starting with the digit "1". + // - If a 20 digit number starting with 1 overflowed (i*10+digit), the result will be smaller + // than 1,553,255,926,290,448,384. + // - That is smaller than the smallest possible 20-digit number the user could write: + // 10,000,000,000,000,000,000. + // - Therefore, if the number is positive and lower than that, it's overflow. + // - The value we are looking at is less than or equal to INT64_MAX. + // + // Note: we use src[1] and not src[0] because src[0] is the quote character in this + // instance. + if (src[1] != uint8_t('1') || i <= uint64_t(INT64_MAX)) { return INCORRECT_TYPE; } + } + + return i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while (parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_integer(const uint8_t * const src, const uint8_t * const src_end) noexcept { + // + // Check for minus sign + // + if(src == src_end) { return NUMBER_ERROR; } + bool negative = (*src == '-'); + const uint8_t *p = src + uint8_t(negative); + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = p; + uint64_t i = 0; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(p - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*p)) { + // return (*p == '.' || *p == 'e' || *p == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if((p != src_end) && integer_string_finisher[*p] != SUCCESS) { return error_code(integer_string_finisher[*p]); } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +// Parse any number from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 +simdjson_unused simdjson_inline simdjson_result parse_integer_in_string(const uint8_t *src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + // PERF NOTE: we don't use is_made_of_eight_digits_fast because large integers like 123456789 are rare + const uint8_t *const start_digits = src; + uint64_t i = 0; + while (parse_digit(*src, i)) { src++; } + + // If there were no digits, or if the integer starts with 0 and has more than one digit, it's an error. + // Optimization note: size_t is expected to be unsigned. + size_t digit_count = size_t(src - start_digits); + // We go from + // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + // so we can never represent numbers that have more than 19 digits. + size_t longest_digit_count = 19; + // Optimization note: the compiler can probably merge + // ((digit_count == 0) || (digit_count > longest_digit_count)) + // into a single branch since digit_count is unsigned. + if ((digit_count == 0) || (digit_count > longest_digit_count)) { return INCORRECT_TYPE; } + // Here digit_count > 0. + if (('0' == *start_digits) && (digit_count > 1)) { return NUMBER_ERROR; } + // We can do the following... + // if (!jsoncharutils::is_structural_or_whitespace(*src)) { + // return (*src == '.' || *src == 'e' || *src == 'E') ? INCORRECT_TYPE : NUMBER_ERROR; + // } + // as a single table lookup: + if(*src != '"') { return NUMBER_ERROR; } + // Negative numbers have can go down to - INT64_MAX - 1 whereas positive numbers are limited to INT64_MAX. + // Performance note: This check is only needed when digit_count == longest_digit_count but it is + // so cheap that we might as well always make it. + if(i > uint64_t(INT64_MAX) + uint64_t(negative)) { return INCORRECT_TYPE; } + return negative ? (~i+1) : i; +} + +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline bool is_negative(const uint8_t * src) noexcept { + return (*src == '-'); +} + +simdjson_unused simdjson_inline simdjson_result is_integer(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { return true; } + return false; +} + +simdjson_unused simdjson_inline simdjson_result get_number_type(const uint8_t * src) noexcept { + bool negative = (*src == '-'); + src += uint8_t(negative); + const uint8_t *p = src; + while(static_cast(*p - '0') <= 9) { p++; } + if ( p == src ) { return NUMBER_ERROR; } + if (jsoncharutils::is_structural_or_whitespace(*p)) { + // We have an integer. + // If the number is negative and valid, it must be a signed integer. + if(negative) { return number_type::signed_integer; } + // We want values larger or equal to 9223372036854775808 to be unsigned + // integers, and the other values to be signed integers. + int digit_count = int(p - src); + if(digit_count >= 19) { + const uint8_t * smaller_big_integer = reinterpret_cast("9223372036854775808"); + if((digit_count >= 20) || (memcmp(src, smaller_big_integer, 19) >= 0)) { + return number_type::unsigned_integer; + } + } + return number_type::signed_integer; + } + // Hopefully, we have 'e' or 'E' or '.'. + return number_type::floating_point_number; +} + +// Never read at src_end or beyond +simdjson_unused simdjson_inline simdjson_result parse_double(const uint8_t * src, const uint8_t * const src_end) noexcept { + if(src == src_end) { return NUMBER_ERROR; } + // + // Check for minus sign + // + bool negative = (*src == '-'); + src += uint8_t(negative); + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + if(p == src_end) { return NUMBER_ERROR; } + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while ((p != src_end) && parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely((p != src_end) && (*p == '.'))) { + p++; + const uint8_t *start_decimal_digits = p; + if ((p == src_end) || !parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while ((p != src_end) && parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = start_digits-src > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if ((p != src_end) && (*p == 'e' || *p == 'E')) { + p++; + if(p == src_end) { return NUMBER_ERROR; } + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while ((p != src_end) && parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) { + return NUMBER_ERROR; + } + return d; +} + +simdjson_unused simdjson_inline simdjson_result parse_double_in_string(const uint8_t * src) noexcept { + // + // Check for minus sign + // + bool negative = (*(src + 1) == '-'); + src += uint8_t(negative) + 1; + + // + // Parse the integer part. + // + uint64_t i = 0; + const uint8_t *p = src; + p += parse_digit(*p, i); + bool leading_zero = (i == 0); + while (parse_digit(*p, i)) { p++; } + // no integer digits, or 0123 (zero must be solo) + if ( p == src ) { return INCORRECT_TYPE; } + if ( (leading_zero && p != src+1)) { return NUMBER_ERROR; } + + // + // Parse the decimal part. + // + int64_t exponent = 0; + bool overflow; + if (simdjson_likely(*p == '.')) { + p++; + const uint8_t *start_decimal_digits = p; + if (!parse_digit(*p, i)) { return NUMBER_ERROR; } // no decimal digits + p++; + while (parse_digit(*p, i)) { p++; } + exponent = -(p - start_decimal_digits); + + // Overflow check. More than 19 digits (minus the decimal) may be overflow. + overflow = p-src-1 > 19; + if (simdjson_unlikely(overflow && leading_zero)) { + // Skip leading 0.00000 and see if it still overflows + const uint8_t *start_digits = src + 2; + while (*start_digits == '0') { start_digits++; } + overflow = p-start_digits > 19; + } + } else { + overflow = p-src > 19; + } + + // + // Parse the exponent + // + if (*p == 'e' || *p == 'E') { + p++; + bool exp_neg = *p == '-'; + p += exp_neg || *p == '+'; + + uint64_t exp = 0; + const uint8_t *start_exp_digits = p; + while (parse_digit(*p, exp)) { p++; } + // no exp digits, or 20+ exp digits + if (p-start_exp_digits == 0 || p-start_exp_digits > 19) { return NUMBER_ERROR; } + + exponent += exp_neg ? 0-exp : exp; + } + + if (*p != '"') { return NUMBER_ERROR; } + + overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power; + + // + // Assemble (or slow-parse) the float + // + double d; + if (simdjson_likely(!overflow)) { + if (compute_float_64(exponent, i, negative, d)) { return d; } + } + if (!parse_float_fallback(src - uint8_t(negative), &d)) { + return NUMBER_ERROR; + } + return d; +} + +} // unnamed namespace +#endif // SIMDJSON_SKIPNUMBERPARSING + +} // namespace numberparsing + +inline std::ostream& operator<<(std::ostream& out, number_type type) noexcept { + switch (type) { + case number_type::signed_integer: out << "integer in [-9223372036854775808,9223372036854775808)"; break; + case number_type::unsigned_integer: out << "unsigned integer in [9223372036854775808,18446744073709551616)"; break; + case number_type::floating_point_number: out << "floating-point number (binary64)"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_NUMBERPARSING_H +/* end file simdjson/generic/numberparsing.h for westmere */ + +/* including simdjson/generic/implementation_simdjson_result_base-inl.h for westmere: #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* begin file simdjson/generic/implementation_simdjson_result_base-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { + +// +// internal::implementation_simdjson_result_base inline implementation +// + +template +simdjson_inline void implementation_simdjson_result_base::tie(T &value, error_code &error) && noexcept { + error = this->second; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +simdjson_warn_unused simdjson_inline error_code implementation_simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; +} + +template +simdjson_inline error_code implementation_simdjson_result_base::error() const noexcept { + return this->second; +} + +#if SIMDJSON_EXCEPTIONS + +template +simdjson_inline T& implementation_simdjson_result_base::value() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +template +simdjson_inline T&& implementation_simdjson_result_base::take_value() && noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::operator T&&() && noexcept(false) { + return std::forward>(*this).take_value(); +} + +#endif // SIMDJSON_EXCEPTIONS + +template +simdjson_inline const T& implementation_simdjson_result_base::value_unsafe() const& noexcept { + return this->first; +} + +template +simdjson_inline T& implementation_simdjson_result_base::value_unsafe() & noexcept { + return this->first; +} + +template +simdjson_inline T&& implementation_simdjson_result_base::value_unsafe() && noexcept { + return std::forward(this->first); +} + +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value, error_code error) noexcept + : first{std::forward(value)}, second{error} {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(error_code error) noexcept + : implementation_simdjson_result_base(T{}, error) {} +template +simdjson_inline implementation_simdjson_result_base::implementation_simdjson_result_base(T &&value) noexcept + : implementation_simdjson_result_base(std::forward(value), SUCCESS) {} + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H +/* end file simdjson/generic/implementation_simdjson_result_base-inl.h for westmere */ +/* end file simdjson/generic/amalgamated.h for westmere */ +/* including simdjson/westmere/end.h: #include "simdjson/westmere/end.h" */ +/* begin file simdjson/westmere/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_WESTMERE +SIMDJSON_UNTARGET_REGION +#endif + +/* undefining SIMDJSON_IMPLEMENTATION from "westmere" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/westmere/end.h */ + +#endif // SIMDJSON_WESTMERE_H +/* end file simdjson/westmere.h */ +#else +#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION +#endif + +/* undefining SIMDJSON_CONDITIONAL_INCLUDE */ +#undef SIMDJSON_CONDITIONAL_INCLUDE + +#endif // SIMDJSON_BUILTIN_H +/* end file simdjson/builtin.h */ +/* skipped duplicate #include "simdjson/builtin/base.h" */ + +/* including simdjson/generic/ondemand/dependencies.h: #include "simdjson/generic/ondemand/dependencies.h" */ +/* begin file simdjson/generic/ondemand/dependencies.h */ +#ifdef SIMDJSON_CONDITIONAL_INCLUDE +#error simdjson/generic/ondemand/dependencies.h must be included before defining SIMDJSON_CONDITIONAL_INCLUDE! +#endif + +#ifndef SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H +#define SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H + +// Internal headers needed for ondemand generics. +// All includes not under simdjson/generic/ondemand must be here! +// Otherwise, amalgamation will fail. +/* skipped duplicate #include "simdjson/dom/base.h" // for MINIMAL_DOCUMENT_CAPACITY */ +/* skipped duplicate #include "simdjson/implementation.h" */ +/* skipped duplicate #include "simdjson/padded_string.h" */ +/* skipped duplicate #include "simdjson/padded_string_view.h" */ +/* skipped duplicate #include "simdjson/internal/dom_parser_implementation.h" */ + +#endif // SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H +/* end file simdjson/generic/ondemand/dependencies.h */ + +/* defining SIMDJSON_CONDITIONAL_INCLUDE */ +#define SIMDJSON_CONDITIONAL_INCLUDE + +#if SIMDJSON_BUILTIN_IMPLEMENTATION_IS(arm64) +/* including simdjson/arm64/ondemand.h: #include "simdjson/arm64/ondemand.h" */ +/* begin file simdjson/arm64/ondemand.h */ +#ifndef SIMDJSON_ARM64_ONDEMAND_H +#define SIMDJSON_ARM64_ONDEMAND_H + +/* including simdjson/arm64/begin.h: #include "simdjson/arm64/begin.h" */ +/* begin file simdjson/arm64/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "arm64" */ +#define SIMDJSON_IMPLEMENTATION arm64 +/* including simdjson/arm64/base.h: #include "simdjson/arm64/base.h" */ +/* begin file simdjson/arm64/base.h */ +#ifndef SIMDJSON_ARM64_BASE_H +#define SIMDJSON_ARM64_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Implementation for NEON (ARMv8). + */ +namespace arm64 { + +class implementation; + +namespace { +namespace simd { +template struct simd8; +template struct simd8x64; +} // namespace simd +} // unnamed namespace + +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_BASE_H +/* end file simdjson/arm64/base.h */ +/* including simdjson/arm64/intrinsics.h: #include "simdjson/arm64/intrinsics.h" */ +/* begin file simdjson/arm64/intrinsics.h */ +#ifndef SIMDJSON_ARM64_INTRINSICS_H +#define SIMDJSON_ARM64_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This should be the correct header whether +// you use visual studio or other compilers. +#include + +static_assert(sizeof(uint8x16_t) <= simdjson::SIMDJSON_PADDING, "insufficient padding for arm64"); + +#endif // SIMDJSON_ARM64_INTRINSICS_H +/* end file simdjson/arm64/intrinsics.h */ +/* including simdjson/arm64/bitmanipulation.h: #include "simdjson/arm64/bitmanipulation.h" */ +/* begin file simdjson/arm64/bitmanipulation.h */ +#ifndef SIMDJSON_ARM64_BITMANIPULATION_H +#define SIMDJSON_ARM64_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num-1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int count_ones(uint64_t input_num) { + return vaddv_u8(vcnt_u8(vcreate_u8(input_num))); +} + + +#if defined(__GNUC__) // catches clang and gcc +/** + * ARM has a fast 64-bit "bit reversal function" that is handy. However, + * it is not generally available as an intrinsic function under Visual + * Studio (though this might be changing). Even under clang/gcc, we + * apparently need to invoke inline assembly. + */ +/* + * We use SIMDJSON_PREFER_REVERSE_BITS as a hint that algorithms that + * work well with bit reversal may use it. + */ +#define SIMDJSON_PREFER_REVERSE_BITS 1 + +/* reverse the bits */ +simdjson_inline uint64_t reverse_bits(uint64_t input_num) { + uint64_t rev_bits; + __asm("rbit %0, %1" : "=r"(rev_bits) : "r"(input_num)); + return rev_bits; +} + +/** + * Flips bit at index 63 - lz. Thus if you have 'leading_zeroes' leading zeroes, + * then this will set to zero the leading bit. It is possible for leading_zeroes to be + * greating or equal to 63 in which case we trigger undefined behavior, but the output + * of such undefined behavior is never used. + **/ +SIMDJSON_NO_SANITIZE_UNDEFINED +simdjson_inline uint64_t zero_leading_bit(uint64_t rev_bits, int leading_zeroes) { + return rev_bits ^ (uint64_t(0x8000000000000000) >> leading_zeroes); +} + +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + *result = value1 + value2; + return *result < value1; +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_BITMANIPULATION_H +/* end file simdjson/arm64/bitmanipulation.h */ +/* including simdjson/arm64/bitmask.h: #include "simdjson/arm64/bitmask.h" */ +/* begin file simdjson/arm64/bitmask.h */ +#ifndef SIMDJSON_ARM64_BITMASK_H +#define SIMDJSON_ARM64_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(uint64_t bitmask) { + ///////////// + // We could do this with PMULL, but it is apparently slow. + // + //#ifdef __ARM_FEATURE_CRYPTO // some ARM processors lack this extension + //return vmull_p64(-1ULL, bitmask); + //#else + // Analysis by @sebpop: + // When diffing the assembly for src/stage1_find_marks.cpp I see that the eors are all spread out + // in between other vector code, so effectively the extra cycles of the sequence do not matter + // because the GPR units are idle otherwise and the critical path is on the FP side. + // Also the PMULL requires two extra fmovs: GPR->FP (3 cycles in N1, 5 cycles in A72 ) + // and FP->GPR (2 cycles on N1 and 5 cycles on A72.) + /////////// + bitmask ^= bitmask << 1; + bitmask ^= bitmask << 2; + bitmask ^= bitmask << 4; + bitmask ^= bitmask << 8; + bitmask ^= bitmask << 16; + bitmask ^= bitmask << 32; + return bitmask; +} + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif +/* end file simdjson/arm64/bitmask.h */ +/* including simdjson/arm64/numberparsing_defs.h: #include "simdjson/arm64/numberparsing_defs.h" */ +/* begin file simdjson/arm64/numberparsing_defs.h */ +#ifndef SIMDJSON_ARM64_NUMBERPARSING_DEFS_H +#define SIMDJSON_ARM64_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +#if _M_ARM64 +// __umulh requires intrin.h +#include +#endif // _M_ARM64 + +namespace simdjson { +namespace arm64 { +namespace numberparsing { + +// we don't have SSE, so let us use a scalar function +// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + uint64_t val; + std::memcpy(&val, chars, sizeof(uint64_t)); + val = (val & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8; + val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16; + return uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32); +} + +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace arm64 +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_ARM64_NUMBERPARSING_DEFS_H +/* end file simdjson/arm64/numberparsing_defs.h */ +/* including simdjson/arm64/simd.h: #include "simdjson/arm64/simd.h" */ +/* begin file simdjson/arm64/simd.h */ +#ifndef SIMDJSON_ARM64_SIMD_H +#define SIMDJSON_ARM64_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { +namespace simd { + +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO +namespace { +// Start of private section with Visual Studio workaround + + +#ifndef simdjson_make_uint8x16_t +#define simdjson_make_uint8x16_t(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \ + x13, x14, x15, x16) \ + ([=]() { \ + uint8_t array[16] = {x1, x2, x3, x4, x5, x6, x7, x8, \ + x9, x10, x11, x12, x13, x14, x15, x16}; \ + return vld1q_u8(array); \ + }()) +#endif +#ifndef simdjson_make_int8x16_t +#define simdjson_make_int8x16_t(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \ + x13, x14, x15, x16) \ + ([=]() { \ + int8_t array[16] = {x1, x2, x3, x4, x5, x6, x7, x8, \ + x9, x10, x11, x12, x13, x14, x15, x16}; \ + return vld1q_s8(array); \ + }()) +#endif + +#ifndef simdjson_make_uint8x8_t +#define simdjson_make_uint8x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + uint8_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1_u8(array); \ + }()) +#endif +#ifndef simdjson_make_int8x8_t +#define simdjson_make_int8x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + int8_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1_s8(array); \ + }()) +#endif +#ifndef simdjson_make_uint16x8_t +#define simdjson_make_uint16x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + uint16_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1q_u16(array); \ + }()) +#endif +#ifndef simdjson_make_int16x8_t +#define simdjson_make_int16x8_t(x1, x2, x3, x4, x5, x6, x7, x8) \ + ([=]() { \ + int16_t array[8] = {x1, x2, x3, x4, x5, x6, x7, x8}; \ + return vld1q_s16(array); \ + }()) +#endif + +// End of private section with Visual Studio workaround +} // namespace +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO + + + template + struct simd8; + + // + // Base class of simd8 and simd8, both of which use uint8x16_t internally. + // + template> + struct base_u8 { + uint8x16_t value; + static const int SIZE = sizeof(value); + + // Conversion from/to SIMD register + simdjson_inline base_u8(const uint8x16_t _value) : value(_value) {} + simdjson_inline operator const uint8x16_t&() const { return this->value; } + simdjson_inline operator uint8x16_t&() { return this->value; } + + // Bit operations + simdjson_inline simd8 operator|(const simd8 other) const { return vorrq_u8(*this, other); } + simdjson_inline simd8 operator&(const simd8 other) const { return vandq_u8(*this, other); } + simdjson_inline simd8 operator^(const simd8 other) const { return veorq_u8(*this, other); } + simdjson_inline simd8 bit_andnot(const simd8 other) const { return vbicq_u8(*this, other); } + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + simdjson_inline simd8& operator|=(const simd8 other) { auto this_cast = static_cast*>(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline simd8& operator&=(const simd8 other) { auto this_cast = static_cast*>(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline simd8& operator^=(const simd8 other) { auto this_cast = static_cast*>(this); *this_cast = *this_cast ^ other; return *this_cast; } + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return vceqq_u8(lhs, rhs); } + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return vextq_u8(prev_chunk, *this, 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base_u8 { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + static simdjson_inline simd8 splat(bool _value) { return vmovq_n_u8(uint8_t(-(!!_value))); } + + simdjson_inline simd8(const uint8x16_t _value) : base_u8(_value) {} + // False constructor + simdjson_inline simd8() : simd8(vdupq_n_u8(0)) {} + // Splat constructor + simdjson_inline simd8(bool _value) : simd8(splat(_value)) {} + + // We return uint32_t instead of uint16_t because that seems to be more efficient for most + // purposes (cutting it down to uint16_t costs performance in some compilers). + simdjson_inline uint32_t to_bitmask() const { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + const uint8x16_t bit_mask = simdjson_make_uint8x16_t(0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80); +#else + const uint8x16_t bit_mask = {0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80}; +#endif + auto minput = *this & bit_mask; + uint8x16_t tmp = vpaddq_u8(minput, minput); + tmp = vpaddq_u8(tmp, tmp); + tmp = vpaddq_u8(tmp, tmp); + return vgetq_lane_u16(vreinterpretq_u16_u8(tmp), 0); + } + simdjson_inline bool any() const { return vmaxvq_u8(*this) != 0; } + }; + + // Unsigned bytes + template<> + struct simd8: base_u8 { + static simdjson_inline uint8x16_t splat(uint8_t _value) { return vmovq_n_u8(_value); } + static simdjson_inline uint8x16_t zero() { return vdupq_n_u8(0); } + static simdjson_inline uint8x16_t load(const uint8_t* values) { return vld1q_u8(values); } + + simdjson_inline simd8(const uint8x16_t _value) : base_u8(_value) {} + // Zero constructor + simdjson_inline simd8() : simd8(zero()) {} + // Array constructor + simdjson_inline simd8(const uint8_t values[16]) : simd8(load(values)) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Member-by-member initialization +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(simdjson_make_uint8x16_t( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} +#else + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(uint8x16_t{ + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + }) {} +#endif + + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Store to array + simdjson_inline void store(uint8_t dst[16]) const { return vst1q_u8(dst, *this); } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return vqaddq_u8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return vqsubq_u8(*this, other); } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return vaddq_u8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return vsubq_u8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *this; } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *this; } + + // Order-specific operations + simdjson_inline uint8_t max_val() const { return vmaxvq_u8(*this); } + simdjson_inline uint8_t min_val() const { return vminvq_u8(*this); } + simdjson_inline simd8 max_val(const simd8 other) const { return vmaxq_u8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return vminq_u8(*this, other); } + simdjson_inline simd8 operator<=(const simd8 other) const { return vcleq_u8(*this, other); } + simdjson_inline simd8 operator>=(const simd8 other) const { return vcgeq_u8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return vcltq_u8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return vcgtq_u8(*this, other); } + // Same as >, but instead of guaranteeing all 1's == true, false = 0 and true = nonzero. For ARM, returns all 1's. + simdjson_inline simd8 gt_bits(const simd8 other) const { return simd8(*this > other); } + // Same as <, but instead of guaranteeing all 1's == true, false = 0 and true = nonzero. For ARM, returns all 1's. + simdjson_inline simd8 lt_bits(const simd8 other) const { return simd8(*this < other); } + + // Bit-specific operations + simdjson_inline simd8 any_bits_set(simd8 bits) const { return vtstq_u8(*this, bits); } + simdjson_inline bool any_bits_set_anywhere() const { return this->max_val() != 0; } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return (*this & bits).any_bits_set_anywhere(); } + template + simdjson_inline simd8 shr() const { return vshrq_n_u8(*this, N); } + template + simdjson_inline simd8 shl() const { return vshlq_n_u8(*this, N); } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return lookup_table.apply_lookup_16_to(*this); + } + + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 16 - count_ones(mask) bytes of the result are significant but 16 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint16_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + uint64x2_t shufmask64 = {thintable_epi8[mask1], thintable_epi8[mask2]}; + uint8x16_t shufmask = vreinterpretq_u8_u64(shufmask64); + // we increment by 0x08 the second half of the mask +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + uint8x16_t inc = simdjson_make_uint8x16_t(0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08); +#else + uint8x16_t inc = {0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; +#endif + shufmask = vaddq_u8(shufmask, inc); + // this is the version "nearly pruned" + uint8x16_t pruned = vqtbl1q_u8(*this, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + uint8x16_t compactmask = vld1q_u8(reinterpret_cast(pshufb_combine_table + pop1 * 8)); + uint8x16_t answer = vqtbl1q_u8(pruned, compactmask); + vst1q_u8(reinterpret_cast(output), answer); + } + + // Copies all bytes corresponding to a 0 in the low half of the mask (interpreted as a + // bitset) to output1, then those corresponding to a 0 in the high half to output2. + template + simdjson_inline void compress_halves(uint16_t mask, L *output1, L *output2) const { + using internal::thintable_epi8; + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + uint8x8_t compactmask1 = vcreate_u8(thintable_epi8[mask1]); + uint8x8_t compactmask2 = vcreate_u8(thintable_epi8[mask2]); + // we increment by 0x08 the second half of the mask +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + uint8x8_t inc = simdjson_make_uint8x8_t(0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08); +#else + uint8x8_t inc = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; +#endif + compactmask2 = vadd_u8(compactmask2, inc); + // store each result (with the second store possibly overlapping the first) + vst1_u8((uint8_t*)output1, vqtbl1_u8(*this, compactmask1)); + vst1_u8((uint8_t*)output2, vqtbl1_u8(*this, compactmask2)); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + + template + simdjson_inline simd8 apply_lookup_16_to(const simd8 original) { + return vqtbl1q_u8(*this, simd8(original)); + } + }; + + // Signed bytes + template<> + struct simd8 { + int8x16_t value; + + static simdjson_inline simd8 splat(int8_t _value) { return vmovq_n_s8(_value); } + static simdjson_inline simd8 zero() { return vdupq_n_s8(0); } + static simdjson_inline simd8 load(const int8_t values[16]) { return vld1q_s8(values); } + + // Conversion from/to SIMD register + simdjson_inline simd8(const int8x16_t _value) : value{_value} {} + simdjson_inline operator const int8x16_t&() const { return this->value; } + simdjson_inline operator int8x16_t&() { return this->value; } + + // Zero constructor + simdjson_inline simd8() : simd8(zero()) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {} + // Member-by-member initialization +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(simdjson_make_int8x16_t( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} +#else + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(int8x16_t{ + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + }) {} +#endif + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Store to array + simdjson_inline void store(int8_t dst[16]) const { return vst1q_s8(dst, *this); } + + // Explicit conversion to/from unsigned + // + // Under Visual Studio/ARM64 uint8x16_t and int8x16_t are apparently the same type. + // In theory, we could check this occurrence with std::same_as and std::enabled_if but it is C++14 + // and relatively ugly and hard to read. +#ifndef SIMDJSON_REGULAR_VISUAL_STUDIO + simdjson_inline explicit simd8(const uint8x16_t other): simd8(vreinterpretq_s8_u8(other)) {} +#endif + simdjson_inline explicit operator simd8() const { return vreinterpretq_u8_s8(this->value); } + + // Math + simdjson_inline simd8 operator+(const simd8 other) const { return vaddq_s8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return vsubq_s8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *this; } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *this; } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return vmaxq_s8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return vminq_s8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return vcgtq_s8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return vcltq_s8(*this, other); } + simdjson_inline simd8 operator==(const simd8 other) const { return vceqq_s8(*this, other); } + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return vextq_s8(prev_chunk, *this, 16 - N); + } + + // Perform a lookup assuming no value is larger than 16 + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return lookup_table.apply_lookup_16_to(*this); + } + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + + template + simdjson_inline simd8 apply_lookup_16_to(const simd8 original) { + return vqtbl1q_s8(*this, simd8(original)); + } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, "ARM kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, const simd8 chunk2, const simd8 chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+16), simd8::load(ptr+32), simd8::load(ptr+48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + this->chunks[2].store(ptr+sizeof(simd8)*2); + this->chunks[3].store(ptr+sizeof(simd8)*3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | (this->chunks[2] | this->chunks[3]); + } + + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + uint64_t popcounts = vget_lane_u64(vreinterpret_u64_u8(vcnt_u8(vcreate_u8(~mask))), 0); + // compute the prefix sum of the popcounts of each byte + uint64_t offsets = popcounts * 0x0101010101010101; + this->chunks[0].compress_halves(uint16_t(mask), output, &output[popcounts & 0xFF]); + this->chunks[1].compress_halves(uint16_t(mask >> 16), &output[(offsets >> 8) & 0xFF], &output[(offsets >> 16) & 0xFF]); + this->chunks[2].compress_halves(uint16_t(mask >> 32), &output[(offsets >> 24) & 0xFF], &output[(offsets >> 32) & 0xFF]); + this->chunks[3].compress_halves(uint16_t(mask >> 48), &output[(offsets >> 40) & 0xFF], &output[(offsets >> 48) & 0xFF]); + return offsets >> 56; + } + + simdjson_inline uint64_t to_bitmask() const { +#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO + const uint8x16_t bit_mask = simdjson_make_uint8x16_t( + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 + ); +#else + const uint8x16_t bit_mask = { + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, + 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 + }; +#endif + // Add each of the elements next to each other, successively, to stuff each 8 byte mask into one. + uint8x16_t sum0 = vpaddq_u8(this->chunks[0] & bit_mask, this->chunks[1] & bit_mask); + uint8x16_t sum1 = vpaddq_u8(this->chunks[2] & bit_mask, this->chunks[3] & bit_mask); + sum0 = vpaddq_u8(sum0, sum1); + sum0 = vpaddq_u8(sum0, sum0); + return vgetq_lane_u64(vreinterpretq_u64_u8(sum0), 0); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask, + this->chunks[2] == mask, + this->chunks[3] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask, + this->chunks[2] <= mask, + this->chunks[3] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_SIMD_H +/* end file simdjson/arm64/simd.h */ +/* including simdjson/arm64/stringparsing_defs.h: #include "simdjson/arm64/stringparsing_defs.h" */ +/* begin file simdjson/arm64/stringparsing_defs.h */ +#ifndef SIMDJSON_ARM64_STRINGPARSING_DEFS_H +#define SIMDJSON_ARM64_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/simd.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return bs_bits != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 31 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v0(src); + simd8 v1(src + sizeof(v0)); + v0.store(dst); + v1.store(dst + sizeof(v0)); + + // Getting a 64-bit bitmask is much cheaper than multiple 16-bit bitmasks on ARM; therefore, we + // smash them together into a 64-byte mask and get the bitmask from there. + uint64_t bs_and_quote = simd8x64(v0 == '\\', v1 == '\\', v0 == '"', v1 == '"').to_bitmask(); + return { + uint32_t(bs_and_quote), // bs_bits + uint32_t(bs_and_quote >> 32) // quote_bits + }; +} + +} // unnamed namespace +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_ARM64_STRINGPARSING_DEFS_H +/* end file simdjson/arm64/stringparsing_defs.h */ + +#define SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT 1 +/* end file simdjson/arm64/begin.h */ +/* including simdjson/generic/ondemand/amalgamated.h for arm64: #include "simdjson/generic/ondemand/amalgamated.h" */ +/* begin file simdjson/generic/ondemand/amalgamated.h for arm64 */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H) +#error simdjson/generic/ondemand/dependencies.h must be included before simdjson/generic/ondemand/amalgamated.h! +#endif + +// Stuff other things depend on +/* including simdjson/generic/ondemand/base.h for arm64: #include "simdjson/generic/ondemand/base.h" */ +/* begin file simdjson/generic/ondemand/base.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +/** + * A fast, simple, DOM-like interface that parses JSON as you use it. + * + * Designed for maximum speed and a lower memory profile. + */ +namespace ondemand { + +/** Represents the depth of a JSON value (number of nested arrays/objects). */ +using depth_t = int32_t; + +/** @copydoc simdjson::arm64::number_type */ +using number_type = simdjson::arm64::number_type; + +/** @private Position in the JSON buffer indexes */ +using token_position = const uint32_t *; + +class array; +class array_iterator; +class document; +class document_reference; +class document_stream; +class field; +class json_iterator; +enum class json_type; +struct number; +class object; +class object_iterator; +class parser; +class raw_json_string; +class token_iterator; +class value; +class value_iterator; + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_BASE_H +/* end file simdjson/generic/ondemand/base.h for arm64 */ +/* including simdjson/generic/ondemand/value_iterator.h for arm64: #include "simdjson/generic/ondemand/value_iterator.h" */ +/* begin file simdjson/generic/ondemand/value_iterator.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +/** + * Iterates through a single JSON value at a particular depth. + * + * Does not keep track of the type of value: provides methods for objects, arrays and scalars and expects + * the caller to call the right ones. + * + * @private This is not intended for external use. + */ +class value_iterator { +protected: + /** The underlying JSON iterator */ + json_iterator *_json_iter{}; + /** The depth of this value */ + depth_t _depth{}; + /** + * The starting token index for this value + */ + token_position _start_position{}; + +public: + simdjson_inline value_iterator() noexcept = default; + + /** + * Denote that we're starting a document. + */ + simdjson_inline void start_document() noexcept; + + /** + * Skips a non-iterated or partially-iterated JSON value, whether it is a scalar, array or object. + * + * Optimized for scalars. + */ + simdjson_warn_unused simdjson_inline error_code skip_child() noexcept; + + /** + * Tell whether the iterator is at the EOF mark + */ + simdjson_inline bool at_end() const noexcept; + + /** + * Tell whether the iterator is at the start of the value + */ + simdjson_inline bool at_start() const noexcept; + + /** + * Tell whether the value is open--if the value has not been used, or the array/object is still open. + */ + simdjson_inline bool is_open() const noexcept; + + /** + * Tell whether the value is at an object's first field (just after the {). + */ + simdjson_inline bool at_first_field() const noexcept; + + /** + * Abandon all iteration. + */ + simdjson_inline void abandon() noexcept; + + /** + * Get the child value as a value_iterator. + */ + simdjson_inline value_iterator child_value() const noexcept; + + /** + * Get the depth of this value. + */ + simdjson_inline int32_t depth() const noexcept; + + /** + * Get the JSON type of this value. + * + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() const noexcept; + + /** + * @addtogroup object Object iteration + * + * Methods to iterate and find object fields. These methods generally *assume* the value is + * actually an object; the caller is responsible for keeping track of that fact. + * + * @{ + */ + + /** + * Start an object iteration. + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCORRECT_TYPE if there is no opening { + */ + simdjson_warn_unused simdjson_inline simdjson_result start_object() noexcept; + /** + * Start an object iteration from the root. + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCORRECT_TYPE if there is no opening { + * @error TAPE_ERROR if there is no matching } at end of document + */ + simdjson_warn_unused simdjson_inline simdjson_result start_root_object() noexcept; + /** + * Checks whether an object could be started from the root. May be called by start_root_object. + * + * @returns SUCCESS if it is possible to safely start an object from the root (document level). + * @error INCORRECT_TYPE if there is no opening { + * @error TAPE_ERROR if there is no matching } at end of document + */ + simdjson_warn_unused simdjson_inline error_code check_root_object() noexcept; + /** + * Start an object iteration after the user has already checked and moved past the {. + * + * Does not move the iterator unless the object is empty ({}). + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_object() noexcept; + /** + * Start an object iteration from the root, after the user has already checked and moved past the {. + * + * Does not move the iterator unless the object is empty ({}). + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_root_object() noexcept; + + /** + * Moves to the next field in an object. + * + * Looks for , and }. If } is found, the object is finished and the iterator advances past it. + * Otherwise, it advances to the next value. + * + * @return whether there is another field in the object. + * @error TAPE_ERROR If there is a comma missing between fields. + * @error TAPE_ERROR If there is a comma, but not enough tokens remaining to have a key, :, and value. + */ + simdjson_warn_unused simdjson_inline simdjson_result has_next_field() noexcept; + + /** + * Get the current field's key. + */ + simdjson_warn_unused simdjson_inline simdjson_result field_key() noexcept; + + /** + * Pass the : in the field and move to its value. + */ + simdjson_warn_unused simdjson_inline error_code field_value() noexcept; + + /** + * Find the next field with the given key. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline error_code find_field(const std::string_view key) noexcept; + + /** + * Find the next field with the given key, *without* unescaping. This assumes object order: it + * will not find the field if it was already passed when looking for some *other* field. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline simdjson_result find_field_raw(const std::string_view key) noexcept; + + /** + * Find the field with the given key without regard to order, and *without* unescaping. + * + * This is an unordered object lookup: if the field is not found initially, it will cycle around and scan from the beginning. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline simdjson_result find_field_unordered_raw(const std::string_view key) noexcept; + + /** @} */ + + /** + * @addtogroup array Array iteration + * Methods to iterate over array elements. These methods generally *assume* the value is actually + * an object; the caller is responsible for keeping track of that fact. + * @{ + */ + + /** + * Check for an opening [ and start an array iteration. + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCORRECT_TYPE If there is no [. + */ + simdjson_warn_unused simdjson_inline simdjson_result start_array() noexcept; + /** + * Check for an opening [ and start an array iteration while at the root. + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCORRECT_TYPE If there is no [. + * @error TAPE_ERROR if there is no matching ] at end of document + */ + simdjson_warn_unused simdjson_inline simdjson_result start_root_array() noexcept; + /** + * Checks whether an array could be started from the root. May be called by start_root_array. + * + * @returns SUCCESS if it is possible to safely start an array from the root (document level). + * @error INCORRECT_TYPE If there is no [. + * @error TAPE_ERROR if there is no matching ] at end of document + */ + simdjson_warn_unused simdjson_inline error_code check_root_array() noexcept; + /** + * Start an array iteration, after the user has already checked and moved past the [. + * + * Does not move the iterator unless the array is empty ([]). + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_array() noexcept; + /** + * Start an array iteration from the root, after the user has already checked and moved past the [. + * + * Does not move the iterator unless the array is empty ([]). + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_root_array() noexcept; + + /** + * Moves to the next element in an array. + * + * Looks for , and ]. If ] is found, the array is finished and the iterator advances past it. + * Otherwise, it advances to the next value. + * + * @return Whether there is another element in the array. + * @error TAPE_ERROR If there is a comma missing between elements. + */ + simdjson_warn_unused simdjson_inline simdjson_result has_next_element() noexcept; + + /** + * Get a child value iterator. + */ + simdjson_warn_unused simdjson_inline value_iterator child() const noexcept; + + /** @} */ + + /** + * @defgroup scalar Scalar values + * @addtogroup scalar + * @{ + */ + + simdjson_warn_unused simdjson_inline simdjson_result get_string(bool allow_replacement) noexcept; + template + simdjson_warn_unused simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_int64() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_double() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_bool() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_null() noexcept; + simdjson_warn_unused simdjson_inline bool is_negative() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_integer() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + simdjson_warn_unused simdjson_inline simdjson_result get_root_string(bool check_trailing, bool allow_replacement) noexcept; + template + simdjson_warn_unused simdjson_inline error_code get_root_string(string_type& receiver, bool check_trailing, bool allow_replacement) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_wobbly_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_raw_json_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_uint64(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_uint64_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_int64(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_int64_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_double(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_double_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_bool(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline bool is_root_negative() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_root_integer(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_number_type(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_number(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_root_null(bool check_trailing) noexcept; + + simdjson_inline error_code error() const noexcept; + simdjson_inline uint8_t *&string_buf_loc() noexcept; + simdjson_inline const json_iterator &json_iter() const noexcept; + simdjson_inline json_iterator &json_iter() noexcept; + + simdjson_inline void assert_is_valid() const noexcept; + simdjson_inline bool is_valid() const noexcept; + + /** @} */ +protected: + /** + * Restarts an array iteration. + * @returns Whether the array has any elements (returns false for empty). + */ + simdjson_inline simdjson_result reset_array() noexcept; + /** + * Restarts an object iteration. + * @returns Whether the object has any fields (returns false for empty). + */ + simdjson_inline simdjson_result reset_object() noexcept; + /** + * move_at_start(): moves us so that we are pointing at the beginning of + * the container. It updates the index so that at_start() is true and it + * syncs the depth. The user can then create a new container instance. + * + * Usage: used with value::count_elements(). + **/ + simdjson_inline void move_at_start() noexcept; + + /** + * move_at_container_start(): moves us so that we are pointing at the beginning of + * the container so that assert_at_container_start() passes. + * + * Usage: used with reset_array() and reset_object(). + **/ + simdjson_inline void move_at_container_start() noexcept; + /* Useful for debugging and logging purposes. */ + inline std::string to_string() const noexcept; + simdjson_inline value_iterator(json_iterator *json_iter, depth_t depth, token_position start_index) noexcept; + + simdjson_inline simdjson_result parse_null(const uint8_t *json) const noexcept; + simdjson_inline simdjson_result parse_bool(const uint8_t *json) const noexcept; + simdjson_inline const uint8_t *peek_start() const noexcept; + simdjson_inline uint32_t peek_start_length() const noexcept; + + /** + * The general idea of the advance_... methods and the peek_* methods + * is that you first peek and check that you have desired type. If you do, + * and only if you do, then you advance. + * + * We used to unconditionally advance. But this made reasoning about our + * current state difficult. + * Suppose you always advance. Look at the 'value' matching the key + * "shadowable" in the following example... + * + * ({"globals":{"a":{"shadowable":[}}}}) + * + * If the user thinks it is a Boolean and asks for it, then we check the '[', + * decide it is not a Boolean, but still move into the next character ('}'). Now + * we are left pointing at '}' right after a '['. And we have not yet reported + * an error, only that we do not have a Boolean. + * + * If, instead, you just stand your ground until it is content that you know, then + * you will only even move beyond the '[' if the user tells you that you have an + * array. So you will be at the '}' character inside the array and, hopefully, you + * will then catch the error because an array cannot start with '}', but the code + * processing Boolean values does not know this. + * + * So the contract is: first call 'peek_...' and then call 'advance_...' only + * if you have determined that it is a type you can handle. + * + * Unfortunately, it makes the code more verbose, longer and maybe more error prone. + */ + + simdjson_inline void advance_scalar(const char *type) noexcept; + simdjson_inline void advance_root_scalar(const char *type) noexcept; + simdjson_inline void advance_non_root_scalar(const char *type) noexcept; + + simdjson_inline const uint8_t *peek_scalar(const char *type) noexcept; + simdjson_inline const uint8_t *peek_root_scalar(const char *type) noexcept; + simdjson_inline const uint8_t *peek_non_root_scalar(const char *type) noexcept; + + + simdjson_inline error_code start_container(uint8_t start_char, const char *incorrect_type_message, const char *type) noexcept; + simdjson_inline error_code end_container() noexcept; + + /** + * Advance to a place expecting a value (increasing depth). + * + * @return The current token (the one left behind). + * @error TAPE_ERROR If the document ended early. + */ + simdjson_inline simdjson_result advance_to_value() noexcept; + + simdjson_inline error_code incorrect_type_error(const char *message) const noexcept; + simdjson_inline error_code error_unless_more_tokens(uint32_t tokens=1) const noexcept; + + simdjson_inline bool is_at_start() const noexcept; + /** + * is_at_iterator_start() returns true on an array or object after it has just been + * created, whether the instance is empty or not. + * + * Usage: used by array::begin() in debug mode (SIMDJSON_DEVELOPMENT_CHECKS) + */ + simdjson_inline bool is_at_iterator_start() const noexcept; + + /** + * Assuming that we are within an object, this returns true if we + * are pointing at a key. + * + * Usage: the skip_child() method should never be used while we are pointing + * at a key inside an object. + */ + simdjson_inline bool is_at_key() const noexcept; + + inline void assert_at_start() const noexcept; + inline void assert_at_container_start() const noexcept; + inline void assert_at_root() const noexcept; + inline void assert_at_child() const noexcept; + inline void assert_at_next() const noexcept; + inline void assert_at_non_root_start() const noexcept; + + /** Get the starting position of this value */ + simdjson_inline token_position start_position() const noexcept; + + /** @copydoc error_code json_iterator::position() const noexcept; */ + simdjson_inline token_position position() const noexcept; + /** @copydoc error_code json_iterator::end_position() const noexcept; */ + simdjson_inline token_position last_position() const noexcept; + /** @copydoc error_code json_iterator::end_position() const noexcept; */ + simdjson_inline token_position end_position() const noexcept; + /** @copydoc error_code json_iterator::report_error(error_code error, const char *message) noexcept; */ + simdjson_inline error_code report_error(error_code error, const char *message) noexcept; + + friend class document; + friend class object; + friend class array; + friend class value; +}; // value_iterator + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::value_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H +/* end file simdjson/generic/ondemand/value_iterator.h for arm64 */ +/* including simdjson/generic/ondemand/value.h for arm64: #include "simdjson/generic/ondemand/value.h" */ +/* begin file simdjson/generic/ondemand/value.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +/** + * An ephemeral JSON value returned during iteration. It is only valid for as long as you do + * not access more data in the JSON document. + */ +class value { +public: + /** + * Create a new invalid value. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline value() noexcept = default; + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * You may use get_double(), get_bool(), get_uint64(), get_int64(), + * get_object(), get_array(), get_raw_json_string(), or get_string() instead. + * + * @returns A value of the given type, parsed from the JSON. + * @returns INCORRECT_TYPE If the JSON value is not the given type. + */ + template simdjson_inline simdjson_result get() noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * @param out This is set to a value of the given type, parsed from the JSON. If there is an error, this may not be initialized. + * @returns INCORRECT_TYPE If the JSON value is not an object. + * @returns SUCCESS If the parse succeeded and the out parameter was set to the value. + */ + template simdjson_inline error_code get(T &out) noexcept; + + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result get_array() noexcept; + + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @returns INCORRECT_TYPE If the JSON value is not an object. + */ + simdjson_inline simdjson_result get_object() noexcept; + + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A unsigned 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64() noexcept; + + /** + * Cast this JSON value (inside string) to a unsigned integer. + * + * @returns A unsigned 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64() noexcept; + + /** + * Cast this JSON value (inside string) to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64_in_string() noexcept; + + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double() noexcept; + + /** + * Cast this JSON value (inside string) to a double + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double_in_string() noexcept; + + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Equivalent to get(). + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + + /** + * Attempts to fill the provided std::string reference with the parsed value of the current string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory. + * We recommend you avoid allocating an std::string unless you need to. + * + * @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS. + */ + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + + /** + * Cast this JSON value to a "wobbly" string. + * + * The string is may not be a valid UTF-8 string. + * See https://simonsapin.github.io/wtf-8/ + * + * Important: a value should be consumed once. Calling get_wobbly_string() twice on the same value + * is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_wobbly_string() noexcept; + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_raw_json_string() noexcept; + + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @returns INCORRECT_TYPE if the JSON value is not true or false. + */ + simdjson_inline simdjson_result get_bool() noexcept; + + /** + * Checks if this JSON value is null. If and only if the value is + * null, then it is consumed (we advance). If we find a token that + * begins with 'n' but is not 'null', then an error is returned. + * + * @returns Whether the value is null. + * @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'. + */ + simdjson_inline simdjson_result is_null() noexcept; + +#if SIMDJSON_EXCEPTIONS + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an array. + */ + simdjson_inline operator array() noexcept(false); + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an object. + */ + simdjson_inline operator object() noexcept(false); + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline operator uint64_t() noexcept(false); + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer. + */ + simdjson_inline operator int64_t() noexcept(false); + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number. + */ + simdjson_inline operator double() noexcept(false); + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Equivalent to get(). + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator std::string_view() noexcept(false); + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator raw_json_string() noexcept(false); + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false. + */ + simdjson_inline operator bool() noexcept(false); +#endif + + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + * + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result begin() & noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() & noexcept; + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * Performance hint: You should only call count_elements() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method on the object instance. + * + * Performance hint: You should only call count_fields() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Get the value at the given index in the array. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) noexcept; + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) noexcept; + + /** + * Get the type of this JSON value. It does not validate or consume the value. + * E.g., you must still call "is_null()" to check that a value is null even if + * "type()" returns json_type::null. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + * + * @return The type of JSON value (json_type::array, json_type::object, json_type::string, + * json_type::number, json_type::boolean, or json_type::null). + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() noexcept; + + /** + * Checks whether the value is a scalar (string, number, null, Boolean). + * Returns false when there it is an array or object. + * + * @returns true if the type is string, number, null, Boolean + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result is_scalar() noexcept; + + /** + * Checks whether the value is a negative number. + * + * @returns true if the number if negative. + */ + simdjson_inline bool is_negative() noexcept; + /** + * Checks whether the value is an integer number. Note that + * this requires to partially parse the number string. If + * the value is determined to be an integer, it may still + * not parse properly as an integer in subsequent steps + * (e.g., it might overflow). + * + * Performance note: if you call this function systematically + * before parsing a number, you may have fallen for a performance + * anti-pattern. + * + * @returns true if the number if negative. + */ + simdjson_inline simdjson_result is_integer() noexcept; + /** + * Determine the number type (integer or floating-point number) as quickly + * as possible. This function does not fully validate the input. It is + * useful when you only need to classify the numbers, without parsing them. + * + * If you are planning to retrieve the value or you need full validation, + * consider using the get_number() method instead: it will fully parse + * and validate the input, and give you access to the type: + * get_number().get_number_type(). + * + * get_number_type() is number_type::unsigned_integer if we have + * an integer greater or equal to 9223372036854775808 + * get_number_type() is number_type::signed_integer if we have an + * integer that is less than 9223372036854775808 + * Otherwise, get_number_type() has value number_type::floating_point_number + * + * This function requires processing the number string, but it is expected + * to be faster than get_number().get_number_type() because it is does not + * parse the number value. + * + * @returns the type of the number + */ + simdjson_inline simdjson_result get_number_type() noexcept; + + /** + * Attempt to parse an ondemand::number. An ondemand::number may + * contain an integer value or a floating-point value, the simdjson + * library will autodetect the type. Thus it is a dynamically typed + * number. Before accessing the value, you must determine the detected + * type. + * + * number.get_number_type() is number_type::signed_integer if we have + * an integer in [-9223372036854775808,9223372036854775808) + * You can recover the value by calling number.get_int64() and you + * have that number.is_int64() is true. + * + * number.get_number_type() is number_type::unsigned_integer if we have + * an integer in [9223372036854775808,18446744073709551616) + * You can recover the value by calling number.get_uint64() and you + * have that number.is_uint64() is true. + * + * Otherwise, number.get_number_type() has value number_type::floating_point_number + * and we have a binary64 number. + * You can recover the value by calling number.get_double() and you + * have that number.is_double() is true. + * + * You must check the type before accessing the value: it is an error + * to call "get_int64()" when number.get_number_type() is not + * number_type::signed_integer and when number.is_int64() is false. + * + * Performance note: this is designed with performance in mind. When + * calling 'get_number()', you scan the number string only once, determining + * efficiently the type and storing it in an efficient manner. + */ + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + + /** + * Get the raw JSON for this token. + * + * The string_view will always point into the input buffer. + * + * The string_view will start at the beginning of the token, and include the entire token + * *as well as all spaces until the next token (or EOF).* This means, for example, that a + * string token always begins with a " and is always terminated by the final ", possibly + * followed by a number of spaces. + * + * The string_view is *not* null-terminated. However, if this is a scalar (string, number, + * boolean, or null), the character after the end of the string_view is guaranteed to be + * a non-space token. + * + * Tokens include: + * - { + * - [ + * - "a string (possibly with UTF-8 or backslashed characters like \\\")". + * - -1.2e-100 + * - true + * - false + * - null + * + * See also value::raw_json(). + */ + simdjson_inline std::string_view raw_json_token() noexcept; + + /** + * Get a string_view pointing at this value in the JSON document. + * If this element is an array or an object, it consumes the array or the object + * and returns a string_view instance corresponding to the + * array as represented in JSON. It points inside the original document. + * If this element is a scalar (string, number, Boolean, null), it returns what + * raw_json_token() would return. + */ + simdjson_inline simdjson_result raw_json() noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + simdjson_inline simdjson_result current_location() noexcept; + + /** + * Returns the current depth in the document if in bounds. + * + * E.g., + * 0 = finished with document + * 1 = document root value (could be [ or {, not yet known) + * 2 = , or } inside root array/object + * 3 = key or value inside root array/object. + */ + simdjson_inline int32_t current_depth() const noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. + * + * Calling at_pointer() on non-document instances (e.g., arrays and objects) is not + * standardized (by RFC 6901). We provide some experimental support for JSON pointers + * on non-document instances. Yet it is not the case when calling at_pointer on an array + * or an object instance: there is no rewind and no invalidation. + * + * You may only call at_pointer on an array after it has been created, but before it has + * been first accessed. When calling at_pointer on an array, the pointer is advanced to + * the location indicated by the JSON pointer (in case of success). It is no longer possible + * to call at_pointer on the same array. + * + * You may call at_pointer more than once on an object, but each time the pointer is advanced + * to be within the value matched by the key indicated by the JSON pointer query. Thus any preceding + * key (as well as the current key) can no longer be used with following JSON pointer calls. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + +protected: + /** + * Create a value. + */ + simdjson_inline value(const value_iterator &iter) noexcept; + + /** + * Skip this value, allowing iteration to continue. + */ + simdjson_inline void skip() noexcept; + + /** + * Start a value at the current position. + * + * (It should already be started; this is just a self-documentation method.) + */ + static simdjson_inline value start(const value_iterator &iter) noexcept; + + /** + * Resume a value. + */ + static simdjson_inline value resume(const value_iterator &iter) noexcept; + + /** + * Get the object, starting or resuming it as necessary + */ + simdjson_inline simdjson_result start_or_resume_object() noexcept; + + // simdjson_inline void log_value(const char *type) const noexcept; + // simdjson_inline void log_error(const char *message) const noexcept; + + value_iterator iter{}; + + friend class document; + friend class array_iterator; + friend class field; + friend class object; + friend struct simdjson_result; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::value &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result get_array() noexcept; + simdjson_inline simdjson_result get_object() noexcept; + + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + + template simdjson_inline simdjson_result get() noexcept; + + template simdjson_inline error_code get(T &out) noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator arm64::ondemand::array() noexcept(false); + simdjson_inline operator arm64::ondemand::object() noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator arm64::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) noexcept; + + /** + * Get the type of this JSON value. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + */ + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + + /** @copydoc simdjson_inline std::string_view value::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + + /** @copydoc simdjson_inline simdjson_result current_location() noexcept */ + simdjson_inline simdjson_result current_location() noexcept; + /** @copydoc simdjson_inline int32_t current_depth() const noexcept */ + simdjson_inline simdjson_result current_depth() const noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_H +/* end file simdjson/generic/ondemand/value.h for arm64 */ +/* including simdjson/generic/ondemand/logger.h for arm64: #include "simdjson/generic/ondemand/logger.h" */ +/* begin file simdjson/generic/ondemand/logger.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_LOGGER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_LOGGER_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +// Logging should be free unless SIMDJSON_VERBOSE_LOGGING is set. Importantly, it is critical +// that the call to the log functions be side-effect free. Thus, for example, you should not +// create temporary std::string instances. +namespace logger { + +enum class log_level : int32_t { + info = 0, + error = 1 +}; + +#if SIMDJSON_VERBOSE_LOGGING + static constexpr const bool LOG_ENABLED = true; +#else + static constexpr const bool LOG_ENABLED = false; +#endif + +// We do not want these functions to be 'really inlined' since real inlining is +// for performance purposes and if you are using the loggers, you do not care about +// performance (or should not). +static inline void log_headers() noexcept; +// If args are provided, title will be treated as format string +template +static inline void log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +template +static inline void log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; +static inline void log_event(const json_iterator &iter, const char *type, std::string_view detail="", int delta=0, int depth_delta=0) noexcept; +static inline void log_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail="") noexcept; +static inline void log_value(const json_iterator &iter, const char *type, std::string_view detail="", int delta=-1, int depth_delta=0) noexcept; +static inline void log_start_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail="") noexcept; +static inline void log_start_value(const json_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_end_value(const json_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; + +static inline void log_error(const json_iterator &iter, token_position index, depth_t depth, const char *error, const char *detail="") noexcept; +static inline void log_error(const json_iterator &iter, const char *error, const char *detail="", int delta=-1, int depth_delta=0) noexcept; + +static inline void log_event(const value_iterator &iter, const char *type, std::string_view detail="", int delta=0, int depth_delta=0) noexcept; +static inline void log_value(const value_iterator &iter, const char *type, std::string_view detail="", int delta=-1, int depth_delta=0) noexcept; +static inline void log_start_value(const value_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_end_value(const value_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_error(const value_iterator &iter, const char *error, const char *detail="", int delta=-1, int depth_delta=0) noexcept; + +} // namespace logger +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_LOGGER_H +/* end file simdjson/generic/ondemand/logger.h for arm64 */ +/* including simdjson/generic/ondemand/token_iterator.h for arm64: #include "simdjson/generic/ondemand/token_iterator.h" */ +/* begin file simdjson/generic/ondemand/token_iterator.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +/** + * Iterates through JSON tokens (`{` `}` `[` `]` `,` `:` `""` `123` `true` `false` `null`) + * detected by stage 1. + * + * @private This is not intended for external use. + */ +class token_iterator { +public: + /** + * Create a new invalid token_iterator. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline token_iterator() noexcept = default; + simdjson_inline token_iterator(token_iterator &&other) noexcept = default; + simdjson_inline token_iterator &operator=(token_iterator &&other) noexcept = default; + simdjson_inline token_iterator(const token_iterator &other) noexcept = default; + simdjson_inline token_iterator &operator=(const token_iterator &other) noexcept = default; + + /** + * Advance to the next token (returning the current one). + */ + simdjson_inline const uint8_t *return_current_and_advance() noexcept; + /** + * Reports the current offset in bytes from the start of the underlying buffer. + */ + simdjson_inline uint32_t current_offset() const noexcept; + /** + * Get the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(int32_t delta=0) const noexcept; + /** + * Get the maximum length of the JSON text for a given token. + * + * The length will include any whitespace at the end of the token. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_length(int32_t delta=0) const noexcept; + + /** + * Get the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token. + * + */ + simdjson_inline const uint8_t *peek(token_position position) const noexcept; + /** + * Get the maximum length of the JSON text for a given token. + * + * The length will include any whitespace at the end of the token. + * + * @param position The position of the token. + */ + simdjson_inline uint32_t peek_length(token_position position) const noexcept; + + /** + * Return the current index. + */ + simdjson_inline token_position position() const noexcept; + /** + * Reset to a previously saved index. + */ + simdjson_inline void set_position(token_position target_position) noexcept; + + // NOTE: we don't support a full C++ iterator interface, because we expect people to make + // different calls to advance the iterator based on *their own* state. + + simdjson_inline bool operator==(const token_iterator &other) const noexcept; + simdjson_inline bool operator!=(const token_iterator &other) const noexcept; + simdjson_inline bool operator>(const token_iterator &other) const noexcept; + simdjson_inline bool operator>=(const token_iterator &other) const noexcept; + simdjson_inline bool operator<(const token_iterator &other) const noexcept; + simdjson_inline bool operator<=(const token_iterator &other) const noexcept; + +protected: + simdjson_inline token_iterator(const uint8_t *buf, token_position position) noexcept; + + /** + * Get the index of the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_index(int32_t delta=0) const noexcept; + /** + * Get the index of the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token. + * + */ + simdjson_inline uint32_t peek_index(token_position position) const noexcept; + + const uint8_t *buf{}; + token_position _position{}; + + friend class json_iterator; + friend class value_iterator; + friend class object; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +}; + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::token_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H +/* end file simdjson/generic/ondemand/token_iterator.h for arm64 */ +/* including simdjson/generic/ondemand/json_iterator.h for arm64: #include "simdjson/generic/ondemand/json_iterator.h" */ +/* begin file simdjson/generic/ondemand/json_iterator.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +/** + * Iterates through JSON tokens, keeping track of depth and string buffer. + * + * @private This is not intended for external use. + */ +class json_iterator { +protected: + token_iterator token{}; + ondemand::parser *parser{}; + /** + * Next free location in the string buffer. + * + * Used by raw_json_string::unescape() to have a place to unescape strings to. + */ + uint8_t *_string_buf_loc{}; + /** + * JSON error, if there is one. + * + * INCORRECT_TYPE and NO_SUCH_FIELD are *not* stored here, ever. + * + * PERF NOTE: we *hope* this will be elided into control flow, as it is only used (a) in the first + * iteration of the loop, or (b) for the final iteration after a missing comma is found in ++. If + * this is not elided, we should make sure it's at least not using up a register. Failing that, + * we should store it in document so there's only one of them. + */ + error_code error{SUCCESS}; + /** + * Depth of the current token in the JSON. + * + * - 0 = finished with document + * - 1 = document root value (could be [ or {, not yet known) + * - 2 = , or } inside root array/object + * - 3 = key or value inside root array/object. + */ + depth_t _depth{}; + /** + * Beginning of the document indexes. + * Normally we have root == parser->implementation->structural_indexes.get() + * but this may differ, especially in streaming mode (where we have several + * documents); + */ + token_position _root{}; + /** + * Normally, a json_iterator operates over a single document, but in + * some cases, we may have a stream of documents. This attribute is meant + * as meta-data: the json_iterator works the same irrespective of the + * value of this attribute. + */ + bool _streaming{false}; + +public: + simdjson_inline json_iterator() noexcept = default; + simdjson_inline json_iterator(json_iterator &&other) noexcept; + simdjson_inline json_iterator &operator=(json_iterator &&other) noexcept; + simdjson_inline explicit json_iterator(const json_iterator &other) noexcept = default; + simdjson_inline json_iterator &operator=(const json_iterator &other) noexcept = default; + /** + * Skips a JSON value, whether it is a scalar, array or object. + */ + simdjson_warn_unused simdjson_inline error_code skip_child(depth_t parent_depth) noexcept; + + /** + * Tell whether the iterator is still at the start + */ + simdjson_inline bool at_root() const noexcept; + + /** + * Tell whether we should be expected to run in streaming + * mode (iterating over many documents). It is pure metadata + * that does not affect how the iterator works. It is used by + * start_root_array() and start_root_object(). + */ + simdjson_inline bool streaming() const noexcept; + + /** + * Get the root value iterator + */ + simdjson_inline token_position root_position() const noexcept; + /** + * Assert that we are at the document depth (== 1) + */ + simdjson_inline void assert_at_document_depth() const noexcept; + /** + * Assert that we are at the root of the document + */ + simdjson_inline void assert_at_root() const noexcept; + + /** + * Tell whether the iterator is at the EOF mark + */ + simdjson_inline bool at_end() const noexcept; + + /** + * Tell whether the iterator is live (has not been moved). + */ + simdjson_inline bool is_alive() const noexcept; + + /** + * Abandon this iterator, setting depth to 0 (as if the document is finished). + */ + simdjson_inline void abandon() noexcept; + + /** + * Advance the current token without modifying depth. + */ + simdjson_inline const uint8_t *return_current_and_advance() noexcept; + + /** + * Returns true if there is a single token in the index (i.e., it is + * a JSON with a scalar value such as a single number). + * + * @return whether there is a single token + */ + simdjson_inline bool is_single_token() const noexcept; + + /** + * Assert that there are at least the given number of tokens left. + * + * Has no effect in release builds. + */ + simdjson_inline void assert_more_tokens(uint32_t required_tokens=1) const noexcept; + /** + * Assert that the given position addresses an actual token (is within bounds). + * + * Has no effect in release builds. + */ + simdjson_inline void assert_valid_position(token_position position) const noexcept; + /** + * Get the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = next token, -1 = prev token. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(int32_t delta=0) const noexcept; + /** + * Get the maximum length of the JSON text for the current token (or relative). + * + * The length will include any whitespace at the end of the token. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_length(int32_t delta=0) const noexcept; + /** + * Get a pointer to the current location in the input buffer. + * + * This is not null-terminated; it is a view into the JSON. + * + * You may be pointing outside of the input buffer: it is not generally + * safe to dereference this pointer. + */ + simdjson_inline const uint8_t *unsafe_pointer() const noexcept; + /** + * Get the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token to retrieve. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(token_position position) const noexcept; + /** + * Get the maximum length of the JSON text for the current token (or relative). + * + * The length will include any whitespace at the end of the token. + * + * @param position The position of the token to retrieve. + */ + simdjson_inline uint32_t peek_length(token_position position) const noexcept; + /** + * Get the JSON text for the last token in the document. + * + * This is not null-terminated; it is a view into the JSON. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek_last() const noexcept; + + /** + * Ascend one level. + * + * Validates that the depth - 1 == parent_depth. + * + * @param parent_depth the expected parent depth. + */ + simdjson_inline void ascend_to(depth_t parent_depth) noexcept; + + /** + * Descend one level. + * + * Validates that the new depth == child_depth. + * + * @param child_depth the expected child depth. + */ + simdjson_inline void descend_to(depth_t child_depth) noexcept; + simdjson_inline void descend_to(depth_t child_depth, int32_t delta) noexcept; + + /** + * Get current depth. + */ + simdjson_inline depth_t depth() const noexcept; + + /** + * Get current (writeable) location in the string buffer. + */ + simdjson_inline uint8_t *&string_buf_loc() noexcept; + + /** + * Report an unrecoverable error, preventing further iteration. + * + * @param error The error to report. Must not be SUCCESS, UNINITIALIZED, INCORRECT_TYPE, or NO_SUCH_FIELD. + * @param message An error message to report with the error. + */ + simdjson_inline error_code report_error(error_code error, const char *message) noexcept; + + /** + * Log error, but don't stop iteration. + * @param error The error to report. Must be INCORRECT_TYPE, or NO_SUCH_FIELD. + * @param message An error message to report with the error. + */ + simdjson_inline error_code optional_error(error_code error, const char *message) noexcept; + + /** + * Take an input in json containing max_len characters and attempt to copy it over to tmpbuf, a buffer with + * N bytes of capacity. It will return false if N is too small (smaller than max_len) of if it is zero. + * The buffer (tmpbuf) is padded with space characters. + */ + simdjson_warn_unused simdjson_inline bool copy_to_buffer(const uint8_t *json, uint32_t max_len, uint8_t *tmpbuf, size_t N) noexcept; + + simdjson_inline token_position position() const noexcept; + /** + * Write the raw_json_string to the string buffer and return a string_view. + * Each raw_json_string should be unescaped once, or else the string buffer might + * overflow. + */ + simdjson_inline simdjson_result unescape(raw_json_string in, bool allow_replacement) noexcept; + simdjson_inline simdjson_result unescape_wobbly(raw_json_string in) noexcept; + + simdjson_inline void reenter_child(token_position position, depth_t child_depth) noexcept; + + simdjson_inline error_code consume_character(char c) noexcept; +#if SIMDJSON_DEVELOPMENT_CHECKS + simdjson_inline token_position start_position(depth_t depth) const noexcept; + simdjson_inline void set_start_position(depth_t depth, token_position position) noexcept; +#endif + + /* Useful for debugging and logging purposes. */ + inline std::string to_string() const noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + inline simdjson_result current_location() const noexcept; + + /** + * Updates this json iterator so that it is back at the beginning of the document, + * as if it had just been created. + */ + inline void rewind() noexcept; + /** + * This checks whether the {,},[,] are balanced so that the document + * ends with proper zero depth. This requires scanning the whole document + * and it may be expensive. It is expected that it will be rarely called. + * It does not attempt to match { with } and [ with ]. + */ + inline bool balanced() const noexcept; +protected: + simdjson_inline json_iterator(const uint8_t *buf, ondemand::parser *parser) noexcept; + /// The last token before the end + simdjson_inline token_position last_position() const noexcept; + /// The token *at* the end. This points at gibberish and should only be used for comparison. + simdjson_inline token_position end_position() const noexcept; + /// The end of the buffer. + simdjson_inline token_position end() const noexcept; + + friend class document; + friend class document_stream; + friend class object; + friend class array; + friend class value; + friend class raw_json_string; + friend class parser; + friend class value_iterator; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +}; // json_iterator + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::json_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H +/* end file simdjson/generic/ondemand/json_iterator.h for arm64 */ +/* including simdjson/generic/ondemand/json_type.h for arm64: #include "simdjson/generic/ondemand/json_type.h" */ +/* begin file simdjson/generic/ondemand/json_type.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/numberparsing.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +/** + * The type of a JSON value. + */ +enum class json_type { + // Start at 1 to catch uninitialized / default values more easily + array=1, ///< A JSON array ( [ 1, 2, 3 ... ] ) + object, ///< A JSON object ( { "a": 1, "b" 2, ... } ) + number, ///< A JSON number ( 1 or -2.3 or 4.5e6 ...) + string, ///< A JSON string ( "a" or "hello world\n" ...) + boolean, ///< A JSON boolean (true or false) + null ///< A JSON null (null) +}; + +/** + * A type representing a JSON number. + * The design of the struct is deliberately straight-forward. All + * functions return standard values with no error check. + */ +struct number { + + /** + * return the automatically determined type of + * the number: number_type::floating_point_number, + * number_type::signed_integer or number_type::unsigned_integer. + * + * enum class number_type { + * floating_point_number=1, /// a binary64 number + * signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + * unsigned_integer /// a positive integer larger or equal to 1<<63 + * }; + */ + simdjson_inline ondemand::number_type get_number_type() const noexcept; + /** + * return true if the automatically determined type of + * the number is number_type::unsigned_integer. + */ + simdjson_inline bool is_uint64() const noexcept; + /** + * return the value as a uint64_t, only valid if is_uint64() is true. + */ + simdjson_inline uint64_t get_uint64() const noexcept; + simdjson_inline operator uint64_t() const noexcept; + + /** + * return true if the automatically determined type of + * the number is number_type::signed_integer. + */ + simdjson_inline bool is_int64() const noexcept; + /** + * return the value as a int64_t, only valid if is_int64() is true. + */ + simdjson_inline int64_t get_int64() const noexcept; + simdjson_inline operator int64_t() const noexcept; + + + /** + * return true if the automatically determined type of + * the number is number_type::floating_point_number. + */ + simdjson_inline bool is_double() const noexcept; + /** + * return the value as a double, only valid if is_double() is true. + */ + simdjson_inline double get_double() const noexcept; + simdjson_inline operator double() const noexcept; + + /** + * Convert the number to a double. Though it always succeed, the conversion + * may be lossy if the number cannot be represented exactly. + */ + simdjson_inline double as_double() const noexcept; + + +protected: + /** + * The next block of declaration is designed so that we can call the number parsing + * functions on a number type. They are protected and should never be used outside + * of the core simdjson library. + */ + friend class value_iterator; + template + friend error_code numberparsing::write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer); + template + friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer); + /** Store a signed 64-bit value to the number. */ + simdjson_inline void append_s64(int64_t value) noexcept; + /** Store an unsigned 64-bit value to the number. */ + simdjson_inline void append_u64(uint64_t value) noexcept; + /** Store a double value to the number. */ + simdjson_inline void append_double(double value) noexcept; + /** Specifies that the value is a double, but leave it undefined. */ + simdjson_inline void skip_double() noexcept; + /** + * End of friend declarations. + */ + + /** + * Our attributes are a union type (size = 64 bits) + * followed by a type indicator. + */ + union { + double floating_point_number; + int64_t signed_integer; + uint64_t unsigned_integer; + } payload{0}; + number_type type{number_type::signed_integer}; +}; + +/** + * Write the JSON type to the output stream + * + * @param out The output stream. + * @param type The json_type. + */ +inline std::ostream& operator<<(std::ostream& out, json_type type) noexcept; + +#if SIMDJSON_EXCEPTIONS +/** + * Send JSON type to an output stream. + * + * @param out The output stream. + * @param type The json_type. + * @throw simdjson_error if the result being printed has an error. If there is an error with the + * underlying output stream, that error will be propagated (simdjson_error will not be + * thrown). + */ +inline std::ostream& operator<<(std::ostream& out, simdjson_result &type) noexcept(false); +#endif + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::json_type &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H +/* end file simdjson/generic/ondemand/json_type.h for arm64 */ +/* including simdjson/generic/ondemand/raw_json_string.h for arm64: #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* begin file simdjson/generic/ondemand/raw_json_string.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +/** + * A string escaped per JSON rules, terminated with quote ("). They are used to represent + * unescaped keys inside JSON documents. + * + * (In other words, a pointer to the beginning of a string, just after the start quote, inside a + * JSON file.) + * + * This class is deliberately simplistic and has little functionality. You can + * compare a raw_json_string instance with an unescaped C string, but + * that is nearly all you can do. + * + * The raw_json_string is unescaped. If you wish to write an unescaped version of it to your own + * buffer, you may do so using the parser.unescape(string, buff) method, using an ondemand::parser + * instance. Doing so requires you to have a sufficiently large buffer. + * + * The raw_json_string instances originate typically from field instance which in turn represent + * key-value pairs from object instances. From a field instance, you get the raw_json_string + * instance by calling key(). You can, if you want a more usable string_view instance, call + * the unescaped_key() method on the field instance. You may also create a raw_json_string from + * any other string value, with the value.get_raw_json_string() method. Again, you can get + * a more usable string_view instance by calling get_string(). + * + */ +class raw_json_string { +public: + /** + * Create a new invalid raw_json_string. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline raw_json_string() noexcept = default; + + /** + * Create a new invalid raw_json_string pointed at the given location in the JSON. + * + * The given location must be just *after* the beginning quote (") in the JSON file. + * + * It *must* be terminated by a ", and be a valid JSON string. + */ + simdjson_inline raw_json_string(const uint8_t * _buf) noexcept; + /** + * Get the raw pointer to the beginning of the string in the JSON (just after the "). + * + * It is possible for this function to return a null pointer if the instance + * has outlived its existence. + */ + simdjson_inline const char * raw() const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done) on target.size() characters, + * and if the raw_json_string instance has a quote character at byte index target.size(). + * We never read more than length + 1 bytes in the raw_json_string instance. + * If length is smaller than target.size(), this will return false. + * + * The std::string_view instance may contain any characters. However, the caller + * is responsible for setting length so that length bytes may be read in the + * raw_json_string. + * + * Performance: the comparison may be done using memcmp which may be efficient + * for long strings. + */ + simdjson_inline bool unsafe_is_equal(size_t length, std::string_view target) const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done). + * The std::string_view instance should not contain unescaped quote characters: + * the caller is responsible for this check. See is_free_from_unescaped_quote. + * + * Performance: the comparison is done byte-by-byte which might be inefficient for + * long strings. + * + * If target is a compile-time constant, and your compiler likes you, + * you should be able to do the following without performance penalty... + * + * static_assert(raw_json_string::is_free_from_unescaped_quote(target), ""); + * s.unsafe_is_equal(target); + */ + simdjson_inline bool unsafe_is_equal(std::string_view target) const noexcept; + + /** + * This compares the current instance to the C string target: returns true if + * they are byte-by-byte equal (no escaping is done). + * The provided C string should not contain an unescaped quote character: + * the caller is responsible for this check. See is_free_from_unescaped_quote. + * + * If target is a compile-time constant, and your compiler likes you, + * you should be able to do the following without performance penalty... + * + * static_assert(raw_json_string::is_free_from_unescaped_quote(target), ""); + * s.unsafe_is_equal(target); + */ + simdjson_inline bool unsafe_is_equal(const char* target) const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done). + */ + simdjson_inline bool is_equal(std::string_view target) const noexcept; + + /** + * This compares the current instance to the C string target: returns true if + * they are byte-by-byte equal (no escaping is done). + */ + simdjson_inline bool is_equal(const char* target) const noexcept; + + /** + * Returns true if target is free from unescaped quote. If target is known at + * compile-time, we might expect the computation to happen at compile time with + * many compilers (not all!). + */ + static simdjson_inline bool is_free_from_unescaped_quote(std::string_view target) noexcept; + static simdjson_inline bool is_free_from_unescaped_quote(const char* target) noexcept; + +private: + + + /** + * This will set the inner pointer to zero, effectively making + * this instance unusable. + */ + simdjson_inline void consume() noexcept { buf = nullptr; } + + /** + * Checks whether the inner pointer is non-null and thus usable. + */ + simdjson_inline simdjson_warn_unused bool alive() const noexcept { return buf != nullptr; } + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. + * The result will be a valid UTF-8. + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid until the next parse() call on the parser. + * + * @param iter A json_iterator, which contains a buffer where the string will be written. + * @param allow_replacement Whether we allow replacement of invalid surrogate pairs. + */ + simdjson_inline simdjson_warn_unused simdjson_result unescape(json_iterator &iter, bool allow_replacement) const noexcept; + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. + * The result may not be a valid UTF-8. https://simonsapin.github.io/wtf-8/ + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid until the next parse() call on the parser. + * + * @param iter A json_iterator, which contains a buffer where the string will be written. + */ + simdjson_inline simdjson_warn_unused simdjson_result unescape_wobbly(json_iterator &iter) const noexcept; + const uint8_t * buf{}; + friend class object; + friend class field; + friend class parser; + friend struct simdjson_result; +}; + +simdjson_unused simdjson_inline std::ostream &operator<<(std::ostream &, const raw_json_string &) noexcept; + +/** + * Comparisons between raw_json_string and std::string_view instances are potentially unsafe: the user is responsible + * for providing a string with no unescaped quote. Note that unescaped quotes cannot be present in valid JSON strings. + */ +simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept; +simdjson_unused simdjson_inline bool operator==(std::string_view c, const raw_json_string &a) noexcept; +simdjson_unused simdjson_inline bool operator!=(const raw_json_string &a, std::string_view c) noexcept; +simdjson_unused simdjson_inline bool operator!=(std::string_view c, const raw_json_string &a) noexcept; + + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::raw_json_string &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private + + simdjson_inline simdjson_result raw() const noexcept; + simdjson_inline simdjson_warn_unused simdjson_result unescape(arm64::ondemand::json_iterator &iter, bool allow_replacement) const noexcept; + simdjson_inline simdjson_warn_unused simdjson_result unescape_wobbly(arm64::ondemand::json_iterator &iter) const noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H +/* end file simdjson/generic/ondemand/raw_json_string.h for arm64 */ +/* including simdjson/generic/ondemand/parser.h for arm64: #include "simdjson/generic/ondemand/parser.h" */ +/* begin file simdjson/generic/ondemand/parser.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_PARSER_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +/** + * The default batch size for document_stream instances for this On Demand kernel. + * Note that different On Demand kernel may use a different DEFAULT_BATCH_SIZE value + * in the future. + */ +static constexpr size_t DEFAULT_BATCH_SIZE = 1000000; +/** + * Some adversary might try to set the batch size to 0 or 1, which might cause problems. + * We set a minimum of 32B since anything else is highly likely to be an error. In practice, + * most users will want a much larger batch size. + * + * All non-negative MINIMAL_BATCH_SIZE values should be 'safe' except that, obviously, no JSON + * document can ever span 0 or 1 byte and that very large values would create memory allocation issues. + */ +static constexpr size_t MINIMAL_BATCH_SIZE = 32; + +/** + * A JSON fragment iterator. + * + * This holds the actual iterator as well as the buffer for writing strings. + */ +class parser { +public: + /** + * Create a JSON parser. + * + * The new parser will have zero capacity. + */ + inline explicit parser(size_t max_capacity = SIMDJSON_MAXSIZE_BYTES) noexcept; + + inline parser(parser &&other) noexcept = default; + simdjson_inline parser(const parser &other) = delete; + simdjson_inline parser &operator=(const parser &other) = delete; + simdjson_inline parser &operator=(parser &&other) noexcept = default; + + /** Deallocate the JSON parser. */ + inline ~parser() noexcept = default; + + /** + * Start iterating an on-demand JSON document. + * + * ondemand::parser parser; + * document doc = parser.iterate(json); + * + * It is expected that the content is a valid UTF-8 file, containing a valid JSON document. + * Otherwise the iterate method may return an error. In particular, the whole input should be + * valid: we do not attempt to tolerate incorrect content either before or after a JSON + * document. If there is a UTF-8 BOM, the parser skips it. + * + * ### IMPORTANT: Validate what you use + * + * Calling iterate on an invalid JSON document may not immediately trigger an error. The call to + * iterate does not parse and validate the whole document. + * + * ### IMPORTANT: Buffer Lifetime + * + * Because parsing is done while you iterate, you *must* keep the JSON buffer around at least as + * long as the document iteration. + * + * ### IMPORTANT: Document Lifetime + * + * Only one iteration at a time can happen per parser, and the parser *must* be kept alive during + * iteration to ensure intermediate buffers can be accessed. Any document must be destroyed before + * you call parse() again or destroy the parser. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * @param json The JSON to parse. + * @param len The length of the JSON. + * @param capacity The number of bytes allocated in the JSON (must be at least len+SIMDJSON_PADDING). + * + * @return The document, or an error: + * - INSUFFICIENT_PADDING if the input has less than SIMDJSON_PADDING extra bytes. + * - MEMALLOC if realloc_if_needed the parser does not have enough capacity, and memory + * allocation fails. + * - EMPTY if the document is all whitespace. + * - UTF8_ERROR if the document is not valid UTF-8. + * - UNESCAPED_CHARS if a string contains control characters that must be escaped + * - UNCLOSED_STRING if there is an unclosed string in the document. + */ + simdjson_warn_unused simdjson_result iterate(padded_string_view json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const char *json, size_t len, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const uint8_t *json, size_t len, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(std::string_view json, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const std::string &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(std::string &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const simdjson_result &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const simdjson_result &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(padded_string &&json) & noexcept = delete; + + /** + * @private + * + * Start iterating an on-demand JSON document. + * + * ondemand::parser parser; + * json_iterator doc = parser.iterate(json); + * + * ### IMPORTANT: Buffer Lifetime + * + * Because parsing is done while you iterate, you *must* keep the JSON buffer around at least as + * long as the document iteration. + * + * ### IMPORTANT: Document Lifetime + * + * Only one iteration at a time can happen per parser, and the parser *must* be kept alive during + * iteration to ensure intermediate buffers can be accessed. Any document must be destroyed before + * you call parse() again or destroy the parser. + * + * The ondemand::document instance holds the iterator. The document must remain in scope + * while you are accessing instances of ondemand::value, ondemand::object, ondemand::array. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * @param json The JSON to parse. + * + * @return The iterator, or an error: + * - INSUFFICIENT_PADDING if the input has less than SIMDJSON_PADDING extra bytes. + * - MEMALLOC if realloc_if_needed the parser does not have enough capacity, and memory + * allocation fails. + * - EMPTY if the document is all whitespace. + * - UTF8_ERROR if the document is not valid UTF-8. + * - UNESCAPED_CHARS if a string contains control characters that must be escaped + * - UNCLOSED_STRING if there is an unclosed string in the document. + */ + simdjson_warn_unused simdjson_result iterate_raw(padded_string_view json) & noexcept; + + + /** + * Parse a buffer containing many JSON documents. + * + * auto json = R"({ "foo": 1 } { "foo": 2 } { "foo": 3 } )"_padded; + * ondemand::parser parser; + * ondemand::document_stream docs = parser.iterate_many(json); + * for (auto & doc : docs) { + * std::cout << doc["foo"] << std::endl; + * } + * // Prints 1 2 3 + * + * No copy of the input buffer is made. + * + * The function is lazy: it may be that no more than one JSON document at a time is parsed. + * + * The caller is responsabile to ensure that the input string data remains unchanged and is + * not deleted during the loop. + * + * ### Format + * + * The buffer must contain a series of one or more JSON documents, concatenated into a single + * buffer, separated by ASCII whitespace. It effectively parses until it has a fully valid document, + * then starts parsing the next document at that point. (It does this with more parallelism and + * lookahead than you might think, though.) + * + * documents that consist of an object or array may omit the whitespace between them, concatenating + * with no separator. Documents that consist of a single primitive (i.e. documents that are not + * arrays or objects) MUST be separated with ASCII whitespace. + * + * The characters inside a JSON document, and between JSON documents, must be valid Unicode (UTF-8). + * If there is a UTF-8 BOM, the parser skips it. + * + * The documents must not exceed batch_size bytes (by default 1MB) or they will fail to parse. + * Setting batch_size to excessively large or excessively small values may impact negatively the + * performance. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * ### Threads + * + * When compiled with SIMDJSON_THREADS_ENABLED, this method will use a single thread under the + * hood to do some lookahead. + * + * ### Parser Capacity + * + * If the parser's current capacity is less than batch_size, it will allocate enough capacity + * to handle it (up to max_capacity). + * + * @param buf The concatenated JSON to parse. + * @param len The length of the concatenated JSON. + * @param batch_size The batch size to use. MUST be larger than the largest document. The sweet + * spot is cache-related: small enough to fit in cache, yet big enough to + * parse as many documents as possible in one tight loop. + * Defaults to 10MB, which has been a reasonable sweet spot in our tests. + * @param allow_comma_separated (defaults on false) This allows a mode where the documents are + * separated by commas instead of whitespace. It comes with a performance + * penalty because the entire document is indexed at once (and the document must be + * less than 4 GB), and there is no multithreading. In this mode, the batch_size parameter + * is effectively ignored, as it is set to at least the document size. + * @return The stream, or an error. An empty input will yield 0 documents rather than an EMPTY error. Errors: + * - MEMALLOC if the parser does not have enough capacity and memory allocation fails + * - CAPACITY if the parser does not have enough capacity and batch_size > max_capacity. + * - other json errors if parsing fails. You should not rely on these errors to always the same for the + * same document: they may vary under runtime dispatch (so they may vary depending on your system and hardware). + */ + inline simdjson_result iterate_many(const uint8_t *buf, size_t len, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const char *buf, size_t len, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const std::string &s, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + inline simdjson_result iterate_many(const std::string &&s, size_t batch_size, bool allow_comma_separated = false) = delete;// unsafe + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const padded_string &s, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + inline simdjson_result iterate_many(const padded_string &&s, size_t batch_size, bool allow_comma_separated = false) = delete;// unsafe + + /** @private We do not want to allow implicit conversion from C string to std::string. */ + simdjson_result iterate_many(const char *buf, size_t batch_size = DEFAULT_BATCH_SIZE) noexcept = delete; + + /** The capacity of this parser (the largest document it can process). */ + simdjson_inline size_t capacity() const noexcept; + /** The maximum capacity of this parser (the largest document it is allowed to process). */ + simdjson_inline size_t max_capacity() const noexcept; + simdjson_inline void set_max_capacity(size_t max_capacity) noexcept; + /** + * The maximum depth of this parser (the most deeply nested objects and arrays it can process). + * This parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true. + * The document's instance current_depth() method should be used to monitor the parsing + * depth and limit it if desired. + */ + simdjson_inline size_t max_depth() const noexcept; + + /** + * Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length + * and `max_depth` depth. + * + * The max_depth parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true. + * The document's instance current_depth() method should be used to monitor the parsing + * depth and limit it if desired. + * + * @param capacity The new capacity. + * @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH. + * @return The error, if there is one. + */ + simdjson_warn_unused error_code allocate(size_t capacity, size_t max_depth=DEFAULT_MAX_DEPTH) noexcept; + + #ifdef SIMDJSON_THREADS_ENABLED + /** + * The parser instance can use threads when they are available to speed up some + * operations. It is enabled by default. Changing this attribute will change the + * behavior of the parser for future operations. + */ + bool threaded{true}; + #endif + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. to a user-provided buffer. + * The result must be valid UTF-8. + * The provided pointer is advanced to the end of the string by reference, and a string_view instance + * is returned. You can ensure that your buffer is large enough by allocating a block of memory at least + * as large as the input JSON plus SIMDJSON_PADDING and then unescape all strings to this one buffer. + * + * This unescape function is a low-level function. If you want a more user-friendly approach, you should + * avoid raw_json_string instances (e.g., by calling unescaped_key() instead of key() or get_string() + * instead of get_raw_json_string()). + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid as long as the bytes in dst. + * + * @param raw_json_string input + * @param dst A pointer to a buffer at least large enough to write this string as well as + * an additional SIMDJSON_PADDING bytes. + * @param allow_replacement Whether we allow a replacement if the input string contains unmatched surrogate pairs. + * @return A string_view pointing at the unescaped string in dst + * @error STRING_ERROR if escapes are incorrect. + */ + simdjson_inline simdjson_result unescape(raw_json_string in, uint8_t *&dst, bool allow_replacement = false) const noexcept; + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. to a user-provided buffer. + * The result may not be valid UTF-8. See https://simonsapin.github.io/wtf-8/ + * The provided pointer is advanced to the end of the string by reference, and a string_view instance + * is returned. You can ensure that your buffer is large enough by allocating a block of memory at least + * as large as the input JSON plus SIMDJSON_PADDING and then unescape all strings to this one buffer. + * + * This unescape function is a low-level function. If you want a more user-friendly approach, you should + * avoid raw_json_string instances (e.g., by calling unescaped_key() instead of key() or get_string() + * instead of get_raw_json_string()). + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid as long as the bytes in dst. + * + * @param raw_json_string input + * @param dst A pointer to a buffer at least large enough to write this string as well as + * an additional SIMDJSON_PADDING bytes. + * @return A string_view pointing at the unescaped string in dst + * @error STRING_ERROR if escapes are incorrect. + */ + simdjson_inline simdjson_result unescape_wobbly(raw_json_string in, uint8_t *&dst) const noexcept; + +private: + /** @private [for benchmarking access] The implementation to use */ + std::unique_ptr implementation{}; + size_t _capacity{0}; + size_t _max_capacity; + size_t _max_depth{DEFAULT_MAX_DEPTH}; + std::unique_ptr string_buf{}; +#if SIMDJSON_DEVELOPMENT_CHECKS + std::unique_ptr start_positions{}; +#endif + + friend class json_iterator; + friend class document_stream; +}; + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::parser &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_PARSER_H +/* end file simdjson/generic/ondemand/parser.h for arm64 */ + +// All other declarations +/* including simdjson/generic/ondemand/array.h for arm64: #include "simdjson/generic/ondemand/array.h" */ +/* begin file simdjson/generic/ondemand/array.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +/** + * A forward-only JSON array. + */ +class array { +public: + /** + * Create a new invalid array. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline array() noexcept = default; + + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result begin() noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() noexcept; + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an array is empty, it is more performant to use + * the is_empty() method. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the beginning of the array and checks whether the + * array is empty. + * The runtime complexity is constant time. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + simdjson_inline simdjson_result is_empty() & noexcept; + /** + * Reset the iterator so that we are pointing back at the + * beginning of the array. You should still consume values only once even if you + * can iterate through the array more than once. If you unescape a string + * within the array more than once, you have unsafe code. Note that rewinding + * an array means that you may need to reparse it anew: it is not a free + * operation. + * + * @returns true if the array contains some elements (not empty) + */ + inline simdjson_result reset() & noexcept; + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard, interpreting the current node + * as the root of its own JSON document. + * + * ondemand::parser parser; + * auto json = R"([ { "foo": { "a": [ 10, 20, 30 ] }} ])"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/0/foo/a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. Yet it is not the case when calling at_pointer on an array + * instance: there is no rewind and no invalidation. + * + * You may only call at_pointer on an array after it has been created, but before it has + * been first accessed. When calling at_pointer on an array, the pointer is advanced to + * the location indicated by the JSON pointer (in case of success). It is no longer possible + * to call at_pointer on the same array. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching. + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + /** + * Consumes the array and returns a string_view instance corresponding to the + * array as represented in JSON. It points inside the original document. + */ + simdjson_inline simdjson_result raw_json() noexcept; + + /** + * Get the value at the given index. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) noexcept; +protected: + /** + * Go to the end of the array, no matter where you are right now. + */ + simdjson_inline error_code consume() noexcept; + + /** + * Begin array iteration. + * + * @param iter The iterator. Must be where the initial [ is expected. Will be *moved* into the + * resulting array. + * @error INCORRECT_TYPE if the iterator is not at [. + */ + static simdjson_inline simdjson_result start(value_iterator &iter) noexcept; + /** + * Begin array iteration from the root. + * + * @param iter The iterator. Must be where the initial [ is expected. Will be *moved* into the + * resulting array. + * @error INCORRECT_TYPE if the iterator is not at [. + * @error TAPE_ERROR if there is no closing ] at the end of the document. + */ + static simdjson_inline simdjson_result start_root(value_iterator &iter) noexcept; + /** + * Begin array iteration. + * + * This version of the method should be called after the initial [ has been verified, and is + * intended for use by switch statements that check the type of a value. + * + * @param iter The iterator. Must be after the initial [. Will be *moved* into the resulting array. + */ + static simdjson_inline simdjson_result started(value_iterator &iter) noexcept; + + /** + * Create an array at the given Internal array creation. Call array::start() or array::started() instead of this. + * + * @param iter The iterator. Must either be at the start of the first element with iter.is_alive() + * == true, or past the [] with is_alive() == false if the array is empty. Will be *moved* + * into the resulting array. + */ + simdjson_inline array(const value_iterator &iter) noexcept; + + /** + * Iterator marking current position. + * + * iter.is_alive() == false indicates iteration is complete. + */ + value_iterator iter{}; + + friend class value; + friend class document; + friend struct simdjson_result; + friend struct simdjson_result; + friend class array_iterator; +}; + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::array &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + inline simdjson_result count_elements() & noexcept; + inline simdjson_result is_empty() & noexcept; + inline simdjson_result reset() & noexcept; + simdjson_inline simdjson_result at(size_t index) noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_H +/* end file simdjson/generic/ondemand/array.h for arm64 */ +/* including simdjson/generic/ondemand/array_iterator.h for arm64: #include "simdjson/generic/ondemand/array_iterator.h" */ +/* begin file simdjson/generic/ondemand/array_iterator.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +/** + * A forward-only JSON array. + * + * This is an input_iterator, meaning: + * - It is forward-only + * - * must be called exactly once per element. + * - ++ must be called exactly once in between each * (*, ++, *, ++, * ...) + */ +class array_iterator { +public: + /** Create a new, invalid array iterator. */ + simdjson_inline array_iterator() noexcept = default; + + // + // Iterator interface + // + + /** + * Get the current element. + * + * Part of the std::iterator interface. + */ + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + /** + * Check if we are at the end of the JSON. + * + * Part of the std::iterator interface. + * + * @return true if there are no more elements in the JSON array. + */ + simdjson_inline bool operator==(const array_iterator &) const noexcept; + /** + * Check if there are more elements in the JSON array. + * + * Part of the std::iterator interface. + * + * @return true if there are more elements in the JSON array. + */ + simdjson_inline bool operator!=(const array_iterator &) const noexcept; + /** + * Move to the next element. + * + * Part of the std::iterator interface. + */ + simdjson_inline array_iterator &operator++() noexcept; + +private: + value_iterator iter{}; + + simdjson_inline array_iterator(const value_iterator &iter) noexcept; + + friend class array; + friend class value; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::array_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + // + // Iterator interface + // + + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + simdjson_inline bool operator==(const simdjson_result &) const noexcept; + simdjson_inline bool operator!=(const simdjson_result &) const noexcept; + simdjson_inline simdjson_result &operator++() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H +/* end file simdjson/generic/ondemand/array_iterator.h for arm64 */ +/* including simdjson/generic/ondemand/document.h for arm64: #include "simdjson/generic/ondemand/document.h" */ +/* begin file simdjson/generic/ondemand/document.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +/** + * A JSON document. It holds a json_iterator instance. + * + * Used by tokens to get text, and string buffer location. + * + * You must keep the document around during iteration. + */ +class document { +public: + /** + * Create a new invalid document. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline document() noexcept = default; + simdjson_inline document(const document &other) noexcept = delete; // pass your documents by reference, not by copy + simdjson_inline document(document &&other) noexcept = default; + simdjson_inline document &operator=(const document &other) noexcept = delete; + simdjson_inline document &operator=(document &&other) noexcept = default; + + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result get_array() & noexcept; + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @returns INCORRECT_TYPE If the JSON value is not an object. + */ + simdjson_inline simdjson_result get_object() & noexcept; + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64() noexcept; + /** + * Cast this JSON value (inside string) to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64() noexcept; + /** + * Cast this JSON value (inside string) to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64_in_string() noexcept; + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double() noexcept; + + /** + * Cast this JSON value (inside string) to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double_in_string() noexcept; + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: Calling get_string() twice on the same document is an error. + * + * @param Whether to allow a replacement character for unmatched surrogate pairs. + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + /** + * Attempts to fill the provided std::string reference with the parsed value of the current string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory. + * We recommend you avoid allocating an std::string unless you need to. + * + * @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS. + */ + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + /** + * Cast this JSON value to a string. + * + * The string is not guaranteed to be valid UTF-8. See https://simonsapin.github.io/wtf-8/ + * + * Important: Calling get_wobbly_string() twice on the same document is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_wobbly_string() noexcept; + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_raw_json_string() noexcept; + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @returns INCORRECT_TYPE if the JSON value is not true or false. + */ + simdjson_inline simdjson_result get_bool() noexcept; + /** + * Cast this JSON value to a value when the document is an object or an array. + * + * You must not have begun iterating through the object or array. When + * SIMDJSON_DEVELOPMENT_CHECKS is set to 1 (which is the case when building in Debug mode + * by default), and you have already begun iterating, + * you will get an OUT_OF_ORDER_ITERATION error. If you have begun iterating, you can use + * rewind() to reset the document to its initial state before calling this method. + * + * @returns A value if a JSON array or object cannot be found. + * @returns SCALAR_DOCUMENT_AS_VALUE error is the document is a scalar (see is_scalar() function). + */ + simdjson_inline simdjson_result get_value() noexcept; + + /** + * Checks if this JSON value is null. If and only if the value is + * null, then it is consumed (we advance). If we find a token that + * begins with 'n' but is not 'null', then an error is returned. + * + * @returns Whether the value is null. + * @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'. + */ + simdjson_inline simdjson_result is_null() noexcept; + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * You may use get_double(), get_bool(), get_uint64(), get_int64(), + * get_object(), get_array(), get_raw_json_string(), or get_string() instead. + * + * @returns A value of the given type, parsed from the JSON. + * @returns INCORRECT_TYPE If the JSON value is not the given type. + */ + template simdjson_inline simdjson_result get() & noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + /** @overload template simdjson_result get() & noexcept */ + template simdjson_inline simdjson_result get() && noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool, value + * + * Be mindful that the document instance must remain in scope while you are accessing object, array and value instances. + * + * @param out This is set to a value of the given type, parsed from the JSON. If there is an error, this may not be initialized. + * @returns INCORRECT_TYPE If the JSON value is not an object. + * @returns SUCCESS If the parse succeeded and the out parameter was set to the value. + */ + template simdjson_inline error_code get(T &out) & noexcept; + /** @overload template error_code get(T &out) & noexcept */ + template simdjson_inline error_code get(T &out) && noexcept; + +#if SIMDJSON_EXCEPTIONS + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an array. + */ + simdjson_inline operator array() & noexcept(false); + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an object. + */ + simdjson_inline operator object() & noexcept(false); + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline operator uint64_t() noexcept(false); + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer. + */ + simdjson_inline operator int64_t() noexcept(false); + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number. + */ + simdjson_inline operator double() noexcept(false); + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator std::string_view() noexcept(false); + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator raw_json_string() noexcept(false); + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false. + */ + simdjson_inline operator bool() noexcept(false); + /** + * Cast this JSON value to a value when the document is an object or an array. + * + * You must not have begun iterating through the object or array. When + * SIMDJSON_DEVELOPMENT_CHECKS is defined, and you have already begun iterating, + * you will get an OUT_OF_ORDER_ITERATION error. If you have begun iterating, you can use + * rewind() to reset the document to its initial state before calling this method. + * + * @returns A value value if a JSON array or object cannot be found. + * @exception SCALAR_DOCUMENT_AS_VALUE error is the document is a scalar (see is_scalar() function). + */ + simdjson_inline operator value() noexcept(false); +#endif + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Get the value at the given index in the array. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) & noexcept; + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result begin() & noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() & noexcept; + + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. E.g., the array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to + * a key a single time. Doing object["mykey"].to_string()and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. E.g., the array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a key + * a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + + /** + * Get the type of this JSON value. It does not validate or consume the value. + * E.g., you must still call "is_null()" to check that a value is null even if + * "type()" returns json_type::null. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + * + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() noexcept; + + /** + * Checks whether the document is a scalar (string, number, null, Boolean). + * Returns false when there it is an array or object. + * + * @returns true if the type is string, number, null, Boolean + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result is_scalar() noexcept; + + /** + * Checks whether the document is a negative number. + * + * @returns true if the number if negative. + */ + simdjson_inline bool is_negative() noexcept; + /** + * Checks whether the document is an integer number. Note that + * this requires to partially parse the number string. If + * the value is determined to be an integer, it may still + * not parse properly as an integer in subsequent steps + * (e.g., it might overflow). + * + * @returns true if the number if negative. + */ + simdjson_inline simdjson_result is_integer() noexcept; + /** + * Determine the number type (integer or floating-point number) as quickly + * as possible. This function does not fully validate the input. It is + * useful when you only need to classify the numbers, without parsing them. + * + * If you are planning to retrieve the value or you need full validation, + * consider using the get_number() method instead: it will fully parse + * and validate the input, and give you access to the type: + * get_number().get_number_type(). + * + * get_number_type() is number_type::unsigned_integer if we have + * an integer greater or equal to 9223372036854775808 + * get_number_type() is number_type::signed_integer if we have an + * integer that is less than 9223372036854775808 + * Otherwise, get_number_type() has value number_type::floating_point_number + * + * This function requires processing the number string, but it is expected + * to be faster than get_number().get_number_type() because it is does not + * parse the number value. + * + * @returns the type of the number + */ + simdjson_inline simdjson_result get_number_type() noexcept; + + /** + * Attempt to parse an ondemand::number. An ondemand::number may + * contain an integer value or a floating-point value, the simdjson + * library will autodetect the type. Thus it is a dynamically typed + * number. Before accessing the value, you must determine the detected + * type. + * + * number.get_number_type() is number_type::signed_integer if we have + * an integer in [-9223372036854775808,9223372036854775808) + * You can recover the value by calling number.get_int64() and you + * have that number.is_int64() is true. + * + * number.get_number_type() is number_type::unsigned_integer if we have + * an integer in [9223372036854775808,18446744073709551616) + * You can recover the value by calling number.get_uint64() and you + * have that number.is_uint64() is true. + * + * Otherwise, number.get_number_type() has value number_type::floating_point_number + * and we have a binary64 number. + * You can recover the value by calling number.get_double() and you + * have that number.is_double() is true. + * + * You must check the type before accessing the value: it is an error + * to call "get_int64()" when number.get_number_type() is not + * number_type::signed_integer and when number.is_int64() is false. + */ + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + /** + * Get the raw JSON for this token. + * + * The string_view will always point into the input buffer. + * + * The string_view will start at the beginning of the token, and include the entire token + * *as well as all spaces until the next token (or EOF).* This means, for example, that a + * string token always begins with a " and is always terminated by the final ", possibly + * followed by a number of spaces. + * + * The string_view is *not* null-terminated. If this is a scalar (string, number, + * boolean, or null), the character after the end of the string_view may be the padded buffer. + * + * Tokens include: + * - { + * - [ + * - "a string (possibly with UTF-8 or backslashed characters like \\\")". + * - -1.2e-100 + * - true + * - false + * - null + */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + /** + * Reset the iterator inside the document instance so we are pointing back at the + * beginning of the document, as if it had just been created. It invalidates all + * values, objects and arrays that you have created so far (including unescaped strings). + */ + inline void rewind() noexcept; + /** + * Returns debugging information. + */ + inline std::string to_debug_string() noexcept; + /** + * Some unrecoverable error conditions may render the document instance unusable. + * The is_alive() method returns true when the document is still suitable. + */ + inline bool is_alive() noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + inline simdjson_result current_location() const noexcept; + + /** + * Returns true if this document has been fully parsed. + * If you have consumed the whole document and at_end() returns + * false, then there may be trailing content. + */ + inline bool at_end() const noexcept; + + /** + * Returns the current depth in the document if in bounds. + * + * E.g., + * 0 = finished with document + * 1 = document root value (could be [ or {, not yet known) + * 2 = , or } inside root array/object + * 3 = key or value inside root array/object. + */ + simdjson_inline int32_t current_depth() const noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() automatically calls rewind between each call. Thus + * all values, objects and arrays that you have created so far (including unescaped strings) + * are invalidated. After calling at_pointer, you need to consume the result: string values + * should be stored in your own variables, arrays should be decoded and stored in your own array-like + * structures and so forth. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + * - SCALAR_DOCUMENT_AS_VALUE if the json_pointer is empty and the document is not a scalar (see is_scalar() function). + */ + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + /** + * Consumes the document and returns a string_view instance corresponding to the + * document as represented in JSON. It points inside the original byte array containing + * the JSON document. + */ + simdjson_inline simdjson_result raw_json() noexcept; +protected: + /** + * Consumes the document. + */ + simdjson_inline error_code consume() noexcept; + + simdjson_inline document(ondemand::json_iterator &&iter) noexcept; + simdjson_inline const uint8_t *text(uint32_t idx) const noexcept; + + simdjson_inline value_iterator resume_value_iterator() noexcept; + simdjson_inline value_iterator get_root_value_iterator() noexcept; + simdjson_inline simdjson_result start_or_resume_object() noexcept; + static simdjson_inline document start(ondemand::json_iterator &&iter) noexcept; + + // + // Fields + // + json_iterator iter{}; ///< Current position in the document + static constexpr depth_t DOCUMENT_DEPTH = 0; ///< document depth is always 0 + + friend class array_iterator; + friend class value; + friend class ondemand::parser; + friend class object; + friend class array; + friend class field; + friend class token; + friend class document_stream; + friend class document_reference; +}; + + +/** + * A document_reference is a thin wrapper around a document reference instance. + */ +class document_reference { +public: + simdjson_inline document_reference() noexcept; + simdjson_inline document_reference(document &d) noexcept; + simdjson_inline document_reference(const document_reference &other) noexcept = default; + simdjson_inline document_reference& operator=(const document_reference &other) noexcept = default; + simdjson_inline void rewind() noexcept; + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + + simdjson_inline simdjson_result is_null() noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + simdjson_inline operator document&() const noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator array() & noexcept(false); + simdjson_inline operator object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline int32_t current_depth() const noexcept; + simdjson_inline bool is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + simdjson_inline simdjson_result raw_json_token() noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +private: + document *doc{nullptr}; +}; +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::document &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline error_code rewind() noexcept; + + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + + template simdjson_inline simdjson_result get() & noexcept; + template simdjson_inline simdjson_result get() && noexcept; + + template simdjson_inline error_code get(T &out) & noexcept; + template simdjson_inline error_code get(T &out) && noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator arm64::ondemand::array() & noexcept(false); + simdjson_inline operator arm64::ondemand::object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator arm64::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator arm64::ondemand::value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline int32_t current_depth() const noexcept; + simdjson_inline bool at_end() const noexcept; + simdjson_inline bool is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + /** @copydoc simdjson_inline std::string_view document::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + + +} // namespace simdjson + + + +namespace simdjson { + +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::document_reference value, error_code error) noexcept; + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline error_code rewind() noexcept; + + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator arm64::ondemand::array() & noexcept(false); + simdjson_inline operator arm64::ondemand::object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator arm64::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator arm64::ondemand::value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline simdjson_result current_depth() const noexcept; + simdjson_inline simdjson_result is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + /** @copydoc simdjson_inline std::string_view document_reference::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H +/* end file simdjson/generic/ondemand/document.h for arm64 */ +/* including simdjson/generic/ondemand/document_stream.h for arm64: #include "simdjson/generic/ondemand/document_stream.h" */ +/* begin file simdjson/generic/ondemand/document_stream.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#ifdef SIMDJSON_THREADS_ENABLED +#include +#include +#include +#endif + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +#ifdef SIMDJSON_THREADS_ENABLED +/** @private Custom worker class **/ +struct stage1_worker { + stage1_worker() noexcept = default; + stage1_worker(const stage1_worker&) = delete; + stage1_worker(stage1_worker&&) = delete; + stage1_worker operator=(const stage1_worker&) = delete; + ~stage1_worker(); + /** + * We only start the thread when it is needed, not at object construction, this may throw. + * You should only call this once. + **/ + void start_thread(); + /** + * Start a stage 1 job. You should first call 'run', then 'finish'. + * You must call start_thread once before. + */ + void run(document_stream * ds, parser * stage1, size_t next_batch_start); + /** Wait for the run to finish (blocking). You should first call 'run', then 'finish'. **/ + void finish(); + +private: + + /** + * Normally, we would never stop the thread. But we do in the destructor. + * This function is only safe assuming that you are not waiting for results. You + * should have called run, then finish, and be done. + **/ + void stop_thread(); + + std::thread thread{}; + /** These three variables define the work done by the thread. **/ + ondemand::parser * stage1_thread_parser{}; + size_t _next_batch_start{}; + document_stream * owner{}; + /** + * We have two state variables. This could be streamlined to one variable in the future but + * we use two for clarity. + */ + bool has_work{false}; + bool can_work{true}; + + /** + * We lock using a mutex. + */ + std::mutex locking_mutex{}; + std::condition_variable cond_var{}; + + friend class document_stream; +}; +#endif // SIMDJSON_THREADS_ENABLED + +/** + * A forward-only stream of documents. + * + * Produced by parser::iterate_many. + * + */ +class document_stream { +public: + /** + * Construct an uninitialized document_stream. + * + * ```c++ + * document_stream docs; + * auto error = parser.iterate_many(json).get(docs); + * ``` + */ + simdjson_inline document_stream() noexcept; + /** Move one document_stream to another. */ + simdjson_inline document_stream(document_stream &&other) noexcept = default; + /** Move one document_stream to another. */ + simdjson_inline document_stream &operator=(document_stream &&other) noexcept = default; + + simdjson_inline ~document_stream() noexcept; + + /** + * Returns the input size in bytes. + */ + inline size_t size_in_bytes() const noexcept; + + /** + * After iterating through the stream, this method + * returns the number of bytes that were not parsed at the end + * of the stream. If truncated_bytes() differs from zero, + * then the input was truncated maybe because incomplete JSON + * documents were found at the end of the stream. You + * may need to process the bytes in the interval [size_in_bytes()-truncated_bytes(), size_in_bytes()). + * + * You should only call truncated_bytes() after streaming through all + * documents, like so: + * + * document_stream stream = parser.iterate_many(json,window); + * for(auto & doc : stream) { + * // do something with doc + * } + * size_t truncated = stream.truncated_bytes(); + * + */ + inline size_t truncated_bytes() const noexcept; + + class iterator { + public: + using value_type = simdjson_result; + using reference = value_type; + + using difference_type = std::ptrdiff_t; + + using iterator_category = std::input_iterator_tag; + + /** + * Default constructor. + */ + simdjson_inline iterator() noexcept; + /** + * Get the current document (or error). + */ + simdjson_inline simdjson_result operator*() noexcept; + /** + * Advance to the next document (prefix). + */ + inline iterator& operator++() noexcept; + /** + * Check if we're at the end yet. + * @param other the end iterator to compare to. + */ + simdjson_inline bool operator!=(const iterator &other) const noexcept; + /** + * @private + * + * Gives the current index in the input document in bytes. + * + * document_stream stream = parser.parse_many(json,window); + * for(auto i = stream.begin(); i != stream.end(); ++i) { + * auto doc = *i; + * size_t index = i.current_index(); + * } + * + * This function (current_index()) is experimental and the usage + * may change in future versions of simdjson: we find the API somewhat + * awkward and we would like to offer something friendlier. + */ + simdjson_inline size_t current_index() const noexcept; + + /** + * @private + * + * Gives a view of the current document at the current position. + * + * document_stream stream = parser.iterate_many(json,window); + * for(auto i = stream.begin(); i != stream.end(); ++i) { + * std::string_view v = i.source(); + * } + * + * The returned string_view instance is simply a map to the (unparsed) + * source string: it may thus include white-space characters and all manner + * of padding. + * + * This function (source()) is experimental and the usage + * may change in future versions of simdjson: we find the API somewhat + * awkward and we would like to offer something friendlier. + * + */ + simdjson_inline std::string_view source() const noexcept; + + /** + * Returns error of the stream (if any). + */ + inline error_code error() const noexcept; + + private: + simdjson_inline iterator(document_stream *s, bool finished) noexcept; + /** The document_stream we're iterating through. */ + document_stream* stream; + /** Whether we're finished or not. */ + bool finished; + + friend class document; + friend class document_stream; + friend class json_iterator; + }; + + /** + * Start iterating the documents in the stream. + */ + simdjson_inline iterator begin() noexcept; + /** + * The end of the stream, for iterator comparison purposes. + */ + simdjson_inline iterator end() noexcept; + +private: + + document_stream &operator=(const document_stream &) = delete; // Disallow copying + document_stream(const document_stream &other) = delete; // Disallow copying + + /** + * Construct a document_stream. Does not allocate or parse anything until the iterator is + * used. + * + * @param parser is a reference to the parser instance used to generate this document_stream + * @param buf is the raw byte buffer we need to process + * @param len is the length of the raw byte buffer in bytes + * @param batch_size is the size of the windows (must be strictly greater or equal to the largest JSON document) + */ + simdjson_inline document_stream( + ondemand::parser &parser, + const uint8_t *buf, + size_t len, + size_t batch_size, + bool allow_comma_separated + ) noexcept; + + /** + * Parse the first document in the buffer. Used by begin(), to handle allocation and + * initialization. + */ + inline void start() noexcept; + + /** + * Parse the next document found in the buffer previously given to document_stream. + * + * The content should be a valid JSON document encoded as UTF-8. If there is a + * UTF-8 BOM, the parser skips it. + * + * You do NOT need to pre-allocate a parser. This function takes care of + * pre-allocating a capacity defined by the batch_size defined when creating the + * document_stream object. + * + * The function returns simdjson::EMPTY if there is no more data to be parsed. + * + * The function returns simdjson::SUCCESS (as integer = 0) in case of success + * and indicates that the buffer has successfully been parsed to the end. + * Every document it contained has been parsed without error. + * + * The function returns an error code from simdjson/simdjson.h in case of failure + * such as simdjson::CAPACITY, simdjson::MEMALLOC, simdjson::DEPTH_ERROR and so forth; + * the simdjson::error_message function converts these error codes into a string). + * + * You can also check validity by calling parser.is_valid(). The same parser can + * and should be reused for the other documents in the buffer. + */ + inline void next() noexcept; + + /** Move the json_iterator of the document to the location of the next document in the stream. */ + inline void next_document() noexcept; + + /** Get the next document index. */ + inline size_t next_batch_start() const noexcept; + + /** Pass the next batch through stage 1 with the given parser. */ + inline error_code run_stage1(ondemand::parser &p, size_t batch_start) noexcept; + + // Fields + ondemand::parser *parser; + const uint8_t *buf; + size_t len; + size_t batch_size; + bool allow_comma_separated; + /** + * We are going to use just one document instance. The document owns + * the json_iterator. It implies that we only ever pass a reference + * to the document to the users. + */ + document doc{}; + /** The error (or lack thereof) from the current document. */ + error_code error; + size_t batch_start{0}; + size_t doc_index{}; + + #ifdef SIMDJSON_THREADS_ENABLED + /** Indicates whether we use threads. Note that this needs to be a constant during the execution of the parsing. */ + bool use_thread; + + inline void load_from_stage1_thread() noexcept; + + /** Start a thread to run stage 1 on the next batch. */ + inline void start_stage1_thread() noexcept; + + /** Wait for the stage 1 thread to finish and capture the results. */ + inline void finish_stage1_thread() noexcept; + + /** The error returned from the stage 1 thread. */ + error_code stage1_thread_error{UNINITIALIZED}; + /** The thread used to run stage 1 against the next batch in the background. */ + std::unique_ptr worker{new(std::nothrow) stage1_worker()}; + /** + * The parser used to run stage 1 in the background. Will be swapped + * with the regular parser when finished. + */ + ondemand::parser stage1_thread_parser{}; + + friend struct stage1_worker; + #endif // SIMDJSON_THREADS_ENABLED + + friend class parser; + friend class document; + friend class json_iterator; + friend struct simdjson_result; + friend struct internal::simdjson_result_base; +}; // document_stream + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::document_stream &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H +/* end file simdjson/generic/ondemand/document_stream.h for arm64 */ +/* including simdjson/generic/ondemand/field.h for arm64: #include "simdjson/generic/ondemand/field.h" */ +/* begin file simdjson/generic/ondemand/field.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_FIELD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_FIELD_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +/** + * A JSON field (key/value pair) in an object. + * + * Returned from object iteration. + * + * Extends from std::pair so you can use C++ algorithms that rely on pairs. + */ +class field : public std::pair { +public: + /** + * Create a new invalid field. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline field() noexcept; + + /** + * Get the key as a string_view (for higher speed, consider raw_key). + * We deliberately use a more cumbersome name (unescaped_key) to force users + * to think twice about using it. + * + * This consumes the key: once you have called unescaped_key(), you cannot + * call it again nor can you call key(). + */ + simdjson_inline simdjson_warn_unused simdjson_result unescaped_key(bool allow_replacement) noexcept; + /** + * Get the key as a raw_json_string. Can be used for direct comparison with + * an unescaped C string: e.g., key() == "test". + */ + simdjson_inline raw_json_string key() const noexcept; + /** + * Get the field value. + */ + simdjson_inline ondemand::value &value() & noexcept; + /** + * @overload ondemand::value &ondemand::value() & noexcept + */ + simdjson_inline ondemand::value value() && noexcept; + +protected: + simdjson_inline field(raw_json_string key, ondemand::value &&value) noexcept; + static simdjson_inline simdjson_result start(value_iterator &parent_iter) noexcept; + static simdjson_inline simdjson_result start(const value_iterator &parent_iter, raw_json_string key) noexcept; + friend struct simdjson_result; + friend class object_iterator; +}; + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::field &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result unescaped_key(bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result key() noexcept; + simdjson_inline simdjson_result value() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_FIELD_H +/* end file simdjson/generic/ondemand/field.h for arm64 */ +/* including simdjson/generic/ondemand/object.h for arm64: #include "simdjson/generic/ondemand/object.h" */ +/* begin file simdjson/generic/ondemand/object.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +/** + * A forward-only JSON object field iterator. + */ +class object { +public: + /** + * Create a new invalid object. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline object() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. The value instance you get + * from `content["bids"]` becomes invalid when you call `content["asks"]`. The array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a + * key a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field(std::string_view key) && noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. The value instance you get + * from `content["bids"]` becomes invalid when you call `content["asks"]`. The array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a key + * a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) && noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) && noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard, interpreting the current node + * as the root of its own JSON document. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. Yet it is not the case when calling at_pointer on an object + * instance: there is no rewind and no invalidation. + * + * You may call at_pointer more than once on an object, but each time the pointer is advanced + * to be within the value matched by the key indicated by the JSON pointer query. Thus any preceding + * key (as well as the current key) can no longer be used with following JSON pointer calls. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching. + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + + /** + * Reset the iterator so that we are pointing back at the + * beginning of the object. You should still consume values only once even if you + * can iterate through the object more than once. If you unescape a string within + * the object more than once, you have unsafe code. Note that rewinding an object + * means that you may need to reparse it anew: it is not a free operation. + * + * @returns true if the object contains some elements (not empty) + */ + inline simdjson_result reset() & noexcept; + /** + * This method scans the beginning of the object and checks whether the + * object is empty. + * The runtime complexity is constant time. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + inline simdjson_result is_empty() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method. + * + * Performance hint: You should only call count_fields() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Consumes the object and returns a string_view instance corresponding to the + * object as represented in JSON. It points inside the original byte array containing + * the JSON document. + */ + simdjson_inline simdjson_result raw_json() noexcept; + +protected: + /** + * Go to the end of the object, no matter where you are right now. + */ + simdjson_inline error_code consume() noexcept; + static simdjson_inline simdjson_result start(value_iterator &iter) noexcept; + static simdjson_inline simdjson_result start_root(value_iterator &iter) noexcept; + static simdjson_inline simdjson_result started(value_iterator &iter) noexcept; + static simdjson_inline object resume(const value_iterator &iter) noexcept; + simdjson_inline object(const value_iterator &iter) noexcept; + + simdjson_warn_unused simdjson_inline error_code find_field_raw(const std::string_view key) noexcept; + + value_iterator iter{}; + + friend class value; + friend class document; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::object &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) && noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) && noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) && noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + inline simdjson_result reset() noexcept; + inline simdjson_result is_empty() noexcept; + inline simdjson_result count_fields() & noexcept; + inline simdjson_result raw_json() noexcept; + +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_H +/* end file simdjson/generic/ondemand/object.h for arm64 */ +/* including simdjson/generic/ondemand/object_iterator.h for arm64: #include "simdjson/generic/ondemand/object_iterator.h" */ +/* begin file simdjson/generic/ondemand/object_iterator.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +class object_iterator { +public: + /** + * Create a new invalid object_iterator. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline object_iterator() noexcept = default; + + // + // Iterator interface + // + + // Reads key and value, yielding them to the user. + // MUST ONLY BE CALLED ONCE PER ITERATION. + simdjson_inline simdjson_result operator*() noexcept; + // Assumes it's being compared with the end. true if depth < iter->depth. + simdjson_inline bool operator==(const object_iterator &) const noexcept; + // Assumes it's being compared with the end. true if depth >= iter->depth. + simdjson_inline bool operator!=(const object_iterator &) const noexcept; + // Checks for ']' and ',' + simdjson_inline object_iterator &operator++() noexcept; + +private: + /** + * The underlying JSON iterator. + * + * PERF NOTE: expected to be elided in favor of the parent document: this is set when the object + * is first used, and never changes afterwards. + */ + value_iterator iter{}; + + simdjson_inline object_iterator(const value_iterator &iter) noexcept; + friend struct simdjson_result; + friend class object; +}; + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public arm64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(arm64::ondemand::object_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + // + // Iterator interface + // + + // Reads key and value, yielding them to the user. + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + // Assumes it's being compared with the end. true if depth < iter->depth. + simdjson_inline bool operator==(const simdjson_result &) const noexcept; + // Assumes it's being compared with the end. true if depth >= iter->depth. + simdjson_inline bool operator!=(const simdjson_result &) const noexcept; + // Checks for ']' and ',' + simdjson_inline simdjson_result &operator++() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H +/* end file simdjson/generic/ondemand/object_iterator.h for arm64 */ +/* including simdjson/generic/ondemand/serialization.h for arm64: #include "simdjson/generic/ondemand/serialization.h" */ +/* begin file simdjson/generic/ondemand/serialization.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Create a string-view instance out of a document instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(arm64::ondemand::document& x) noexcept; +/** + * Create a string-view instance out of a value instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. The value must + * not have been accessed previously. It does not + * validate the content. + */ +inline simdjson_result to_json_string(arm64::ondemand::value& x) noexcept; +/** + * Create a string-view instance out of an object instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(arm64::ondemand::object& x) noexcept; +/** + * Create a string-view instance out of an array instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(arm64::ondemand::array& x) noexcept; +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +} // namespace simdjson + +/** + * We want to support argument-dependent lookup (ADL). + * Hence we should define operator<< in the namespace + * where the argument (here value, object, etc.) resides. + * Credit: @madhur4127 + * See https://github.com/simdjson/simdjson/issues/1768 + */ +namespace simdjson { namespace arm64 { namespace ondemand { + +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The element. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::arm64::ondemand::value x); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The array. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::arm64::ondemand::array value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The array. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::arm64::ondemand::document& value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x); +#endif +inline std::ostream& operator<<(std::ostream& out, simdjson::arm64::ondemand::document_reference& value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The object. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::arm64::ondemand::object value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +}}} // namespace simdjson::arm64::ondemand + +#endif // SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H +/* end file simdjson/generic/ondemand/serialization.h for arm64 */ + +// Inline definitions +/* including simdjson/generic/ondemand/array-inl.h for arm64: #include "simdjson/generic/ondemand/array-inl.h" */ +/* begin file simdjson/generic/ondemand/array-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +// +// ### Live States +// +// While iterating or looking up values, depth >= iter->depth. at_start may vary. Error is +// always SUCCESS: +// +// - Start: This is the state when the array is first found and the iterator is just past the `{`. +// In this state, at_start == true. +// - Next: After we hand a scalar value to the user, or an array/object which they then fully +// iterate over, the iterator is at the `,` before the next value (or `]`). In this state, +// depth == iter->depth, at_start == false, and error == SUCCESS. +// - Unfinished Business: When we hand an array/object to the user which they do not fully +// iterate over, we need to finish that iteration by skipping child values until we reach the +// Next state. In this state, depth > iter->depth, at_start == false, and error == SUCCESS. +// +// ## Error States +// +// In error states, we will yield exactly one more value before stopping. iter->depth == depth +// and at_start is always false. We decrement after yielding the error, moving to the Finished +// state. +// +// - Chained Error: When the array iterator is part of an error chain--for example, in +// `for (auto tweet : doc["tweets"])`, where the tweet element may be missing or not be an +// array--we yield that error in the loop, exactly once. In this state, error != SUCCESS and +// iter->depth == depth, and at_start == false. We decrement depth when we yield the error. +// - Missing Comma Error: When the iterator ++ method discovers there is no comma between elements, +// we flag that as an error and treat it exactly the same as a Chained Error. In this state, +// error == TAPE_ERROR, iter->depth == depth, and at_start == false. +// +// ## Terminal State +// +// The terminal state has iter->depth < depth. at_start is always false. +// +// - Finished: When we have reached a `]` or have reported an error, we are finished. We signal this +// by decrementing depth. In this state, iter->depth < depth, at_start == false, and +// error == SUCCESS. +// + +simdjson_inline array::array(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} + +simdjson_inline simdjson_result array::start(value_iterator &iter) noexcept { + // We don't need to know if the array is empty to start iteration, but we do want to know if there + // is an error--thus `simdjson_unused`. + simdjson_unused bool has_value; + SIMDJSON_TRY( iter.start_array().get(has_value) ); + return array(iter); +} +simdjson_inline simdjson_result array::start_root(value_iterator &iter) noexcept { + simdjson_unused bool has_value; + SIMDJSON_TRY( iter.start_root_array().get(has_value) ); + return array(iter); +} +simdjson_inline simdjson_result array::started(value_iterator &iter) noexcept { + bool has_value; + SIMDJSON_TRY(iter.started_array().get(has_value)); + return array(iter); +} + +simdjson_inline simdjson_result array::begin() noexcept { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + return array_iterator(iter); +} +simdjson_inline simdjson_result array::end() noexcept { + return array_iterator(iter); +} +simdjson_inline error_code array::consume() noexcept { + auto error = iter.json_iter().skip_child(iter.depth()-1); + if(error) { iter.abandon(); } + return error; +} + +simdjson_inline simdjson_result array::raw_json() noexcept { + const uint8_t * starting_point{iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + // After 'consume()', we could be left pointing just beyond the document, but that + // is ok because we are not going to dereference the final pointer position, we just + // use it to compute the length in bytes. + const uint8_t * final_point{iter._json_iter->unsafe_pointer()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline simdjson_result array::count_elements() & noexcept { + size_t count{0}; + // Important: we do not consume any of the values. + for(simdjson_unused auto v : *this) { count++; } + // The above loop will always succeed, but we want to report errors. + if(iter.error()) { return iter.error(); } + // We need to move back at the start because we expect users to iterate through + // the array after counting the number of elements. + iter.reset_array(); + return count; +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline simdjson_result array::is_empty() & noexcept { + bool is_not_empty; + auto error = iter.reset_array().get(is_not_empty); + if(error) { return error; } + return !is_not_empty; +} + +inline simdjson_result array::reset() & noexcept { + return iter.reset_array(); +} + +inline simdjson_result array::at_pointer(std::string_view json_pointer) noexcept { + if (json_pointer[0] != '/') { return INVALID_JSON_POINTER; } + json_pointer = json_pointer.substr(1); + // - 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; } + + // Read the array index + size_t array_index = 0; + size_t i; + for (i = 0; i < json_pointer.length() && json_pointer[i] != '/'; i++) { + uint8_t digit = uint8_t(json_pointer[i] - '0'); + // Check for non-digit in array index. If it's there, we're trying to get a field in an object + if (digit > 9) { return INCORRECT_TYPE; } + array_index = array_index*10 + digit; + } + + // 0 followed by other digits is invalid + if (i > 1 && json_pointer[0] == '0') { return INVALID_JSON_POINTER; } // "JSON pointer array index has other characters after 0" + + // Empty string is invalid; so is a "/" with no digits before it + if (i == 0) { return INVALID_JSON_POINTER; } // "Empty string in JSON pointer array index" + // Get the child + auto child = at(array_index); + // If there is an error, it ends here + if(child.error()) { + return child; + } + + // If there is a /, we're not done yet, call recursively. + if (i < json_pointer.length()) { + child = child.at_pointer(json_pointer.substr(i)); + } + return child; +} + +simdjson_inline simdjson_result array::at(size_t index) noexcept { + size_t i = 0; + for (auto value : *this) { + if (i == index) { return value; } + i++; + } + return INDEX_OUT_OF_BOUNDS; +} + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + arm64::ondemand::array &&value +) noexcept + : implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept + : implementation_simdjson_result_base(error) +{ +} + +simdjson_inline simdjson_result simdjson_result::begin() noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() noexcept { + if (error()) { return error(); } + return first.end(); +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::is_empty() & noexcept { + if (error()) { return error(); } + return first.is_empty(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H +/* end file simdjson/generic/ondemand/array-inl.h for arm64 */ +/* including simdjson/generic/ondemand/array_iterator-inl.h for arm64: #include "simdjson/generic/ondemand/array_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/array_iterator-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +simdjson_inline array_iterator::array_iterator(const value_iterator &_iter) noexcept + : iter{_iter} +{} + +simdjson_inline simdjson_result array_iterator::operator*() noexcept { + if (iter.error()) { iter.abandon(); return iter.error(); } + return value(iter.child()); +} +simdjson_inline bool array_iterator::operator==(const array_iterator &other) const noexcept { + return !(*this != other); +} +simdjson_inline bool array_iterator::operator!=(const array_iterator &) const noexcept { + return iter.is_open(); +} +simdjson_inline array_iterator &array_iterator::operator++() noexcept { + error_code error; + // PERF NOTE this is a safety rail ... users should exit loops as soon as they receive an error, so we'll never get here. + // However, it does not seem to make a perf difference, so we add it out of an abundance of caution. + if (( error = iter.error() )) { return *this; } + if (( error = iter.skip_child() )) { return *this; } + if (( error = iter.has_next_element().error() )) { return *this; } + return *this; +} + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + arm64::ondemand::array_iterator &&value +) noexcept + : arm64::implementation_simdjson_result_base(std::forward(value)) +{ + first.iter.assert_is_valid(); +} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : arm64::implementation_simdjson_result_base({}, error) +{ +} + +simdjson_inline simdjson_result simdjson_result::operator*() noexcept { + if (error()) { return error(); } + return *first; +} +simdjson_inline bool simdjson_result::operator==(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return !error(); } + return first == other.first; +} +simdjson_inline bool simdjson_result::operator!=(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return error(); } + return first != other.first; +} +simdjson_inline simdjson_result &simdjson_result::operator++() noexcept { + // Clear the error if there is one, so we don't yield it twice + if (error()) { second = SUCCESS; return *this; } + ++(first); + return *this; +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/array_iterator-inl.h for arm64 */ +/* including simdjson/generic/ondemand/document-inl.h for arm64: #include "simdjson/generic/ondemand/document-inl.h" */ +/* begin file simdjson/generic/ondemand/document-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +simdjson_inline document::document(ondemand::json_iterator &&_iter) noexcept + : iter{std::forward(_iter)} +{ + logger::log_start_value(iter, "document"); +} + +simdjson_inline document document::start(json_iterator &&iter) noexcept { + return document(std::forward(iter)); +} + +inline void document::rewind() noexcept { + iter.rewind(); +} + +inline std::string document::to_debug_string() noexcept { + return iter.to_string(); +} + +inline simdjson_result document::current_location() const noexcept { + return iter.current_location(); +} + +inline int32_t document::current_depth() const noexcept { + return iter.depth(); +} + +inline bool document::at_end() const noexcept { + return iter.at_end(); +} + + +inline bool document::is_alive() noexcept { + return iter.is_alive(); +} +simdjson_inline value_iterator document::resume_value_iterator() noexcept { + return value_iterator(&iter, 1, iter.root_position()); +} +simdjson_inline value_iterator document::get_root_value_iterator() noexcept { + return resume_value_iterator(); +} +simdjson_inline simdjson_result document::start_or_resume_object() noexcept { + if (iter.at_root()) { + return get_object(); + } else { + return object::resume(resume_value_iterator()); + } +} +simdjson_inline simdjson_result document::get_value() noexcept { + // Make sure we start any arrays or objects before returning, so that start_root_() + // gets called. + + // It is the convention throughout the code that the macro `SIMDJSON_DEVELOPMENT_CHECKS` determines whether + // we check for OUT_OF_ORDER_ITERATION. Proper on::demand code should never trigger this error. +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.at_root()) { return OUT_OF_ORDER_ITERATION; } +#endif + // assert_at_root() serves two purposes: in Debug mode, whether or not + // SIMDJSON_DEVELOPMENT_CHECKS is set or not, it checks that we are at the root of + // the document (this will typically be redundant). In release mode, it generates + // SIMDJSON_ASSUME statements to allow the compiler to make assumptions. + iter.assert_at_root(); + switch (*iter.peek()) { + case '[': { + // The following lines check that the document ends with ]. + auto value_iterator = get_root_value_iterator(); + auto error = value_iterator.check_root_array(); + if(error) { return error; } + return value(get_root_value_iterator()); + } + case '{': { + // The following lines would check that the document ends with }. + auto value_iterator = get_root_value_iterator(); + auto error = value_iterator.check_root_object(); + if(error) { return error; } + return value(get_root_value_iterator()); + } + default: + // Unfortunately, scalar documents are a special case in simdjson and they cannot + // be safely converted to value instances. + return SCALAR_DOCUMENT_AS_VALUE; + } +} +simdjson_inline simdjson_result document::get_array() & noexcept { + auto value = get_root_value_iterator(); + return array::start_root(value); +} +simdjson_inline simdjson_result document::get_object() & noexcept { + auto value = get_root_value_iterator(); + return object::start_root(value); +} + +/** + * We decided that calling 'get_double()' on the JSON document '1.233 blabla' should + * give an error, so we check for trailing content. We want to disallow trailing + * content. + * Thus, in several implementations below, we pass a 'true' parameter value to + * a get_root_value_iterator() method: this indicates that we disallow trailing content. + */ + +simdjson_inline simdjson_result document::get_uint64() noexcept { + return get_root_value_iterator().get_root_uint64(true); +} +simdjson_inline simdjson_result document::get_uint64_in_string() noexcept { + return get_root_value_iterator().get_root_uint64_in_string(true); +} +simdjson_inline simdjson_result document::get_int64() noexcept { + return get_root_value_iterator().get_root_int64(true); +} +simdjson_inline simdjson_result document::get_int64_in_string() noexcept { + return get_root_value_iterator().get_root_int64_in_string(true); +} +simdjson_inline simdjson_result document::get_double() noexcept { + return get_root_value_iterator().get_root_double(true); +} +simdjson_inline simdjson_result document::get_double_in_string() noexcept { + return get_root_value_iterator().get_root_double_in_string(true); +} +simdjson_inline simdjson_result document::get_string(bool allow_replacement) noexcept { + return get_root_value_iterator().get_root_string(true, allow_replacement); +} +template +simdjson_inline error_code document::get_string(string_type& receiver, bool allow_replacement) noexcept { + return get_root_value_iterator().get_root_string(receiver, true, allow_replacement); +} +simdjson_inline simdjson_result document::get_wobbly_string() noexcept { + return get_root_value_iterator().get_root_wobbly_string(true); +} +simdjson_inline simdjson_result document::get_raw_json_string() noexcept { + return get_root_value_iterator().get_root_raw_json_string(true); +} +simdjson_inline simdjson_result document::get_bool() noexcept { + return get_root_value_iterator().get_root_bool(true); +} +simdjson_inline simdjson_result document::is_null() noexcept { + return get_root_value_iterator().is_root_null(true); +} + +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_array(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_object(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_double(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_uint64(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_int64(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_bool(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_value(); } + +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_double(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_uint64(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_int64(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_bool(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_value(); } + +template simdjson_inline error_code document::get(T &out) & noexcept { + return get().get(out); +} +template simdjson_inline error_code document::get(T &out) && noexcept { + return std::forward(*this).get().get(out); +} + +#if SIMDJSON_EXCEPTIONS +simdjson_inline document::operator array() & noexcept(false) { return get_array(); } +simdjson_inline document::operator object() & noexcept(false) { return get_object(); } +simdjson_inline document::operator uint64_t() noexcept(false) { return get_uint64(); } +simdjson_inline document::operator int64_t() noexcept(false) { return get_int64(); } +simdjson_inline document::operator double() noexcept(false) { return get_double(); } +simdjson_inline document::operator std::string_view() noexcept(false) { return get_string(false); } +simdjson_inline document::operator raw_json_string() noexcept(false) { return get_raw_json_string(); } +simdjson_inline document::operator bool() noexcept(false) { return get_bool(); } +simdjson_inline document::operator value() noexcept(false) { return get_value(); } + +#endif +simdjson_inline simdjson_result document::count_elements() & noexcept { + auto a = get_array(); + simdjson_result answer = a.count_elements(); + /* If there was an array, we are now left pointing at its first element. */ + if(answer.error() == SUCCESS) { rewind(); } + return answer; +} +simdjson_inline simdjson_result document::count_fields() & noexcept { + auto a = get_object(); + simdjson_result answer = a.count_fields(); + /* If there was an object, we are now left pointing at its first element. */ + if(answer.error() == SUCCESS) { rewind(); } + return answer; +} +simdjson_inline simdjson_result document::at(size_t index) & noexcept { + auto a = get_array(); + return a.at(index); +} +simdjson_inline simdjson_result document::begin() & noexcept { + return get_array().begin(); +} +simdjson_inline simdjson_result document::end() & noexcept { + return {}; +} + +simdjson_inline simdjson_result document::find_field(std::string_view key) & noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result document::find_field(const char *key) & noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result document::find_field_unordered(std::string_view key) & noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result document::find_field_unordered(const char *key) & noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result document::operator[](std::string_view key) & noexcept { + return start_or_resume_object()[key]; +} +simdjson_inline simdjson_result document::operator[](const char *key) & noexcept { + return start_or_resume_object()[key]; +} + +simdjson_inline error_code document::consume() noexcept { + auto error = iter.skip_child(0); + if(error) { iter.abandon(); } + return error; +} + +simdjson_inline simdjson_result document::raw_json() noexcept { + auto _iter = get_root_value_iterator(); + const uint8_t * starting_point{_iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + // After 'consume()', we could be left pointing just beyond the document, but that + // is ok because we are not going to dereference the final pointer position, we just + // use it to compute the length in bytes. + const uint8_t * final_point{iter.unsafe_pointer()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +simdjson_inline simdjson_result document::type() noexcept { + return get_root_value_iterator().type(); +} + +simdjson_inline simdjson_result document::is_scalar() noexcept { + json_type this_type; + auto error = type().get(this_type); + if(error) { return error; } + return ! ((this_type == json_type::array) || (this_type == json_type::object)); +} + +simdjson_inline bool document::is_negative() noexcept { + return get_root_value_iterator().is_root_negative(); +} + +simdjson_inline simdjson_result document::is_integer() noexcept { + return get_root_value_iterator().is_root_integer(true); +} + +simdjson_inline simdjson_result document::get_number_type() noexcept { + return get_root_value_iterator().get_root_number_type(true); +} + +simdjson_inline simdjson_result document::get_number() noexcept { + return get_root_value_iterator().get_root_number(true); +} + + +simdjson_inline simdjson_result document::raw_json_token() noexcept { + auto _iter = get_root_value_iterator(); + return std::string_view(reinterpret_cast(_iter.peek_start()), _iter.peek_start_length()); +} + +simdjson_inline simdjson_result document::at_pointer(std::string_view json_pointer) noexcept { + rewind(); // Rewind the document each time at_pointer is called + if (json_pointer.empty()) { + return this->get_value(); + } + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: + return (*this).get_array().at_pointer(json_pointer); + case json_type::object: + return (*this).get_object().at_pointer(json_pointer); + default: + return INVALID_JSON_POINTER; + } +} + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + arm64::ondemand::document &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base( + error + ) +{ +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) & noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline error_code simdjson_result::rewind() noexcept { + if (error()) { return error(); } + first.rewind(); + return SUCCESS; +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::get_array() & noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() & noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::get_value() noexcept { + if (error()) { return error(); } + return first.get_value(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} + +template +simdjson_inline simdjson_result simdjson_result::get() & noexcept { + if (error()) { return error(); } + return first.get(); +} +template +simdjson_inline simdjson_result simdjson_result::get() && noexcept { + if (error()) { return error(); } + return std::forward(first).get(); +} +template +simdjson_inline error_code simdjson_result::get(T &out) & noexcept { + if (error()) { return error(); } + return first.get(out); +} +template +simdjson_inline error_code simdjson_result::get(T &out) && noexcept { + if (error()) { return error(); } + return std::forward(first).get(out); +} + +template<> simdjson_inline simdjson_result simdjson_result::get() & noexcept = delete; +template<> simdjson_inline simdjson_result simdjson_result::get() && noexcept { + if (error()) { return error(); } + return std::forward(first); +} +template<> simdjson_inline error_code simdjson_result::get(arm64::ondemand::document &out) & noexcept = delete; +template<> simdjson_inline error_code simdjson_result::get(arm64::ondemand::document &out) && noexcept { + if (error()) { return error(); } + out = std::forward(first); + return SUCCESS; +} + +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} + +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} + + +simdjson_inline bool simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} + +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} + +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} + +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} + + +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator arm64::ondemand::array() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator arm64::ondemand::object() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator arm64::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator arm64::ondemand::value() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline bool simdjson_result::at_end() const noexcept { + if (error()) { return error(); } + return first.at_end(); +} + + +simdjson_inline int32_t simdjson_result::current_depth() const noexcept { + if (error()) { return error(); } + return first.current_depth(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + + +} // namespace simdjson + + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +simdjson_inline document_reference::document_reference() noexcept : doc{nullptr} {} +simdjson_inline document_reference::document_reference(document &d) noexcept : doc(&d) {} +simdjson_inline void document_reference::rewind() noexcept { doc->rewind(); } +simdjson_inline simdjson_result document_reference::get_array() & noexcept { return doc->get_array(); } +simdjson_inline simdjson_result document_reference::get_object() & noexcept { return doc->get_object(); } +/** + * The document_reference instances are used primarily/solely for streams of JSON + * documents. + * We decided that calling 'get_double()' on the JSON document '1.233 blabla' should + * give an error, so we check for trailing content. + * + * However, for streams of JSON documents, we want to be able to start from + * "321" "321" "321" + * and parse it successfully as a stream of JSON documents, calling get_uint64_in_string() + * successfully each time. + * + * To achieve this result, we pass a 'false' to a get_root_value_iterator() method: + * this indicates that we allow trailing content. + */ +simdjson_inline simdjson_result document_reference::get_uint64() noexcept { return doc->get_root_value_iterator().get_root_uint64(false); } +simdjson_inline simdjson_result document_reference::get_uint64_in_string() noexcept { return doc->get_root_value_iterator().get_root_uint64_in_string(false); } +simdjson_inline simdjson_result document_reference::get_int64() noexcept { return doc->get_root_value_iterator().get_root_int64(false); } +simdjson_inline simdjson_result document_reference::get_int64_in_string() noexcept { return doc->get_root_value_iterator().get_root_int64_in_string(false); } +simdjson_inline simdjson_result document_reference::get_double() noexcept { return doc->get_root_value_iterator().get_root_double(false); } +simdjson_inline simdjson_result document_reference::get_double_in_string() noexcept { return doc->get_root_value_iterator().get_root_double(false); } +simdjson_inline simdjson_result document_reference::get_string(bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(false, allow_replacement); } +template +simdjson_inline error_code document_reference::get_string(string_type& receiver, bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(receiver, false, allow_replacement); } +simdjson_inline simdjson_result document_reference::get_wobbly_string() noexcept { return doc->get_root_value_iterator().get_root_wobbly_string(false); } +simdjson_inline simdjson_result document_reference::get_raw_json_string() noexcept { return doc->get_root_value_iterator().get_root_raw_json_string(false); } +simdjson_inline simdjson_result document_reference::get_bool() noexcept { return doc->get_root_value_iterator().get_root_bool(false); } +simdjson_inline simdjson_result document_reference::get_value() noexcept { return doc->get_value(); } +simdjson_inline simdjson_result document_reference::is_null() noexcept { return doc->get_root_value_iterator().is_root_null(false); } + +#if SIMDJSON_EXCEPTIONS +simdjson_inline document_reference::operator array() & noexcept(false) { return array(*doc); } +simdjson_inline document_reference::operator object() & noexcept(false) { return object(*doc); } +simdjson_inline document_reference::operator uint64_t() noexcept(false) { return get_uint64(); } +simdjson_inline document_reference::operator int64_t() noexcept(false) { return get_int64(); } +simdjson_inline document_reference::operator double() noexcept(false) { return get_double(); } +simdjson_inline document_reference::operator std::string_view() noexcept(false) { return std::string_view(*doc); } +simdjson_inline document_reference::operator raw_json_string() noexcept(false) { return raw_json_string(*doc); } +simdjson_inline document_reference::operator bool() noexcept(false) { return get_bool(); } +simdjson_inline document_reference::operator value() noexcept(false) { return value(*doc); } +#endif +simdjson_inline simdjson_result document_reference::count_elements() & noexcept { return doc->count_elements(); } +simdjson_inline simdjson_result document_reference::count_fields() & noexcept { return doc->count_fields(); } +simdjson_inline simdjson_result document_reference::at(size_t index) & noexcept { return doc->at(index); } +simdjson_inline simdjson_result document_reference::begin() & noexcept { return doc->begin(); } +simdjson_inline simdjson_result document_reference::end() & noexcept { return doc->end(); } +simdjson_inline simdjson_result document_reference::find_field(std::string_view key) & noexcept { return doc->find_field(key); } +simdjson_inline simdjson_result document_reference::find_field(const char *key) & noexcept { return doc->find_field(key); } +simdjson_inline simdjson_result document_reference::operator[](std::string_view key) & noexcept { return (*doc)[key]; } +simdjson_inline simdjson_result document_reference::operator[](const char *key) & noexcept { return (*doc)[key]; } +simdjson_inline simdjson_result document_reference::find_field_unordered(std::string_view key) & noexcept { return doc->find_field_unordered(key); } +simdjson_inline simdjson_result document_reference::find_field_unordered(const char *key) & noexcept { return doc->find_field_unordered(key); } +simdjson_inline simdjson_result document_reference::type() noexcept { return doc->type(); } +simdjson_inline simdjson_result document_reference::is_scalar() noexcept { return doc->is_scalar(); } +simdjson_inline simdjson_result document_reference::current_location() noexcept { return doc->current_location(); } +simdjson_inline int32_t document_reference::current_depth() const noexcept { return doc->current_depth(); } +simdjson_inline bool document_reference::is_negative() noexcept { return doc->is_negative(); } +simdjson_inline simdjson_result document_reference::is_integer() noexcept { return doc->get_root_value_iterator().is_root_integer(false); } +simdjson_inline simdjson_result document_reference::get_number_type() noexcept { return doc->get_root_value_iterator().get_root_number_type(false); } +simdjson_inline simdjson_result document_reference::get_number() noexcept { return doc->get_root_value_iterator().get_root_number(false); } +simdjson_inline simdjson_result document_reference::raw_json_token() noexcept { return doc->raw_json_token(); } +simdjson_inline simdjson_result document_reference::at_pointer(std::string_view json_pointer) noexcept { return doc->at_pointer(json_pointer); } +simdjson_inline simdjson_result document_reference::raw_json() noexcept { return doc->raw_json();} +simdjson_inline document_reference::operator document&() const noexcept { return *doc; } + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + + + +namespace simdjson { +simdjson_inline simdjson_result::simdjson_result(arm64::ondemand::document_reference value, error_code error) + noexcept : implementation_simdjson_result_base(std::forward(value), error) {} + + +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) & noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline error_code simdjson_result::rewind() noexcept { + if (error()) { return error(); } + first.rewind(); + return SUCCESS; +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::get_array() & noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() & noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::get_value() noexcept { + if (error()) { return error(); } + return first.get_value(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} +simdjson_inline simdjson_result simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator arm64::ondemand::array() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator arm64::ondemand::object() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator arm64::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator arm64::ondemand::value() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H +/* end file simdjson/generic/ondemand/document-inl.h for arm64 */ +/* including simdjson/generic/ondemand/document_stream-inl.h for arm64: #include "simdjson/generic/ondemand/document_stream-inl.h" */ +/* begin file simdjson/generic/ondemand/document_stream-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document_stream.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +#ifdef SIMDJSON_THREADS_ENABLED + +inline void stage1_worker::finish() { + // After calling "run" someone would call finish() to wait + // for the end of the processing. + // This function will wait until either the thread has done + // the processing or, else, the destructor has been called. + std::unique_lock lock(locking_mutex); + cond_var.wait(lock, [this]{return has_work == false;}); +} + +inline stage1_worker::~stage1_worker() { + // The thread may never outlive the stage1_worker instance + // and will always be stopped/joined before the stage1_worker + // instance is gone. + stop_thread(); +} + +inline void stage1_worker::start_thread() { + std::unique_lock lock(locking_mutex); + if(thread.joinable()) { + return; // This should never happen but we never want to create more than one thread. + } + thread = std::thread([this]{ + while(true) { + std::unique_lock thread_lock(locking_mutex); + // We wait for either "run" or "stop_thread" to be called. + cond_var.wait(thread_lock, [this]{return has_work || !can_work;}); + // If, for some reason, the stop_thread() method was called (i.e., the + // destructor of stage1_worker is called, then we want to immediately destroy + // the thread (and not do any more processing). + if(!can_work) { + break; + } + this->owner->stage1_thread_error = this->owner->run_stage1(*this->stage1_thread_parser, + this->_next_batch_start); + this->has_work = false; + // The condition variable call should be moved after thread_lock.unlock() for performance + // reasons but thread sanitizers may report it as a data race if we do. + // See https://stackoverflow.com/questions/35775501/c-should-condition-variable-be-notified-under-lock + cond_var.notify_one(); // will notify "finish" + thread_lock.unlock(); + } + } + ); +} + + +inline void stage1_worker::stop_thread() { + std::unique_lock lock(locking_mutex); + // We have to make sure that all locks can be released. + can_work = false; + has_work = false; + cond_var.notify_all(); + lock.unlock(); + if(thread.joinable()) { + thread.join(); + } +} + +inline void stage1_worker::run(document_stream * ds, parser * stage1, size_t next_batch_start) { + std::unique_lock lock(locking_mutex); + owner = ds; + _next_batch_start = next_batch_start; + stage1_thread_parser = stage1; + has_work = true; + // The condition variable call should be moved after thread_lock.unlock() for performance + // reasons but thread sanitizers may report it as a data race if we do. + // See https://stackoverflow.com/questions/35775501/c-should-condition-variable-be-notified-under-lock + cond_var.notify_one(); // will notify the thread lock that we have work + lock.unlock(); +} + +#endif // SIMDJSON_THREADS_ENABLED + +simdjson_inline document_stream::document_stream( + ondemand::parser &_parser, + const uint8_t *_buf, + size_t _len, + size_t _batch_size, + bool _allow_comma_separated +) noexcept + : parser{&_parser}, + buf{_buf}, + len{_len}, + batch_size{_batch_size <= MINIMAL_BATCH_SIZE ? MINIMAL_BATCH_SIZE : _batch_size}, + allow_comma_separated{_allow_comma_separated}, + error{SUCCESS} + #ifdef SIMDJSON_THREADS_ENABLED + , use_thread(_parser.threaded) // we need to make a copy because _parser.threaded can change + #endif +{ +#ifdef SIMDJSON_THREADS_ENABLED + if(worker.get() == nullptr) { + error = MEMALLOC; + } +#endif +} + +simdjson_inline document_stream::document_stream() noexcept + : parser{nullptr}, + buf{nullptr}, + len{0}, + batch_size{0}, + allow_comma_separated{false}, + error{UNINITIALIZED} + #ifdef SIMDJSON_THREADS_ENABLED + , use_thread(false) + #endif +{ +} + +simdjson_inline document_stream::~document_stream() noexcept +{ + #ifdef SIMDJSON_THREADS_ENABLED + worker.reset(); + #endif +} + +inline size_t document_stream::size_in_bytes() const noexcept { + return len; +} + +inline size_t document_stream::truncated_bytes() const noexcept { + if(error == CAPACITY) { return len - batch_start; } + return parser->implementation->structural_indexes[parser->implementation->n_structural_indexes] - parser->implementation->structural_indexes[parser->implementation->n_structural_indexes + 1]; +} + +simdjson_inline document_stream::iterator::iterator() noexcept + : stream{nullptr}, finished{true} { +} + +simdjson_inline document_stream::iterator::iterator(document_stream* _stream, bool is_end) noexcept + : stream{_stream}, finished{is_end} { +} + +simdjson_inline simdjson_result document_stream::iterator::operator*() noexcept { + //if(stream->error) { return stream->error; } + return simdjson_result(stream->doc, stream->error); +} + +simdjson_inline document_stream::iterator& document_stream::iterator::operator++() noexcept { + // If there is an error, then we want the iterator + // to be finished, no matter what. (E.g., we do not + // keep generating documents with errors, or go beyond + // a document with errors.) + // + // Users do not have to call "operator*()" when they use operator++, + // so we need to end the stream in the operator++ function. + // + // Note that setting finished = true is essential otherwise + // we would enter an infinite loop. + if (stream->error) { finished = true; } + // Note that stream->error() is guarded against error conditions + // (it will immediately return if stream->error casts to false). + // In effect, this next function does nothing when (stream->error) + // is true (hence the risk of an infinite loop). + stream->next(); + // If that was the last document, we're finished. + // It is the only type of error we do not want to appear + // in operator*. + if (stream->error == EMPTY) { finished = true; } + // If we had any other kind of error (not EMPTY) then we want + // to pass it along to the operator* and we cannot mark the result + // as "finished" just yet. + return *this; +} + +simdjson_inline bool document_stream::iterator::operator!=(const document_stream::iterator &other) const noexcept { + return finished != other.finished; +} + +simdjson_inline document_stream::iterator document_stream::begin() noexcept { + start(); + // If there are no documents, we're finished. + return iterator(this, error == EMPTY); +} + +simdjson_inline document_stream::iterator document_stream::end() noexcept { + return iterator(this, true); +} + +inline void document_stream::start() noexcept { + if (error) { return; } + error = parser->allocate(batch_size); + if (error) { return; } + // Always run the first stage 1 parse immediately + batch_start = 0; + error = run_stage1(*parser, batch_start); + while(error == EMPTY) { + // In exceptional cases, we may start with an empty block + batch_start = next_batch_start(); + if (batch_start >= len) { return; } + error = run_stage1(*parser, batch_start); + } + if (error) { return; } + doc_index = batch_start; + doc = document(json_iterator(&buf[batch_start], parser)); + doc.iter._streaming = true; + + #ifdef SIMDJSON_THREADS_ENABLED + if (use_thread && next_batch_start() < len) { + // Kick off the first thread on next batch if needed + error = stage1_thread_parser.allocate(batch_size); + if (error) { return; } + worker->start_thread(); + start_stage1_thread(); + if (error) { return; } + } + #endif // SIMDJSON_THREADS_ENABLED +} + +inline void document_stream::next() noexcept { + // We always enter at once once in an error condition. + if (error) { return; } + next_document(); + if (error) { return; } + auto cur_struct_index = doc.iter._root - parser->implementation->structural_indexes.get(); + doc_index = batch_start + parser->implementation->structural_indexes[cur_struct_index]; + + // Check if at end of structural indexes (i.e. at end of batch) + if(cur_struct_index >= static_cast(parser->implementation->n_structural_indexes)) { + error = EMPTY; + // Load another batch (if available) + while (error == EMPTY) { + batch_start = next_batch_start(); + if (batch_start >= len) { break; } + #ifdef SIMDJSON_THREADS_ENABLED + if(use_thread) { + load_from_stage1_thread(); + } else { + error = run_stage1(*parser, batch_start); + } + #else + error = run_stage1(*parser, batch_start); + #endif + /** + * Whenever we move to another window, we need to update all pointers to make + * it appear as if the input buffer started at the beginning of the window. + * + * Take this input: + * + * {"z":5} {"1":1,"2":2,"4":4} [7, 10, 9] [15, 11, 12, 13] [154, 110, 112, 1311] + * + * Say you process the following window... + * + * '{"z":5} {"1":1,"2":2,"4":4} [7, 10, 9]' + * + * When you do so, the json_iterator has a pointer at the beginning of the memory region + * (pointing at the beginning of '{"z"...'. + * + * When you move to the window that starts at... + * + * '[7, 10, 9] [15, 11, 12, 13] ... + * + * then it is not sufficient to just run stage 1. You also need to re-anchor the + * json_iterator so that it believes we are starting at '[7, 10, 9]...'. + * + * Under the DOM front-end, this gets done automatically because the parser owns + * the pointer the data, and when you call stage1 and then stage2 on the same + * parser, then stage2 will run on the pointer acquired by stage1. + * + * That is, stage1 calls "this->buf = _buf" so the parser remembers the buffer that + * we used. But json_iterator has no callback when stage1 is called on the parser. + * In fact, I think that the parser is unaware of json_iterator. + * + * + * So we need to re-anchor the json_iterator after each call to stage 1 so that + * all of the pointers are in sync. + */ + doc.iter = json_iterator(&buf[batch_start], parser); + doc.iter._streaming = true; + /** + * End of resync. + */ + + if (error) { continue; } // If the error was EMPTY, we may want to load another batch. + doc_index = batch_start; + } + } +} + +inline void document_stream::next_document() noexcept { + // Go to next place where depth=0 (document depth) + error = doc.iter.skip_child(0); + if (error) { return; } + // Always set depth=1 at the start of document + doc.iter._depth = 1; + // consume comma if comma separated is allowed + if (allow_comma_separated) { doc.iter.consume_character(','); } + // Resets the string buffer at the beginning, thus invalidating the strings. + doc.iter._string_buf_loc = parser->string_buf.get(); + doc.iter._root = doc.iter.position(); +} + +inline size_t document_stream::next_batch_start() const noexcept { + return batch_start + parser->implementation->structural_indexes[parser->implementation->n_structural_indexes]; +} + +inline error_code document_stream::run_stage1(ondemand::parser &p, size_t _batch_start) noexcept { + // This code only updates the structural index in the parser, it does not update any json_iterator + // instance. + size_t remaining = len - _batch_start; + if (remaining <= batch_size) { + return p.implementation->stage1(&buf[_batch_start], remaining, stage1_mode::streaming_final); + } else { + return p.implementation->stage1(&buf[_batch_start], batch_size, stage1_mode::streaming_partial); + } +} + +simdjson_inline size_t document_stream::iterator::current_index() const noexcept { + return stream->doc_index; +} + +simdjson_inline std::string_view document_stream::iterator::source() const noexcept { + auto depth = stream->doc.iter.depth(); + auto cur_struct_index = stream->doc.iter._root - stream->parser->implementation->structural_indexes.get(); + + // If at root, process the first token to determine if scalar value + if (stream->doc.iter.at_root()) { + switch (stream->buf[stream->batch_start + stream->parser->implementation->structural_indexes[cur_struct_index]]) { + case '{': case '[': // Depth=1 already at start of document + break; + case '}': case ']': + depth--; + break; + default: // Scalar value document + // TODO: Remove any trailing whitespaces + // This returns a string spanning from start of value to the beginning of the next document (excluded) + return std::string_view(reinterpret_cast(stream->buf) + current_index(), stream->parser->implementation->structural_indexes[++cur_struct_index] - current_index() - 1); + } + cur_struct_index++; + } + + while (cur_struct_index <= static_cast(stream->parser->implementation->n_structural_indexes)) { + switch (stream->buf[stream->batch_start + stream->parser->implementation->structural_indexes[cur_struct_index]]) { + case '{': case '[': + depth++; + break; + case '}': case ']': + depth--; + break; + } + if (depth == 0) { break; } + cur_struct_index++; + } + + return std::string_view(reinterpret_cast(stream->buf) + current_index(), stream->parser->implementation->structural_indexes[cur_struct_index] - current_index() + stream->batch_start + 1);; +} + +inline error_code document_stream::iterator::error() const noexcept { + return stream->error; +} + +#ifdef SIMDJSON_THREADS_ENABLED + +inline void document_stream::load_from_stage1_thread() noexcept { + worker->finish(); + // Swap to the parser that was loaded up in the thread. Make sure the parser has + // enough memory to swap to, as well. + std::swap(stage1_thread_parser,*parser); + error = stage1_thread_error; + if (error) { return; } + + // If there's anything left, start the stage 1 thread! + if (next_batch_start() < len) { + start_stage1_thread(); + } +} + +inline void document_stream::start_stage1_thread() noexcept { + // we call the thread on a lambda that will update + // this->stage1_thread_error + // there is only one thread that may write to this value + // TODO this is NOT exception-safe. + this->stage1_thread_error = UNINITIALIZED; // In case something goes wrong, make sure it's an error + size_t _next_batch_start = this->next_batch_start(); + + worker->run(this, & this->stage1_thread_parser, _next_batch_start); +} + +#endif // SIMDJSON_THREADS_ENABLED + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} +simdjson_inline simdjson_result::simdjson_result( + arm64::ondemand::document_stream &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} + +} + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H +/* end file simdjson/generic/ondemand/document_stream-inl.h for arm64 */ +/* including simdjson/generic/ondemand/field-inl.h for arm64: #include "simdjson/generic/ondemand/field-inl.h" */ +/* begin file simdjson/generic/ondemand/field-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +// clang 6 doesn't think the default constructor can be noexcept, so we make it explicit +simdjson_inline field::field() noexcept : std::pair() {} + +simdjson_inline field::field(raw_json_string key, ondemand::value &&value) noexcept + : std::pair(key, std::forward(value)) +{ +} + +simdjson_inline simdjson_result field::start(value_iterator &parent_iter) noexcept { + raw_json_string key; + SIMDJSON_TRY( parent_iter.field_key().get(key) ); + SIMDJSON_TRY( parent_iter.field_value() ); + return field::start(parent_iter, key); +} + +simdjson_inline simdjson_result field::start(const value_iterator &parent_iter, raw_json_string key) noexcept { + return field(key, parent_iter.child()); +} + +simdjson_inline simdjson_warn_unused simdjson_result field::unescaped_key(bool allow_replacement) noexcept { + SIMDJSON_ASSUME(first.buf != nullptr); // We would like to call .alive() but Visual Studio won't let us. + simdjson_result answer = first.unescape(second.iter.json_iter(), allow_replacement); + first.consume(); + return answer; +} + +simdjson_inline raw_json_string field::key() const noexcept { + SIMDJSON_ASSUME(first.buf != nullptr); // We would like to call .alive() by Visual Studio won't let us. + return first; +} + +simdjson_inline value &field::value() & noexcept { + return second; +} + +simdjson_inline value field::value() && noexcept { + return std::forward(*this).second; +} + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + arm64::ondemand::field &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} + +simdjson_inline simdjson_result simdjson_result::key() noexcept { + if (error()) { return error(); } + return first.key(); +} +simdjson_inline simdjson_result simdjson_result::unescaped_key(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.unescaped_key(allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::value() noexcept { + if (error()) { return error(); } + return std::move(first.value()); +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H +/* end file simdjson/generic/ondemand/field-inl.h for arm64 */ +/* including simdjson/generic/ondemand/json_iterator-inl.h for arm64: #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/json_iterator-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +simdjson_inline json_iterator::json_iterator(json_iterator &&other) noexcept + : token(std::forward(other.token)), + parser{other.parser}, + _string_buf_loc{other._string_buf_loc}, + error{other.error}, + _depth{other._depth}, + _root{other._root}, + _streaming{other._streaming} +{ + other.parser = nullptr; +} +simdjson_inline json_iterator &json_iterator::operator=(json_iterator &&other) noexcept { + token = other.token; + parser = other.parser; + _string_buf_loc = other._string_buf_loc; + error = other.error; + _depth = other._depth; + _root = other._root; + _streaming = other._streaming; + other.parser = nullptr; + return *this; +} + +simdjson_inline json_iterator::json_iterator(const uint8_t *buf, ondemand::parser *_parser) noexcept + : token(buf, &_parser->implementation->structural_indexes[0]), + parser{_parser}, + _string_buf_loc{parser->string_buf.get()}, + _depth{1}, + _root{parser->implementation->structural_indexes.get()}, + _streaming{false} + +{ + logger::log_headers(); +#if SIMDJSON_CHECK_EOF + assert_more_tokens(); +#endif +} + +inline void json_iterator::rewind() noexcept { + token.set_position( root_position() ); + logger::log_headers(); // We start again + _string_buf_loc = parser->string_buf.get(); + _depth = 1; +} + +inline bool json_iterator::balanced() const noexcept { + token_iterator ti(token); + int32_t count{0}; + ti.set_position( root_position() ); + while(ti.peek() <= peek_last()) { + switch (*ti.return_current_and_advance()) + { + case '[': case '{': + count++; + break; + case ']': case '}': + count--; + break; + default: + break; + } + } + return count == 0; +} + + +// GCC 7 warns when the first line of this function is inlined away into oblivion due to the caller +// relating depth and parent_depth, which is a desired effect. The warning does not show up if the +// skip_child() function is not marked inline). +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_warn_unused simdjson_inline error_code json_iterator::skip_child(depth_t parent_depth) noexcept { + if (depth() <= parent_depth) { return SUCCESS; } + switch (*return_current_and_advance()) { + // TODO consider whether matching braces is a requirement: if non-matching braces indicates + // *missing* braces, then future lookups are not in the object/arrays they think they are, + // violating the rule "validate enough structure that the user can be confident they are + // looking at the right values." + // PERF TODO we can eliminate the switch here with a lookup of how much to add to depth + + // For the first open array/object in a value, we've already incremented depth, so keep it the same + // We never stop at colon, but if we did, it wouldn't affect depth + case '[': case '{': case ':': + logger::log_start_value(*this, "skip"); + break; + // If there is a comma, we have just finished a value in an array/object, and need to get back in + case ',': + logger::log_value(*this, "skip"); + break; + // ] or } means we just finished a value and need to jump out of the array/object + case ']': case '}': + logger::log_end_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } +#if SIMDJSON_CHECK_EOF + // If there are no more tokens, the parent is incomplete. + if (at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "Missing [ or { at start"); } +#endif // SIMDJSON_CHECK_EOF + break; + case '"': + if(*peek() == ':') { + // We are at a key!!! + // This might happen if you just started an object and you skip it immediately. + // Performance note: it would be nice to get rid of this check as it is somewhat + // expensive. + // https://github.com/simdjson/simdjson/issues/1742 + logger::log_value(*this, "key"); + return_current_and_advance(); // eat up the ':' + break; // important!!! + } + simdjson_fallthrough; + // Anything else must be a scalar value + default: + // For the first scalar, we will have incremented depth already, so we decrement it here. + logger::log_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } + break; + } + + // Now that we've considered the first value, we only increment/decrement for arrays/objects + while (position() < end_position()) { + switch (*return_current_and_advance()) { + case '[': case '{': + logger::log_start_value(*this, "skip"); + _depth++; + break; + // TODO consider whether matching braces is a requirement: if non-matching braces indicates + // *missing* braces, then future lookups are not in the object/arrays they think they are, + // violating the rule "validate enough structure that the user can be confident they are + // looking at the right values." + // PERF TODO we can eliminate the switch here with a lookup of how much to add to depth + case ']': case '}': + logger::log_end_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } + break; + default: + logger::log_value(*this, "skip", ""); + break; + } + } + + return report_error(TAPE_ERROR, "not enough close braces"); +} + +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline bool json_iterator::at_root() const noexcept { + return position() == root_position(); +} + +simdjson_inline bool json_iterator::is_single_token() const noexcept { + return parser->implementation->n_structural_indexes == 1; +} + +simdjson_inline bool json_iterator::streaming() const noexcept { + return _streaming; +} + +simdjson_inline token_position json_iterator::root_position() const noexcept { + return _root; +} + +simdjson_inline void json_iterator::assert_at_document_depth() const noexcept { + SIMDJSON_ASSUME( _depth == 1 ); +} + +simdjson_inline void json_iterator::assert_at_root() const noexcept { + SIMDJSON_ASSUME( _depth == 1 ); +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + // Under Visual Studio, the next SIMDJSON_ASSUME fails with: the argument + // has side effects that will be discarded. + SIMDJSON_ASSUME( token.position() == _root ); +#endif +} + +simdjson_inline void json_iterator::assert_more_tokens(uint32_t required_tokens) const noexcept { + assert_valid_position(token._position + required_tokens - 1); +} + +simdjson_inline void json_iterator::assert_valid_position(token_position position) const noexcept { +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + SIMDJSON_ASSUME( position >= &parser->implementation->structural_indexes[0] ); + SIMDJSON_ASSUME( position < &parser->implementation->structural_indexes[parser->implementation->n_structural_indexes] ); +#endif +} + +simdjson_inline bool json_iterator::at_end() const noexcept { + return position() == end_position(); +} +simdjson_inline token_position json_iterator::end_position() const noexcept { + uint32_t n_structural_indexes{parser->implementation->n_structural_indexes}; + return &parser->implementation->structural_indexes[n_structural_indexes]; +} + +inline std::string json_iterator::to_string() const noexcept { + if( !is_alive() ) { return "dead json_iterator instance"; } + const char * current_structural = reinterpret_cast(token.peek()); + return std::string("json_iterator [ depth : ") + std::to_string(_depth) + + std::string(", structural : '") + std::string(current_structural,1) + + std::string("', offset : ") + std::to_string(token.current_offset()) + + std::string("', error : ") + error_message(error) + + std::string(" ]"); +} + +inline simdjson_result json_iterator::current_location() const noexcept { + if (!is_alive()) { // Unrecoverable error + if (!at_root()) { + return reinterpret_cast(token.peek(-1)); + } else { + return reinterpret_cast(token.peek()); + } + } + if (at_end()) { + return OUT_OF_BOUNDS; + } + return reinterpret_cast(token.peek()); +} + +simdjson_inline bool json_iterator::is_alive() const noexcept { + return parser; +} + +simdjson_inline void json_iterator::abandon() noexcept { + parser = nullptr; + _depth = 0; +} + +simdjson_inline const uint8_t *json_iterator::return_current_and_advance() noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(); +#endif // SIMDJSON_CHECK_EOF + return token.return_current_and_advance(); +} + +simdjson_inline const uint8_t *json_iterator::unsafe_pointer() const noexcept { + // deliberately done without safety guard: + return token.peek(); +} + +simdjson_inline const uint8_t *json_iterator::peek(int32_t delta) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(delta+1); +#endif // SIMDJSON_CHECK_EOF + return token.peek(delta); +} + +simdjson_inline uint32_t json_iterator::peek_length(int32_t delta) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(delta+1); +#endif // #if SIMDJSON_CHECK_EOF + return token.peek_length(delta); +} + +simdjson_inline const uint8_t *json_iterator::peek(token_position position) const noexcept { + // todo: currently we require end-of-string buffering, but the following + // assert_valid_position should be turned on if/when we lift that condition. + // assert_valid_position(position); + // This is almost surely related to SIMDJSON_CHECK_EOF but given that SIMDJSON_CHECK_EOF + // is ON by default, we have no choice but to disable it for real with a comment. + return token.peek(position); +} + +simdjson_inline uint32_t json_iterator::peek_length(token_position position) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_valid_position(position); +#endif // SIMDJSON_CHECK_EOF + return token.peek_length(position); +} + +simdjson_inline token_position json_iterator::last_position() const noexcept { + // The following line fails under some compilers... + // SIMDJSON_ASSUME(parser->implementation->n_structural_indexes > 0); + // since it has side-effects. + uint32_t n_structural_indexes{parser->implementation->n_structural_indexes}; + SIMDJSON_ASSUME(n_structural_indexes > 0); + return &parser->implementation->structural_indexes[n_structural_indexes - 1]; +} +simdjson_inline const uint8_t *json_iterator::peek_last() const noexcept { + return token.peek(last_position()); +} + +simdjson_inline void json_iterator::ascend_to(depth_t parent_depth) noexcept { + SIMDJSON_ASSUME(parent_depth >= 0 && parent_depth < INT32_MAX - 1); + SIMDJSON_ASSUME(_depth == parent_depth + 1); + _depth = parent_depth; +} + +simdjson_inline void json_iterator::descend_to(depth_t child_depth) noexcept { + SIMDJSON_ASSUME(child_depth >= 1 && child_depth < INT32_MAX); + SIMDJSON_ASSUME(_depth == child_depth - 1); + _depth = child_depth; +} + +simdjson_inline depth_t json_iterator::depth() const noexcept { + return _depth; +} + +simdjson_inline uint8_t *&json_iterator::string_buf_loc() noexcept { + return _string_buf_loc; +} + +simdjson_inline error_code json_iterator::report_error(error_code _error, const char *message) noexcept { + SIMDJSON_ASSUME(_error != SUCCESS && _error != UNINITIALIZED && _error != INCORRECT_TYPE && _error != NO_SUCH_FIELD); + logger::log_error(*this, message); + error = _error; + return error; +} + +simdjson_inline token_position json_iterator::position() const noexcept { + return token.position(); +} + +simdjson_inline simdjson_result json_iterator::unescape(raw_json_string in, bool allow_replacement) noexcept { + return parser->unescape(in, _string_buf_loc, allow_replacement); +} + +simdjson_inline simdjson_result json_iterator::unescape_wobbly(raw_json_string in) noexcept { + return parser->unescape_wobbly(in, _string_buf_loc); +} + +simdjson_inline void json_iterator::reenter_child(token_position position, depth_t child_depth) noexcept { + SIMDJSON_ASSUME(child_depth >= 1 && child_depth < INT32_MAX); + SIMDJSON_ASSUME(_depth == child_depth - 1); +#if SIMDJSON_DEVELOPMENT_CHECKS +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + SIMDJSON_ASSUME(size_t(child_depth) < parser->max_depth()); + SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]); +#endif +#endif + token.set_position(position); + _depth = child_depth; +} + +simdjson_inline error_code json_iterator::consume_character(char c) noexcept { + if (*peek() == c) { + return_current_and_advance(); + return SUCCESS; + } + return TAPE_ERROR; +} + +#if SIMDJSON_DEVELOPMENT_CHECKS + +simdjson_inline token_position json_iterator::start_position(depth_t depth) const noexcept { + SIMDJSON_ASSUME(size_t(depth) < parser->max_depth()); + return size_t(depth) < parser->max_depth() ? parser->start_positions[depth] : 0; +} + +simdjson_inline void json_iterator::set_start_position(depth_t depth, token_position position) noexcept { + SIMDJSON_ASSUME(size_t(depth) < parser->max_depth()); + if(size_t(depth) < parser->max_depth()) { parser->start_positions[depth] = position; } +} + +#endif + + +simdjson_inline error_code json_iterator::optional_error(error_code _error, const char *message) noexcept { + SIMDJSON_ASSUME(_error == INCORRECT_TYPE || _error == NO_SUCH_FIELD); + logger::log_error(*this, message); + return _error; +} + + +simdjson_warn_unused simdjson_inline bool json_iterator::copy_to_buffer(const uint8_t *json, uint32_t max_len, uint8_t *tmpbuf, size_t N) noexcept { + // This function is not expected to be called in performance-sensitive settings. + // Let us guard against silly cases: + if((N < max_len) || (N == 0)) { return false; } + // Copy to the buffer. + std::memcpy(tmpbuf, json, max_len); + if(N > max_len) { // We pad whatever remains with ' '. + std::memset(tmpbuf + max_len, ' ', N - max_len); + } + return true; +} + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(arm64::ondemand::json_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/json_iterator-inl.h for arm64 */ +/* including simdjson/generic/ondemand/json_type-inl.h for arm64: #include "simdjson/generic/ondemand/json_type-inl.h" */ +/* begin file simdjson/generic/ondemand/json_type-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +inline std::ostream& operator<<(std::ostream& out, json_type type) noexcept { + switch (type) { + case json_type::array: out << "array"; break; + case json_type::object: out << "object"; break; + case json_type::number: out << "number"; break; + case json_type::string: out << "string"; break; + case json_type::boolean: out << "boolean"; break; + case json_type::null: out << "null"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson_result &type) noexcept(false) { + return out << type.value(); +} +#endif + + + +simdjson_inline number_type number::get_number_type() const noexcept { + return type; +} + +simdjson_inline bool number::is_uint64() const noexcept { + return get_number_type() == number_type::unsigned_integer; +} + +simdjson_inline uint64_t number::get_uint64() const noexcept { + return payload.unsigned_integer; +} + +simdjson_inline number::operator uint64_t() const noexcept { + return get_uint64(); +} + + +simdjson_inline bool number::is_int64() const noexcept { + return get_number_type() == number_type::signed_integer; +} + +simdjson_inline int64_t number::get_int64() const noexcept { + return payload.signed_integer; +} + +simdjson_inline number::operator int64_t() const noexcept { + return get_int64(); +} + +simdjson_inline bool number::is_double() const noexcept { + return get_number_type() == number_type::floating_point_number; +} + +simdjson_inline double number::get_double() const noexcept { + return payload.floating_point_number; +} + +simdjson_inline number::operator double() const noexcept { + return get_double(); +} + +simdjson_inline double number::as_double() const noexcept { + if(is_double()) { + return payload.floating_point_number; + } + if(is_int64()) { + return double(payload.signed_integer); + } + return double(payload.unsigned_integer); +} + +simdjson_inline void number::append_s64(int64_t value) noexcept { + payload.signed_integer = value; + type = number_type::signed_integer; +} + +simdjson_inline void number::append_u64(uint64_t value) noexcept { + payload.unsigned_integer = value; + type = number_type::unsigned_integer; +} + +simdjson_inline void number::append_double(double value) noexcept { + payload.floating_point_number = value; + type = number_type::floating_point_number; +} + +simdjson_inline void number::skip_double() noexcept { + type = number_type::floating_point_number; +} + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(arm64::ondemand::json_type &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H +/* end file simdjson/generic/ondemand/json_type-inl.h for arm64 */ +/* including simdjson/generic/ondemand/logger-inl.h for arm64: #include "simdjson/generic/ondemand/logger-inl.h" */ +/* begin file simdjson/generic/ondemand/logger-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include + +namespace simdjson { +namespace arm64 { +namespace ondemand { +namespace logger { + +static constexpr const char * DASHES = "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"; +static constexpr const int LOG_EVENT_LEN = 20; +static constexpr const int LOG_BUFFER_LEN = 30; +static constexpr const int LOG_SMALL_BUFFER_LEN = 10; +static int log_depth = 0; // Not threadsafe. Log only. + +// Helper to turn unprintable or newline characters into spaces +static inline char printable_char(char c) { + if (c >= 0x20) { + return c; + } else { + return ' '; + } +} + +template +static inline std::string string_format(const std::string& format, const Args&... args) +{ + SIMDJSON_PUSH_DISABLE_ALL_WARNINGS + int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; + auto size = static_cast(size_s); + if (size <= 0) return std::string(); + std::unique_ptr buf(new char[size]); + std::snprintf(buf.get(), size, format.c_str(), args...); + SIMDJSON_POP_DISABLE_WARNINGS + return std::string(buf.get(), buf.get() + size - 1); +} + +static inline log_level get_log_level_from_env() +{ + SIMDJSON_PUSH_DISABLE_WARNINGS + SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe + char *lvl = getenv("SIMDJSON_LOG_LEVEL"); + SIMDJSON_POP_DISABLE_WARNINGS + if (lvl && simdjson_strcasecmp(lvl, "ERROR") == 0) { return log_level::error; } + return log_level::info; +} + +static inline log_level log_threshold() +{ + static log_level threshold = get_log_level_from_env(); + return threshold; +} + +static inline bool should_log(log_level level) +{ + return level >= log_threshold(); +} + +inline void log_event(const json_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_line(iter, "", type, detail, delta, depth_delta, log_level::info); +} + +inline void log_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail) noexcept { + log_line(iter, index, depth, "", type, detail, log_level::info); +} +inline void log_value(const json_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_line(iter, "", type, detail, delta, depth_delta, log_level::info); +} + +inline void log_start_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail) noexcept { + log_line(iter, index, depth, "+", type, detail, log_level::info); + if (LOG_ENABLED) { log_depth++; } +} +inline void log_start_value(const json_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_line(iter, "+", type, "", delta, depth_delta, log_level::info); + if (LOG_ENABLED) { log_depth++; } +} + +inline void log_end_value(const json_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + if (LOG_ENABLED) { log_depth--; } + log_line(iter, "-", type, "", delta, depth_delta, log_level::info); +} + +inline void log_error(const json_iterator &iter, const char *error, const char *detail, int delta, int depth_delta) noexcept { + log_line(iter, "ERROR: ", error, detail, delta, depth_delta, log_level::error); +} +inline void log_error(const json_iterator &iter, token_position index, depth_t depth, const char *error, const char *detail) noexcept { + log_line(iter, index, depth, "ERROR: ", error, detail, log_level::error); +} + +inline void log_event(const value_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_event(iter.json_iter(), type, detail, delta, depth_delta); +} + +inline void log_value(const value_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_value(iter.json_iter(), type, detail, delta, depth_delta); +} + +inline void log_start_value(const value_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_start_value(iter.json_iter(), type, delta, depth_delta); +} + +inline void log_end_value(const value_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_end_value(iter.json_iter(), type, delta, depth_delta); +} + +inline void log_error(const value_iterator &iter, const char *error, const char *detail, int delta, int depth_delta) noexcept { + log_error(iter.json_iter(), error, detail, delta, depth_delta); +} + +inline void log_headers() noexcept { + if (LOG_ENABLED) { + if (simdjson_unlikely(should_log(log_level::info))) { + // Technically a static variable is not thread-safe, but if you are using threads and logging... well... + static bool displayed_hint{false}; + log_depth = 0; + printf("\n"); + if (!displayed_hint) { + // We only print this helpful header once. + printf("# Logging provides the depth and position of the iterator user-visible steps:\n"); + printf("# +array says 'this is where we were when we discovered the start array'\n"); + printf( + "# -array says 'this is where we were when we ended the array'\n"); + printf("# skip says 'this is a structural or value I am skipping'\n"); + printf("# +/-skip says 'this is a start/end array or object I am skipping'\n"); + printf("#\n"); + printf("# The indentation of the terms (array, string,...) indicates the depth,\n"); + printf("# in addition to the depth being displayed.\n"); + printf("#\n"); + printf("# Every token in the document has a single depth determined by the tokens before it,\n"); + printf("# and is not affected by what the token actually is.\n"); + printf("#\n"); + printf("# Not all structural elements are presented as tokens in the logs.\n"); + printf("#\n"); + printf("# We never give control to the user within an empty array or an empty object.\n"); + printf("#\n"); + printf("# Inside an array, having a depth greater than the array's depth means that\n"); + printf("# we are pointing inside a value.\n"); + printf("# Having a depth equal to the array means that we are pointing right before a value.\n"); + printf("# Having a depth smaller than the array means that we have moved beyond the array.\n"); + displayed_hint = true; + } + printf("\n"); + printf("| %-*s ", LOG_EVENT_LEN, "Event"); + printf("| %-*s ", LOG_BUFFER_LEN, "Buffer"); + printf("| %-*s ", LOG_SMALL_BUFFER_LEN, "Next"); + // printf("| %-*s ", 5, "Next#"); + printf("| %-*s ", 5, "Depth"); + printf("| Detail "); + printf("|\n"); + + printf("|%.*s", LOG_EVENT_LEN + 2, DASHES); + printf("|%.*s", LOG_BUFFER_LEN + 2, DASHES); + printf("|%.*s", LOG_SMALL_BUFFER_LEN + 2, DASHES); + // printf("|%.*s", 5+2, DASHES); + printf("|%.*s", 5 + 2, DASHES); + printf("|--------"); + printf("|\n"); + fflush(stdout); + } + } +} + +template +inline void log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, log_level level, Args&&... args) noexcept { + log_line(iter, iter.position()+delta, depth_t(iter.depth()+depth_delta), title_prefix, title, detail, level, std::forward(args)...); +} + +template +inline void log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, log_level level, Args&&... args) noexcept { + if (LOG_ENABLED) { + if (simdjson_unlikely(should_log(level))) { + const int indent = depth * 2; + const auto buf = iter.token.buf; + auto msg = string_format(title, std::forward(args)...); + printf("| %*s%s%-*s ", indent, "", title_prefix, + LOG_EVENT_LEN - indent - int(strlen(title_prefix)), msg.c_str()); + { + // Print the current structural. + printf("| "); + // Before we begin, the index might point right before the document. + // This could be unsafe, see https://github.com/simdjson/simdjson/discussions/1938 + if (index < iter._root) { + printf("%*s", LOG_BUFFER_LEN, ""); + } else { + auto current_structural = &buf[*index]; + for (int i = 0; i < LOG_BUFFER_LEN; i++) { + printf("%c", printable_char(current_structural[i])); + } + } + printf(" "); + } + { + // Print the next structural. + printf("| "); + auto next_structural = &buf[*(index + 1)]; + for (int i = 0; i < LOG_SMALL_BUFFER_LEN; i++) { + printf("%c", printable_char(next_structural[i])); + } + printf(" "); + } + // printf("| %5u ", *(index+1)); + printf("| %5i ", depth); + printf("| %6.*s ", int(detail.size()), detail.data()); + printf("|\n"); + fflush(stdout); + } + } +} + +} // namespace logger +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H +/* end file simdjson/generic/ondemand/logger-inl.h for arm64 */ +/* including simdjson/generic/ondemand/object-inl.h for arm64: #include "simdjson/generic/ondemand/object-inl.h" */ +/* begin file simdjson/generic/ondemand/object-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +simdjson_inline simdjson_result object::find_field_unordered(const std::string_view key) & noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::find_field_unordered(const std::string_view key) && noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::operator[](const std::string_view key) & noexcept { + return find_field_unordered(key); +} +simdjson_inline simdjson_result object::operator[](const std::string_view key) && noexcept { + return std::forward(*this).find_field_unordered(key); +} +simdjson_inline simdjson_result object::find_field(const std::string_view key) & noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::find_field(const std::string_view key) && noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} + +simdjson_inline simdjson_result object::start(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.start_object().error() ); + return object(iter); +} +simdjson_inline simdjson_result object::start_root(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.start_root_object().error() ); + return object(iter); +} +simdjson_inline error_code object::consume() noexcept { + if(iter.is_at_key()) { + /** + * whenever you are pointing at a key, calling skip_child() is + * unsafe because you will hit a string and you will assume that + * it is string value, and this mistake will lead you to make bad + * depth computation. + */ + /** + * We want to 'consume' the key. We could really + * just do _json_iter->return_current_and_advance(); at this + * point, but, for clarity, we will use the high-level API to + * eat the key. We assume that the compiler optimizes away + * most of the work. + */ + simdjson_unused raw_json_string actual_key; + auto error = iter.field_key().get(actual_key); + if (error) { iter.abandon(); return error; }; + // Let us move to the value while we are at it. + if ((error = iter.field_value())) { iter.abandon(); return error; } + } + auto error_skip = iter.json_iter().skip_child(iter.depth()-1); + if(error_skip) { iter.abandon(); } + return error_skip; +} + +simdjson_inline simdjson_result object::raw_json() noexcept { + const uint8_t * starting_point{iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + const uint8_t * final_point{iter._json_iter->peek()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +simdjson_inline simdjson_result object::started(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.started_object().error() ); + return object(iter); +} + +simdjson_inline object object::resume(const value_iterator &iter) noexcept { + return iter; +} + +simdjson_inline object::object(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} + +simdjson_inline simdjson_result object::begin() noexcept { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + return object_iterator(iter); +} +simdjson_inline simdjson_result object::end() noexcept { + return object_iterator(iter); +} + +inline simdjson_result object::at_pointer(std::string_view json_pointer) noexcept { + if (json_pointer[0] != '/') { return INVALID_JSON_POINTER; } + json_pointer = json_pointer.substr(1); + size_t slash = json_pointer.find('/'); + std::string_view key = json_pointer.substr(0, slash); + // Grab the child with the given key + simdjson_result child; + + // If there is an escape character in the key, unescape it and then get the child. + size_t escape = key.find('~'); + if (escape != std::string_view::npos) { + // Unescape the key + std::string unescaped(key); + do { + switch (unescaped[escape+1]) { + case '0': + unescaped.replace(escape, 2, "~"); + break; + case '1': + unescaped.replace(escape, 2, "/"); + break; + default: + return INVALID_JSON_POINTER; // "Unexpected ~ escape character in JSON pointer"); + } + escape = unescaped.find('~', escape+1); + } while (escape != std::string::npos); + child = find_field(unescaped); // Take note find_field does not unescape keys when matching + } else { + child = find_field(key); + } + if(child.error()) { + return child; // we do not continue if there was an error + } + // If there is a /, we have to recurse and look up more of the path + if (slash != std::string_view::npos) { + child = child.at_pointer(json_pointer.substr(slash)); + } + return child; +} + +simdjson_inline simdjson_result object::count_fields() & noexcept { + size_t count{0}; + // Important: we do not consume any of the values. + for(simdjson_unused auto v : *this) { count++; } + // The above loop will always succeed, but we want to report errors. + if(iter.error()) { return iter.error(); } + // We need to move back at the start because we expect users to iterate through + // the object after counting the number of elements. + iter.reset_object(); + return count; +} + +simdjson_inline simdjson_result object::is_empty() & noexcept { + bool is_not_empty; + auto error = iter.reset_object().get(is_not_empty); + if(error) { return error; } + return !is_not_empty; +} + +simdjson_inline simdjson_result object::reset() & noexcept { + return iter.reset_object(); +} + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(arm64::ondemand::object &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +simdjson_inline simdjson_result simdjson_result::begin() noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() noexcept { + if (error()) { return error(); } + return first.end(); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first).find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first)[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first).find_field(key); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + +inline simdjson_result simdjson_result::reset() noexcept { + if (error()) { return error(); } + return first.reset(); +} + +inline simdjson_result simdjson_result::is_empty() noexcept { + if (error()) { return error(); } + return first.is_empty(); +} + +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H +/* end file simdjson/generic/ondemand/object-inl.h for arm64 */ +/* including simdjson/generic/ondemand/object_iterator-inl.h for arm64: #include "simdjson/generic/ondemand/object_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/object_iterator-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +// +// object_iterator +// + +simdjson_inline object_iterator::object_iterator(const value_iterator &_iter) noexcept + : iter{_iter} +{} + +simdjson_inline simdjson_result object_iterator::operator*() noexcept { + error_code error = iter.error(); + if (error) { iter.abandon(); return error; } + auto result = field::start(iter); + // TODO this is a safety rail ... users should exit loops as soon as they receive an error. + // Nonetheless, let's see if performance is OK with this if statement--the compiler may give it to us for free. + if (result.error()) { iter.abandon(); } + return result; +} +simdjson_inline bool object_iterator::operator==(const object_iterator &other) const noexcept { + return !(*this != other); +} +simdjson_inline bool object_iterator::operator!=(const object_iterator &) const noexcept { + return iter.is_open(); +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline object_iterator &object_iterator::operator++() noexcept { + // TODO this is a safety rail ... users should exit loops as soon as they receive an error. + // Nonetheless, let's see if performance is OK with this if statement--the compiler may give it to us for free. + if (!iter.is_open()) { return *this; } // Iterator will be released if there is an error + + simdjson_unused error_code error; + if ((error = iter.skip_child() )) { return *this; } + + simdjson_unused bool has_value; + if ((error = iter.has_next_field().get(has_value) )) { return *this; }; + return *this; +} +SIMDJSON_POP_DISABLE_WARNINGS + +// +// ### Live States +// +// While iterating or looking up values, depth >= iter.depth. at_start may vary. Error is +// always SUCCESS: +// +// - Start: This is the state when the object is first found and the iterator is just past the {. +// In this state, at_start == true. +// - Next: After we hand a scalar value to the user, or an array/object which they then fully +// iterate over, the iterator is at the , or } before the next value. In this state, +// depth == iter.depth, at_start == false, and error == SUCCESS. +// - Unfinished Business: When we hand an array/object to the user which they do not fully +// iterate over, we need to finish that iteration by skipping child values until we reach the +// Next state. In this state, depth > iter.depth, at_start == false, and error == SUCCESS. +// +// ## Error States +// +// In error states, we will yield exactly one more value before stopping. iter.depth == depth +// and at_start is always false. We decrement after yielding the error, moving to the Finished +// state. +// +// - Chained Error: When the object iterator is part of an error chain--for example, in +// `for (auto tweet : doc["tweets"])`, where the tweet field may be missing or not be an +// object--we yield that error in the loop, exactly once. In this state, error != SUCCESS and +// iter.depth == depth, and at_start == false. We decrement depth when we yield the error. +// - Missing Comma Error: When the iterator ++ method discovers there is no comma between fields, +// we flag that as an error and treat it exactly the same as a Chained Error. In this state, +// error == TAPE_ERROR, iter.depth == depth, and at_start == false. +// +// Errors that occur while reading a field to give to the user (such as when the key is not a +// string or the field is missing a colon) are yielded immediately. Depth is then decremented, +// moving to the Finished state without transitioning through an Error state at all. +// +// ## Terminal State +// +// The terminal state has iter.depth < depth. at_start is always false. +// +// - Finished: When we have reached a }, we are finished. We signal this by decrementing depth. +// In this state, iter.depth < depth, at_start == false, and error == SUCCESS. +// + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + arm64::ondemand::object_iterator &&value +) noexcept + : implementation_simdjson_result_base(std::forward(value)) +{ + first.iter.assert_is_valid(); +} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base({}, error) +{ +} + +simdjson_inline simdjson_result simdjson_result::operator*() noexcept { + if (error()) { return error(); } + return *first; +} +// If we're iterating and there is an error, return the error once. +simdjson_inline bool simdjson_result::operator==(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return !error(); } + return first == other.first; +} +// If we're iterating and there is an error, return the error once. +simdjson_inline bool simdjson_result::operator!=(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return error(); } + return first != other.first; +} +// Checks for ']' and ',' +simdjson_inline simdjson_result &simdjson_result::operator++() noexcept { + // Clear the error if there is one, so we don't yield it twice + if (error()) { second = SUCCESS; return *this; } + ++first; + return *this; +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/object_iterator-inl.h for arm64 */ +/* including simdjson/generic/ondemand/parser-inl.h for arm64: #include "simdjson/generic/ondemand/parser-inl.h" */ +/* begin file simdjson/generic/ondemand/parser-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/padded_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/padded_string_view.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/dom/base.h" // for MINIMAL_DOCUMENT_CAPACITY */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document_stream.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +simdjson_inline parser::parser(size_t max_capacity) noexcept + : _max_capacity{max_capacity} { +} + +simdjson_warn_unused simdjson_inline error_code parser::allocate(size_t new_capacity, size_t new_max_depth) noexcept { + if (new_capacity > max_capacity()) { return CAPACITY; } + if (string_buf && new_capacity == capacity() && new_max_depth == max_depth()) { return SUCCESS; } + + // string_capacity copied from document::allocate + _capacity = 0; + size_t string_capacity = SIMDJSON_ROUNDUP_N(5 * new_capacity / 3 + SIMDJSON_PADDING, 64); + string_buf.reset(new (std::nothrow) uint8_t[string_capacity]); +#if SIMDJSON_DEVELOPMENT_CHECKS + start_positions.reset(new (std::nothrow) token_position[new_max_depth]); +#endif + if (implementation) { + SIMDJSON_TRY( implementation->set_capacity(new_capacity) ); + SIMDJSON_TRY( implementation->set_max_depth(new_max_depth) ); + } else { + SIMDJSON_TRY( simdjson::get_active_implementation()->create_dom_parser_implementation(new_capacity, new_max_depth, implementation) ); + } + _capacity = new_capacity; + _max_depth = new_max_depth; + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(padded_string_view json) & noexcept { + if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; } + + json.remove_utf8_bom(); + + // Allocate if needed + if (capacity() < json.length() || !string_buf) { + SIMDJSON_TRY( allocate(json.length(), max_depth()) ); + } + + // Run stage 1. + SIMDJSON_TRY( implementation->stage1(reinterpret_cast(json.data()), json.length(), stage1_mode::regular) ); + return document::start({ reinterpret_cast(json.data()), this }); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const char *json, size_t len, size_t allocated) & noexcept { + return iterate(padded_string_view(json, len, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const uint8_t *json, size_t len, size_t allocated) & noexcept { + return iterate(padded_string_view(json, len, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(std::string_view json, size_t allocated) & noexcept { + return iterate(padded_string_view(json, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(std::string &json) & noexcept { + if(json.capacity() - json.size() < SIMDJSON_PADDING) { + json.reserve(json.size() + SIMDJSON_PADDING); + } + return iterate(padded_string_view(json)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const std::string &json) & noexcept { + return iterate(padded_string_view(json)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const simdjson_result &result) & noexcept { + // We don't presently have a way to temporarily get a const T& from a simdjson_result without throwing an exception + SIMDJSON_TRY( result.error() ); + padded_string_view json = result.value_unsafe(); + return iterate(json); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const simdjson_result &result) & noexcept { + // We don't presently have a way to temporarily get a const T& from a simdjson_result without throwing an exception + SIMDJSON_TRY( result.error() ); + const padded_string &json = result.value_unsafe(); + return iterate(json); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate_raw(padded_string_view json) & noexcept { + if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; } + + json.remove_utf8_bom(); + + // Allocate if needed + if (capacity() < json.length()) { + SIMDJSON_TRY( allocate(json.length(), max_depth()) ); + } + + // Run stage 1. + SIMDJSON_TRY( implementation->stage1(reinterpret_cast(json.data()), json.length(), stage1_mode::regular) ); + return json_iterator(reinterpret_cast(json.data()), this); +} + +inline simdjson_result parser::iterate_many(const uint8_t *buf, size_t len, size_t batch_size, bool allow_comma_separated) noexcept { + if(batch_size < MINIMAL_BATCH_SIZE) { batch_size = MINIMAL_BATCH_SIZE; } + if((len >= 3) && (std::memcmp(buf, "\xEF\xBB\xBF", 3) == 0)) { + buf += 3; + len -= 3; + } + if(allow_comma_separated && batch_size < len) { batch_size = len; } + return document_stream(*this, buf, len, batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const char *buf, size_t len, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(reinterpret_cast(buf), len, batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const std::string &s, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(s.data(), s.length(), batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const padded_string &s, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(s.data(), s.length(), batch_size, allow_comma_separated); +} + +simdjson_inline size_t parser::capacity() const noexcept { + return _capacity; +} +simdjson_inline size_t parser::max_capacity() const noexcept { + return _max_capacity; +} +simdjson_inline size_t parser::max_depth() const noexcept { + return _max_depth; +} + +simdjson_inline void parser::set_max_capacity(size_t max_capacity) noexcept { + if(max_capacity < dom::MINIMAL_DOCUMENT_CAPACITY) { + _max_capacity = max_capacity; + } else { + _max_capacity = dom::MINIMAL_DOCUMENT_CAPACITY; + } +} + +simdjson_inline simdjson_warn_unused simdjson_result parser::unescape(raw_json_string in, uint8_t *&dst, bool allow_replacement) const noexcept { + uint8_t *end = implementation->parse_string(in.buf, dst, allow_replacement); + if (!end) { return STRING_ERROR; } + std::string_view result(reinterpret_cast(dst), end-dst); + dst = end; + return result; +} + +simdjson_inline simdjson_warn_unused simdjson_result parser::unescape_wobbly(raw_json_string in, uint8_t *&dst) const noexcept { + uint8_t *end = implementation->parse_wobbly_string(in.buf, dst); + if (!end) { return STRING_ERROR; } + std::string_view result(reinterpret_cast(dst), end-dst); + dst = end; + return result; +} + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(arm64::ondemand::parser &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H +/* end file simdjson/generic/ondemand/parser-inl.h for arm64 */ +/* including simdjson/generic/ondemand/raw_json_string-inl.h for arm64: #include "simdjson/generic/ondemand/raw_json_string-inl.h" */ +/* begin file simdjson/generic/ondemand/raw_json_string-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +namespace arm64 { +namespace ondemand { + +simdjson_inline raw_json_string::raw_json_string(const uint8_t * _buf) noexcept : buf{_buf} {} + +simdjson_inline const char * raw_json_string::raw() const noexcept { return reinterpret_cast(buf); } + + +simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(std::string_view target) noexcept { + size_t pos{0}; + // if the content has no escape character, just scan through it quickly! + for(;pos < target.size() && target[pos] != '\\';pos++) {} + // slow path may begin. + bool escaping{false}; + for(;pos < target.size();pos++) { + if((target[pos] == '"') && !escaping) { + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + return true; +} + +simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(const char* target) noexcept { + size_t pos{0}; + // if the content has no escape character, just scan through it quickly! + for(;target[pos] && target[pos] != '\\';pos++) {} + // slow path may begin. + bool escaping{false}; + for(;target[pos];pos++) { + if((target[pos] == '"') && !escaping) { + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + return true; +} + + +simdjson_inline bool raw_json_string::unsafe_is_equal(size_t length, std::string_view target) const noexcept { + // If we are going to call memcmp, then we must know something about the length of the raw_json_string. + return (length >= target.size()) && (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size()); +} + +simdjson_inline bool raw_json_string::unsafe_is_equal(std::string_view target) const noexcept { + // Assumptions: does not contain unescaped quote characters, and + // the raw content is quote terminated within a valid JSON string. + if(target.size() <= SIMDJSON_PADDING) { + return (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size()); + } + const char * r{raw()}; + size_t pos{0}; + for(;pos < target.size();pos++) { + if(r[pos] != target[pos]) { return false; } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_inline bool raw_json_string::is_equal(std::string_view target) const noexcept { + const char * r{raw()}; + size_t pos{0}; + bool escaping{false}; + for(;pos < target.size();pos++) { + if(r[pos] != target[pos]) { return false; } + // if target is a compile-time constant and it is free from + // quotes, then the next part could get optimized away through + // inlining. + if((target[pos] == '"') && !escaping) { + // We have reached the end of the raw_json_string but + // the target is not done. + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + if(r[pos] != '"') { return false; } + return true; +} + + +simdjson_inline bool raw_json_string::unsafe_is_equal(const char * target) const noexcept { + // Assumptions: 'target' does not contain unescaped quote characters, is null terminated and + // the raw content is quote terminated within a valid JSON string. + const char * r{raw()}; + size_t pos{0}; + for(;target[pos];pos++) { + if(r[pos] != target[pos]) { return false; } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_inline bool raw_json_string::is_equal(const char* target) const noexcept { + // Assumptions: does not contain unescaped quote characters, and + // the raw content is quote terminated within a valid JSON string. + const char * r{raw()}; + size_t pos{0}; + bool escaping{false}; + for(;target[pos];pos++) { + if(r[pos] != target[pos]) { return false; } + // if target is a compile-time constant and it is free from + // quotes, then the next part could get optimized away through + // inlining. + if((target[pos] == '"') && !escaping) { + // We have reached the end of the raw_json_string but + // the target is not done. + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept { + return a.unsafe_is_equal(c); +} + +simdjson_unused simdjson_inline bool operator==(std::string_view c, const raw_json_string &a) noexcept { + return a == c; +} + +simdjson_unused simdjson_inline bool operator!=(const raw_json_string &a, std::string_view c) noexcept { + return !(a == c); +} + +simdjson_unused simdjson_inline bool operator!=(std::string_view c, const raw_json_string &a) noexcept { + return !(a == c); +} + + +simdjson_inline simdjson_warn_unused simdjson_result raw_json_string::unescape(json_iterator &iter, bool allow_replacement) const noexcept { + return iter.unescape(*this, allow_replacement); +} + +simdjson_inline simdjson_warn_unused simdjson_result raw_json_string::unescape_wobbly(json_iterator &iter) const noexcept { + return iter.unescape_wobbly(*this); +} + +simdjson_unused simdjson_inline std::ostream &operator<<(std::ostream &out, const raw_json_string &str) noexcept { + bool in_escape = false; + const char *s = str.raw(); + while (true) { + switch (*s) { + case '\\': in_escape = !in_escape; break; + case '"': if (in_escape) { in_escape = false; } else { return out; } break; + default: if (in_escape) { in_escape = false; } + } + out << *s; + s++; + } +} + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(arm64::ondemand::raw_json_string &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +simdjson_inline simdjson_result simdjson_result::raw() const noexcept { + if (error()) { return error(); } + return first.raw(); +} +simdjson_inline simdjson_warn_unused simdjson_result simdjson_result::unescape(arm64::ondemand::json_iterator &iter, bool allow_replacement) const noexcept { + if (error()) { return error(); } + return first.unescape(iter, allow_replacement); +} +simdjson_inline simdjson_warn_unused simdjson_result simdjson_result::unescape_wobbly(arm64::ondemand::json_iterator &iter) const noexcept { + if (error()) { return error(); } + return first.unescape_wobbly(iter); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H +/* end file simdjson/generic/ondemand/raw_json_string-inl.h for arm64 */ +/* including simdjson/generic/ondemand/serialization-inl.h for arm64: #include "simdjson/generic/ondemand/serialization-inl.h" */ +/* begin file simdjson/generic/ondemand/serialization-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/serialization.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +inline std::string_view trim(const std::string_view str) noexcept { + // We can almost surely do better by rolling our own find_first_not_of function. + size_t first = str.find_first_not_of(" \t\n\r"); + // If we have the empty string (just white space), then no trimming is possible, and + // we return the empty string_view. + if (std::string_view::npos == first) { return std::string_view(); } + size_t last = str.find_last_not_of(" \t\n\r"); + return str.substr(first, (last - first + 1)); +} + + +inline simdjson_result to_json_string(arm64::ondemand::document& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(arm64::ondemand::document_reference& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(arm64::ondemand::value& x) noexcept { + /** + * If we somehow receive a value that has already been consumed, + * then the following code could be in trouble. E.g., we create + * an array as needed, but if an array was already created, then + * it could be bad. + */ + using namespace arm64::ondemand; + arm64::ondemand::json_type t; + auto error = x.type().get(t); + if(error != SUCCESS) { return error; } + switch (t) + { + case json_type::array: + { + arm64::ondemand::array array; + error = x.get_array().get(array); + if(error) { return error; } + return to_json_string(array); + } + case json_type::object: + { + arm64::ondemand::object object; + error = x.get_object().get(object); + if(error) { return error; } + return to_json_string(object); + } + default: + return trim(x.raw_json_token()); + } +} + +inline simdjson_result to_json_string(arm64::ondemand::object& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(arm64::ondemand::array& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} +} // namespace simdjson + +namespace simdjson { namespace arm64 { namespace ondemand { + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::arm64::ondemand::value x) { + std::string_view v; + auto error = simdjson::to_json_string(x).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::arm64::ondemand::value x) { + std::string_view v; + auto error = simdjson::to_json_string(x).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::arm64::ondemand::array value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::arm64::ondemand::array value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::arm64::ondemand::document& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::arm64::ondemand::document_reference& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::arm64::ondemand::document& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::arm64::ondemand::object value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::arm64::ondemand::object value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif +}}} // namespace simdjson::arm64::ondemand + +#endif // SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H +/* end file simdjson/generic/ondemand/serialization-inl.h for arm64 */ +/* including simdjson/generic/ondemand/token_iterator-inl.h for arm64: #include "simdjson/generic/ondemand/token_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/token_iterator-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +simdjson_inline token_iterator::token_iterator( + const uint8_t *_buf, + token_position position +) noexcept : buf{_buf}, _position{position} +{ +} + +simdjson_inline uint32_t token_iterator::current_offset() const noexcept { + return *(_position); +} + + +simdjson_inline const uint8_t *token_iterator::return_current_and_advance() noexcept { + return &buf[*(_position++)]; +} + +simdjson_inline const uint8_t *token_iterator::peek(token_position position) const noexcept { + return &buf[*position]; +} +simdjson_inline uint32_t token_iterator::peek_index(token_position position) const noexcept { + return *position; +} +simdjson_inline uint32_t token_iterator::peek_length(token_position position) const noexcept { + return *(position+1) - *position; +} + +simdjson_inline const uint8_t *token_iterator::peek(int32_t delta) const noexcept { + return &buf[*(_position+delta)]; +} +simdjson_inline uint32_t token_iterator::peek_index(int32_t delta) const noexcept { + return *(_position+delta); +} +simdjson_inline uint32_t token_iterator::peek_length(int32_t delta) const noexcept { + return *(_position+delta+1) - *(_position+delta); +} + +simdjson_inline token_position token_iterator::position() const noexcept { + return _position; +} +simdjson_inline void token_iterator::set_position(token_position target_position) noexcept { + _position = target_position; +} + +simdjson_inline bool token_iterator::operator==(const token_iterator &other) const noexcept { + return _position == other._position; +} +simdjson_inline bool token_iterator::operator!=(const token_iterator &other) const noexcept { + return _position != other._position; +} +simdjson_inline bool token_iterator::operator>(const token_iterator &other) const noexcept { + return _position > other._position; +} +simdjson_inline bool token_iterator::operator>=(const token_iterator &other) const noexcept { + return _position >= other._position; +} +simdjson_inline bool token_iterator::operator<(const token_iterator &other) const noexcept { + return _position < other._position; +} +simdjson_inline bool token_iterator::operator<=(const token_iterator &other) const noexcept { + return _position <= other._position; +} + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(arm64::ondemand::token_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/token_iterator-inl.h for arm64 */ +/* including simdjson/generic/ondemand/value-inl.h for arm64: #include "simdjson/generic/ondemand/value-inl.h" */ +/* begin file simdjson/generic/ondemand/value-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +simdjson_inline value::value(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} +simdjson_inline value value::start(const value_iterator &iter) noexcept { + return iter; +} +simdjson_inline value value::resume(const value_iterator &iter) noexcept { + return iter; +} + +simdjson_inline simdjson_result value::get_array() noexcept { + return array::start(iter); +} +simdjson_inline simdjson_result value::get_object() noexcept { + return object::start(iter); +} +simdjson_inline simdjson_result value::start_or_resume_object() noexcept { + if (iter.at_start()) { + return get_object(); + } else { + return object::resume(iter); + } +} + +simdjson_inline simdjson_result value::get_raw_json_string() noexcept { + return iter.get_raw_json_string(); +} +simdjson_inline simdjson_result value::get_string(bool allow_replacement) noexcept { + return iter.get_string(allow_replacement); +} +template +simdjson_inline error_code value::get_string(string_type& receiver, bool allow_replacement) noexcept { + return iter.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result value::get_wobbly_string() noexcept { + return iter.get_wobbly_string(); +} +simdjson_inline simdjson_result value::get_double() noexcept { + return iter.get_double(); +} +simdjson_inline simdjson_result value::get_double_in_string() noexcept { + return iter.get_double_in_string(); +} +simdjson_inline simdjson_result value::get_uint64() noexcept { + return iter.get_uint64(); +} +simdjson_inline simdjson_result value::get_uint64_in_string() noexcept { + return iter.get_uint64_in_string(); +} +simdjson_inline simdjson_result value::get_int64() noexcept { + return iter.get_int64(); +} +simdjson_inline simdjson_result value::get_int64_in_string() noexcept { + return iter.get_int64_in_string(); +} +simdjson_inline simdjson_result value::get_bool() noexcept { + return iter.get_bool(); +} +simdjson_inline simdjson_result value::is_null() noexcept { + return iter.is_null(); +} +template<> simdjson_inline simdjson_result value::get() noexcept { return get_array(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_object(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_number(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_double(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_uint64(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_int64(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_bool(); } + +template simdjson_inline error_code value::get(T &out) noexcept { + return get().get(out); +} + +#if SIMDJSON_EXCEPTIONS +simdjson_inline value::operator array() noexcept(false) { + return get_array(); +} +simdjson_inline value::operator object() noexcept(false) { + return get_object(); +} +simdjson_inline value::operator uint64_t() noexcept(false) { + return get_uint64(); +} +simdjson_inline value::operator int64_t() noexcept(false) { + return get_int64(); +} +simdjson_inline value::operator double() noexcept(false) { + return get_double(); +} +simdjson_inline value::operator std::string_view() noexcept(false) { + return get_string(false); +} +simdjson_inline value::operator raw_json_string() noexcept(false) { + return get_raw_json_string(); +} +simdjson_inline value::operator bool() noexcept(false) { + return get_bool(); +} +#endif + +simdjson_inline simdjson_result value::begin() & noexcept { + return get_array().begin(); +} +simdjson_inline simdjson_result value::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result value::count_elements() & noexcept { + simdjson_result answer; + auto a = get_array(); + answer = a.count_elements(); + // count_elements leaves you pointing inside the array, at the first element. + // We need to move back so that the user can create a new array (which requires that + // we point at '['). + iter.move_at_start(); + return answer; +} +simdjson_inline simdjson_result value::count_fields() & noexcept { + simdjson_result answer; + auto a = get_object(); + answer = a.count_fields(); + iter.move_at_start(); + return answer; +} +simdjson_inline simdjson_result value::at(size_t index) noexcept { + auto a = get_array(); + return a.at(index); +} + +simdjson_inline simdjson_result value::find_field(std::string_view key) noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result value::find_field(const char *key) noexcept { + return start_or_resume_object().find_field(key); +} + +simdjson_inline simdjson_result value::find_field_unordered(std::string_view key) noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result value::find_field_unordered(const char *key) noexcept { + return start_or_resume_object().find_field_unordered(key); +} + +simdjson_inline simdjson_result value::operator[](std::string_view key) noexcept { + return start_or_resume_object()[key]; +} +simdjson_inline simdjson_result value::operator[](const char *key) noexcept { + return start_or_resume_object()[key]; +} + +simdjson_inline simdjson_result value::type() noexcept { + return iter.type(); +} + +simdjson_inline simdjson_result value::is_scalar() noexcept { + json_type this_type; + auto error = type().get(this_type); + if(error) { return error; } + return ! ((this_type == json_type::array) || (this_type == json_type::object)); +} + +simdjson_inline bool value::is_negative() noexcept { + return iter.is_negative(); +} + +simdjson_inline simdjson_result value::is_integer() noexcept { + return iter.is_integer(); +} +simdjson_warn_unused simdjson_inline simdjson_result value::get_number_type() noexcept { + return iter.get_number_type(); +} +simdjson_warn_unused simdjson_inline simdjson_result value::get_number() noexcept { + return iter.get_number(); +} + +simdjson_inline std::string_view value::raw_json_token() noexcept { + return std::string_view(reinterpret_cast(iter.peek_start()), iter.peek_start_length()); +} + +simdjson_inline simdjson_result value::raw_json() noexcept { + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: { + ondemand::array array; + SIMDJSON_TRY(get_array().get(array)); + return array.raw_json(); + } + case json_type::object: { + ondemand::object object; + SIMDJSON_TRY(get_object().get(object)); + return object.raw_json(); + } + default: + return raw_json_token(); + } +} + +simdjson_inline simdjson_result value::current_location() noexcept { + return iter.json_iter().current_location(); +} + +simdjson_inline int32_t value::current_depth() const noexcept{ + return iter.json_iter().depth(); +} + +simdjson_inline simdjson_result value::at_pointer(std::string_view json_pointer) noexcept { + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: + return (*this).get_array().at_pointer(json_pointer); + case json_type::object: + return (*this).get_object().at_pointer(json_pointer); + default: + return INVALID_JSON_POINTER; + } +} + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + arm64::ondemand::value &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + if (error()) { return error(); } + return {}; +} + +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) noexcept { + if (error()) { return error(); } + return first.find_field(key); +} + +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} + +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) noexcept { + if (error()) { return error(); } + return first[key]; +} + +simdjson_inline simdjson_result simdjson_result::get_array() noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} + +template simdjson_inline simdjson_result simdjson_result::get() noexcept { + if (error()) { return error(); } + return first.get(); +} +template simdjson_inline error_code simdjson_result::get(T &out) noexcept { + if (error()) { return error(); } + return first.get(out); +} + +template<> simdjson_inline simdjson_result simdjson_result::get() noexcept { + if (error()) { return error(); } + return std::move(first); +} +template<> simdjson_inline error_code simdjson_result::get(arm64::ondemand::value &out) noexcept { + if (error()) { return error(); } + out = first; + return SUCCESS; +} + +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} +simdjson_inline simdjson_result simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator arm64::ondemand::array() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator arm64::ondemand::object() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator arm64::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline simdjson_result simdjson_result::current_depth() const noexcept { + if (error()) { return error(); } + return first.current_depth(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H +/* end file simdjson/generic/ondemand/value-inl.h for arm64 */ +/* including simdjson/generic/ondemand/value_iterator-inl.h for arm64: #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/value_iterator-inl.h for arm64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/atomparsing.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/numberparsing.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace arm64 { +namespace ondemand { + +simdjson_inline value_iterator::value_iterator( + json_iterator *json_iter, + depth_t depth, + token_position start_position +) noexcept : _json_iter{json_iter}, _depth{depth}, _start_position{start_position} +{ +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_object() noexcept { + SIMDJSON_TRY( start_container('{', "Not an object", "object") ); + return started_object(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_root_object() noexcept { + SIMDJSON_TRY( start_container('{', "Not an object", "object") ); + return started_root_object(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_object() noexcept { + assert_at_container_start(); +#if SIMDJSON_DEVELOPMENT_CHECKS + _json_iter->set_start_position(_depth, start_position()); +#endif + if (*_json_iter->peek() == '}') { + logger::log_value(*_json_iter, "empty object"); + _json_iter->return_current_and_advance(); + end_container(); + return false; + } + return true; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::check_root_object() noexcept { + // When in streaming mode, we cannot expect peek_last() to be the last structural element of the + // current document. It only works in the normal mode where we have indexed a single document. + // Note that adding a check for 'streaming' is not expensive since we only have at most + // one root element. + if ( ! _json_iter->streaming() ) { + // The following lines do not fully protect against garbage content within the + // object: e.g., `{"a":2} foo }`. Users concerned with garbage content should + // call `at_end()` on the document instance at the end of the processing to + // ensure that the processing has finished at the end. + // + if (*_json_iter->peek_last() != '}') { + _json_iter->abandon(); + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing } at end"); + } + // If the last character is } *and* the first gibberish character is also '}' + // then on-demand could accidentally go over. So we need additional checks. + // https://github.com/simdjson/simdjson/issues/1834 + // Checking that the document is balanced requires a full scan which is potentially + // expensive, but it only happens in edge cases where the first padding character is + // a closing bracket. + if ((*_json_iter->peek(_json_iter->end_position()) == '}') && (!_json_iter->balanced())) { + _json_iter->abandon(); + // The exact error would require more work. It will typically be an unclosed object. + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "the document is unbalanced"); + } + } + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_root_object() noexcept { + auto error = check_root_object(); + if(error) { return error; } + return started_object(); +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::end_container() noexcept { +#if SIMDJSON_CHECK_EOF + if (depth() > 1 && at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing parent ] or }"); } + // if (depth() <= 1 && !at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing [ or { at start"); } +#endif // SIMDJSON_CHECK_EOF + _json_iter->ascend_to(depth()-1); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::has_next_field() noexcept { + assert_at_next(); + + // It's illegal to call this unless there are more tokens: anything that ends in } or ] is + // obligated to verify there are more tokens if they are not the top level. + switch (*_json_iter->return_current_and_advance()) { + case '}': + logger::log_end_value(*_json_iter, "object"); + SIMDJSON_TRY( end_container() ); + return false; + case ',': + return true; + default: + return report_error(TAPE_ERROR, "Missing comma between object fields"); + } +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::find_field_raw(const std::string_view key) noexcept { + error_code error; + bool has_value; + // + // Initially, the object can be in one of a few different places: + // + // 1. The start of the object, at the first field: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2, index 1) + // ``` + if (at_first_field()) { + has_value = true; + + // + // 2. When a previous search did not yield a value or the object is empty: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // { } + // ^ (depth 0, index 2) + // ``` + // + } else if (!is_open()) { +#if SIMDJSON_DEVELOPMENT_CHECKS + // If we're past the end of the object, we're being iterated out of order. + // Note: this isn't perfect detection. It's possible the user is inside some other object; if so, + // this object iterator will blithely scan that object for fields. + if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; } +#endif + return false; + + // 3. When a previous search found a field or an iterator yielded a value: + // + // ``` + // // When a field was not fully consumed (or not even touched at all) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2) + // // When a field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // When the last field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // ``` + // + } else { + if ((error = skip_child() )) { abandon(); return error; } + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } +#if SIMDJSON_DEVELOPMENT_CHECKS + if (_json_iter->start_position(_depth) != start_position()) { return OUT_OF_ORDER_ITERATION; } +#endif + } + while (has_value) { + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + if ((error = field_key().get(actual_key) )) { abandon(); return error; }; + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + if ((error = field_value() )) { abandon(); return error; } + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + //if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); // Skip the value entirely + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } + } + + // If the loop ended, we're out of fields to look at. + return false; +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::find_field_unordered_raw(const std::string_view key) noexcept { + /** + * When find_field_unordered_raw is called, we can either be pointing at the + * first key, pointing outside (at the closing brace) or if a key was matched + * we can be either pointing right afterthe ':' right before the value (that we need skip), + * or we may have consumed the value and we might be at a comma or at the + * final brace (ready for a call to has_next_field()). + */ + error_code error; + bool has_value; + + // First, we scan from that point to the end. + // If we don't find a match, we may loop back around, and scan from the beginning to that point. + token_position search_start = _json_iter->position(); + + // We want to know whether we need to go back to the beginning. + bool at_first = at_first_field(); + /////////////// + // Initially, the object can be in one of a few different places: + // + // 1. At the first key: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2, index 1) + // ``` + // + if (at_first) { + has_value = true; + + // 2. When a previous search did not yield a value or the object is empty: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // { } + // ^ (depth 0, index 2) + // ``` + // + } else if (!is_open()) { + +#if SIMDJSON_DEVELOPMENT_CHECKS + // If we're past the end of the object, we're being iterated out of order. + // Note: this isn't perfect detection. It's possible the user is inside some other object; if so, + // this object iterator will blithely scan that object for fields. + if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; } +#endif + SIMDJSON_TRY(reset_object().get(has_value)); + at_first = true; + // 3. When a previous search found a field or an iterator yielded a value: + // + // ``` + // // When a field was not fully consumed (or not even touched at all) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2) + // // When a field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // When the last field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // ``` + // + } else { + // If someone queried a key but they not did access the value, then we are left pointing + // at the ':' and we need to move forward through the value... If the value was + // processed then skip_child() does not move the iterator (but may adjust the depth). + if ((error = skip_child() )) { abandon(); return error; } + search_start = _json_iter->position(); + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } +#if SIMDJSON_DEVELOPMENT_CHECKS + if (_json_iter->start_position(_depth) != start_position()) { return OUT_OF_ORDER_ITERATION; } +#endif + } + + // After initial processing, we will be in one of two states: + // + // ``` + // // At the beginning of a field + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // At the end of the object + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // ``` + // + // Next, we find a match starting from the current position. + while (has_value) { + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); // We must be at the start of a field + + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + if ((error = field_key().get(actual_key) )) { abandon(); return error; }; + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + if ((error = field_value() )) { abandon(); return error; } + + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + // if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } + } + // Performance note: it maybe wasteful to rewind to the beginning when there might be + // no other query following. Indeed, it would require reskipping the whole object. + // Instead, you can just stay where you are. If there is a new query, there is always time + // to rewind. + if(at_first) { return false; } + + // If we reach the end without finding a match, search the rest of the fields starting at the + // beginning of the object. + // (We have already run through the object before, so we've already validated its structure. We + // don't check errors in this bit.) + SIMDJSON_TRY(reset_object().get(has_value)); + while (true) { + SIMDJSON_ASSUME(has_value); // we should reach search_start before ever reaching the end of the object + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); // We must be at the start of a field + + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + error = field_key().get(actual_key); SIMDJSON_ASSUME(!error); + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + error = field_value(); SIMDJSON_ASSUME(!error); + + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + // if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); + // If we reached the end of the key-value pair we started from, then we know + // that the key is not there so we return false. We are either right before + // the next comma or the final brace. + if(_json_iter->position() == search_start) { return false; } + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + error = has_next_field().get(has_value); SIMDJSON_ASSUME(!error); + // If we make the mistake of exiting here, then we could be left pointing at a key + // in the middle of an object. That's not an allowable state. + } + // If the loop ended, we're out of fields to look at. The program should + // never reach this point. + return false; +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::field_key() noexcept { + assert_at_next(); + + const uint8_t *key = _json_iter->return_current_and_advance(); + if (*(key++) != '"') { return report_error(TAPE_ERROR, "Object key is not a string"); } + return raw_json_string(key); +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::field_value() noexcept { + assert_at_next(); + + if (*_json_iter->return_current_and_advance() != ':') { return report_error(TAPE_ERROR, "Missing colon in object field"); } + _json_iter->descend_to(depth()+1); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_array() noexcept { + SIMDJSON_TRY( start_container('[', "Not an array", "array") ); + return started_array(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_root_array() noexcept { + SIMDJSON_TRY( start_container('[', "Not an array", "array") ); + return started_root_array(); +} + +inline std::string value_iterator::to_string() const noexcept { + auto answer = std::string("value_iterator [ depth : ") + std::to_string(_depth) + std::string(", "); + if(_json_iter != nullptr) { answer += _json_iter->to_string(); } + answer += std::string(" ]"); + return answer; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_array() noexcept { + assert_at_container_start(); + if (*_json_iter->peek() == ']') { + logger::log_value(*_json_iter, "empty array"); + _json_iter->return_current_and_advance(); + SIMDJSON_TRY( end_container() ); + return false; + } + _json_iter->descend_to(depth()+1); +#if SIMDJSON_DEVELOPMENT_CHECKS + _json_iter->set_start_position(_depth, start_position()); +#endif + return true; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::check_root_array() noexcept { + // When in streaming mode, we cannot expect peek_last() to be the last structural element of the + // current document. It only works in the normal mode where we have indexed a single document. + // Note that adding a check for 'streaming' is not expensive since we only have at most + // one root element. + if ( ! _json_iter->streaming() ) { + // The following lines do not fully protect against garbage content within the + // array: e.g., `[1, 2] foo]`. Users concerned with garbage content should + // also call `at_end()` on the document instance at the end of the processing to + // ensure that the processing has finished at the end. + // + if (*_json_iter->peek_last() != ']') { + _json_iter->abandon(); + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing ] at end"); + } + // If the last character is ] *and* the first gibberish character is also ']' + // then on-demand could accidentally go over. So we need additional checks. + // https://github.com/simdjson/simdjson/issues/1834 + // Checking that the document is balanced requires a full scan which is potentially + // expensive, but it only happens in edge cases where the first padding character is + // a closing bracket. + if ((*_json_iter->peek(_json_iter->end_position()) == ']') && (!_json_iter->balanced())) { + _json_iter->abandon(); + // The exact error would require more work. It will typically be an unclosed array. + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "the document is unbalanced"); + } + } + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_root_array() noexcept { + auto error = check_root_array(); + if (error) { return error; } + return started_array(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::has_next_element() noexcept { + assert_at_next(); + + logger::log_event(*this, "has_next_element"); + switch (*_json_iter->return_current_and_advance()) { + case ']': + logger::log_end_value(*_json_iter, "array"); + SIMDJSON_TRY( end_container() ); + return false; + case ',': + _json_iter->descend_to(depth()+1); + return true; + default: + return report_error(TAPE_ERROR, "Missing comma between array elements"); + } +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::parse_bool(const uint8_t *json) const noexcept { + auto not_true = atomparsing::str4ncmp(json, "true"); + auto not_false = atomparsing::str4ncmp(json, "fals") | (json[4] ^ 'e'); + bool error = (not_true && not_false) || jsoncharutils::is_not_structural_or_whitespace(json[not_true ? 5 : 4]); + if (error) { return incorrect_type_error("Not a boolean"); } + return simdjson_result(!not_true); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::parse_null(const uint8_t *json) const noexcept { + bool is_null_string = !atomparsing::str4ncmp(json, "null") && jsoncharutils::is_structural_or_whitespace(json[4]); + // if we start with 'n', we must be a null + if(!is_null_string && json[0]=='n') { return incorrect_type_error("Not a null but starts with n"); } + return is_null_string; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_string(bool allow_replacement) noexcept { + return get_raw_json_string().unescape(json_iter(), allow_replacement); +} +template +simdjson_warn_unused simdjson_inline error_code value_iterator::get_string(string_type& receiver, bool allow_replacement) noexcept { + std::string_view content; + auto err = get_string(allow_replacement).get(content); + if (err) { return err; } + receiver = content; + return SUCCESS; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_wobbly_string() noexcept { + return get_raw_json_string().unescape_wobbly(json_iter()); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_raw_json_string() noexcept { + auto json = peek_scalar("string"); + if (*json != '"') { return incorrect_type_error("Not a string"); } + advance_scalar("string"); + return raw_json_string(json+1); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_uint64() noexcept { + auto result = numberparsing::parse_unsigned(peek_non_root_scalar("uint64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("uint64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_uint64_in_string() noexcept { + auto result = numberparsing::parse_unsigned_in_string(peek_non_root_scalar("uint64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("uint64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_int64() noexcept { + auto result = numberparsing::parse_integer(peek_non_root_scalar("int64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("int64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_int64_in_string() noexcept { + auto result = numberparsing::parse_integer_in_string(peek_non_root_scalar("int64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("int64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_double() noexcept { + auto result = numberparsing::parse_double(peek_non_root_scalar("double")); + if(result.error() == SUCCESS) { advance_non_root_scalar("double"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_double_in_string() noexcept { + auto result = numberparsing::parse_double_in_string(peek_non_root_scalar("double")); + if(result.error() == SUCCESS) { advance_non_root_scalar("double"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_bool() noexcept { + auto result = parse_bool(peek_non_root_scalar("bool")); + if(result.error() == SUCCESS) { advance_non_root_scalar("bool"); } + return result; +} +simdjson_inline simdjson_result value_iterator::is_null() noexcept { + bool is_null_value; + SIMDJSON_TRY(parse_null(peek_non_root_scalar("null")).get(is_null_value)); + if(is_null_value) { advance_non_root_scalar("null"); } + return is_null_value; +} +simdjson_inline bool value_iterator::is_negative() noexcept { + return numberparsing::is_negative(peek_non_root_scalar("numbersign")); +} +simdjson_inline bool value_iterator::is_root_negative() noexcept { + return numberparsing::is_negative(peek_root_scalar("numbersign")); +} +simdjson_inline simdjson_result value_iterator::is_integer() noexcept { + return numberparsing::is_integer(peek_non_root_scalar("integer")); +} +simdjson_inline simdjson_result value_iterator::get_number_type() noexcept { + return numberparsing::get_number_type(peek_non_root_scalar("integer")); +} +simdjson_inline simdjson_result value_iterator::get_number() noexcept { + number num; + error_code error = numberparsing::parse_number(peek_non_root_scalar("number"), num); + if(error) { return error; } + return num; +} + +simdjson_inline simdjson_result value_iterator::is_root_integer(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("is_root_integer"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + return false; // if there are more than 20 characters, it cannot be represented as an integer. + } + auto answer = numberparsing::is_integer(tmpbuf); + // If the parsing was a success, we must still check that it is + // a single scalar. Note that we parse first because of cases like '[]' where + // getting TRAILING_CONTENT is wrong. + if(check_trailing && (answer.error() == SUCCESS) && (!_json_iter->is_single_token())) { return TRAILING_CONTENT; } + return answer; +} + +simdjson_inline simdjson_result value_iterator::get_root_number_type(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("number"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto answer = numberparsing::get_number_type(tmpbuf); + if (check_trailing && (answer.error() == SUCCESS) && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + return answer; +} +simdjson_inline simdjson_result value_iterator::get_root_number(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("number"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + number num; + error_code error = numberparsing::parse_number(tmpbuf, num); + if(error) { return error; } + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("number"); + return num; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_string(bool check_trailing, bool allow_replacement) noexcept { + return get_root_raw_json_string(check_trailing).unescape(json_iter(), allow_replacement); +} +template +simdjson_warn_unused simdjson_inline error_code value_iterator::get_root_string(string_type& receiver, bool check_trailing, bool allow_replacement) noexcept { + std::string_view content; + auto err = get_root_string(check_trailing, allow_replacement).get(content); + if (err) { return err; } + receiver = content; + return SUCCESS; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_wobbly_string(bool check_trailing) noexcept { + return get_root_raw_json_string(check_trailing).unescape_wobbly(json_iter()); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_raw_json_string(bool check_trailing) noexcept { + auto json = peek_scalar("string"); + if (*json != '"') { return incorrect_type_error("Not a string"); } + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_scalar("string"); + return raw_json_string(json+1); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_uint64(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("uint64"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_unsigned(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("uint64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_uint64_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("uint64"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_unsigned_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("uint64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_int64(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("int64"); + uint8_t tmpbuf[20+1+1]; // -<19 digits> is the longest possible integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + + auto result = numberparsing::parse_integer(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("int64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_int64_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("int64"); + uint8_t tmpbuf[20+1+1]; // -<19 digits> is the longest possible integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + + auto result = numberparsing::parse_integer_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("int64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_double(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("double"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; // +1 for null termination. + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_double(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("double"); + } + return result; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_double_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("double"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; // +1 for null termination. + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_double_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("double"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_bool(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("bool"); + uint8_t tmpbuf[5+1+1]; // +1 for null termination + tmpbuf[5+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 5+1)) { return incorrect_type_error("Not a boolean"); } + auto result = parse_bool(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("bool"); + } + return result; +} +simdjson_inline simdjson_result value_iterator::is_root_null(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("null"); + bool result = (max_len >= 4 && !atomparsing::str4ncmp(json, "null") && + (max_len == 4 || jsoncharutils::is_structural_or_whitespace(json[4]))); + if(result) { // we have something that looks like a null. + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("null"); + } + return result; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::skip_child() noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth >= _depth ); + + return _json_iter->skip_child(depth()); +} + +simdjson_inline value_iterator value_iterator::child() const noexcept { + assert_at_child(); + return { _json_iter, depth()+1, _json_iter->token.position() }; +} + +// GCC 7 warns when the first line of this function is inlined away into oblivion due to the caller +// relating depth and iterator depth, which is a desired effect. It does not happen if is_open is +// marked non-inline. +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline bool value_iterator::is_open() const noexcept { + return _json_iter->depth() >= depth(); +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline bool value_iterator::at_end() const noexcept { + return _json_iter->at_end(); +} + +simdjson_inline bool value_iterator::at_start() const noexcept { + return _json_iter->token.position() == start_position(); +} + +simdjson_inline bool value_iterator::at_first_field() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + return _json_iter->token.position() == start_position() + 1; +} + +simdjson_inline void value_iterator::abandon() noexcept { + _json_iter->abandon(); +} + +simdjson_warn_unused simdjson_inline depth_t value_iterator::depth() const noexcept { + return _depth; +} +simdjson_warn_unused simdjson_inline error_code value_iterator::error() const noexcept { + return _json_iter->error; +} +simdjson_warn_unused simdjson_inline uint8_t *&value_iterator::string_buf_loc() noexcept { + return _json_iter->string_buf_loc(); +} +simdjson_warn_unused simdjson_inline const json_iterator &value_iterator::json_iter() const noexcept { + return *_json_iter; +} +simdjson_warn_unused simdjson_inline json_iterator &value_iterator::json_iter() noexcept { + return *_json_iter; +} + +simdjson_inline const uint8_t *value_iterator::peek_start() const noexcept { + return _json_iter->peek(start_position()); +} +simdjson_inline uint32_t value_iterator::peek_start_length() const noexcept { + return _json_iter->peek_length(start_position()); +} + +simdjson_inline const uint8_t *value_iterator::peek_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + if (!is_at_start()) { return peek_start(); } + + // Get the JSON and advance the cursor, decreasing depth to signify that we have retrieved the value. + assert_at_start(); + return _json_iter->peek(); +} + +simdjson_inline void value_iterator::advance_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + if (!is_at_start()) { return; } + + // Get the JSON and advance the cursor, decreasing depth to signify that we have retrieved the value. + assert_at_start(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} + +simdjson_inline error_code value_iterator::start_container(uint8_t start_char, const char *incorrect_type_message, const char *type) noexcept { + logger::log_start_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + const uint8_t *json; + if (!is_at_start()) { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + json = peek_start(); + if (*json != start_char) { return incorrect_type_error(incorrect_type_message); } + } else { + assert_at_start(); + /** + * We should be prudent. Let us peek. If it is not the right type, we + * return an error. Only once we have determined that we have the right + * type are we allowed to advance! + */ + json = _json_iter->peek(); + if (*json != start_char) { return incorrect_type_error(incorrect_type_message); } + _json_iter->return_current_and_advance(); + } + + + return SUCCESS; +} + + +simdjson_inline const uint8_t *value_iterator::peek_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return peek_start(); } + + assert_at_root(); + return _json_iter->peek(); +} +simdjson_inline const uint8_t *value_iterator::peek_non_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return peek_start(); } + + assert_at_non_root_start(); + return _json_iter->peek(); +} + +simdjson_inline void value_iterator::advance_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return; } + + assert_at_root(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} +simdjson_inline void value_iterator::advance_non_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return; } + + assert_at_non_root_start(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} + +simdjson_inline error_code value_iterator::incorrect_type_error(const char *message) const noexcept { + logger::log_error(*_json_iter, start_position(), depth(), message); + return INCORRECT_TYPE; +} + +simdjson_inline bool value_iterator::is_at_start() const noexcept { + return position() == start_position(); +} + +simdjson_inline bool value_iterator::is_at_key() const noexcept { + // Keys are at the same depth as the object. + // Note here that we could be safer and check that we are within an object, + // but we do not. + return _depth == _json_iter->_depth && *_json_iter->peek() == '"'; +} + +simdjson_inline bool value_iterator::is_at_iterator_start() const noexcept { + // We can legitimately be either at the first value ([1]), or after the array if it's empty ([]). + auto delta = position() - start_position(); + return delta == 1 || delta == 2; +} + +inline void value_iterator::assert_at_start() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position == _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_container_start() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position == _start_position + 1 ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_next() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +simdjson_inline void value_iterator::move_at_start() noexcept { + _json_iter->_depth = _depth; + _json_iter->token.set_position(_start_position); +} + +simdjson_inline void value_iterator::move_at_container_start() noexcept { + _json_iter->_depth = _depth; + _json_iter->token.set_position(_start_position + 1); +} + +simdjson_inline simdjson_result value_iterator::reset_array() noexcept { + if(error()) { return error(); } + move_at_container_start(); + return started_array(); +} + +simdjson_inline simdjson_result value_iterator::reset_object() noexcept { + if(error()) { return error(); } + move_at_container_start(); + return started_object(); +} + +inline void value_iterator::assert_at_child() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth + 1 ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_root() const noexcept { + assert_at_start(); + SIMDJSON_ASSUME( _depth == 1 ); +} + +inline void value_iterator::assert_at_non_root_start() const noexcept { + assert_at_start(); + SIMDJSON_ASSUME( _depth > 1 ); +} + +inline void value_iterator::assert_is_valid() const noexcept { + SIMDJSON_ASSUME( _json_iter != nullptr ); +} + +simdjson_inline bool value_iterator::is_valid() const noexcept { + return _json_iter != nullptr; +} + +simdjson_inline simdjson_result value_iterator::type() const noexcept { + switch (*peek_start()) { + case '{': + return json_type::object; + case '[': + return json_type::array; + case '"': + return json_type::string; + case 'n': + return json_type::null; + case 't': case 'f': + return json_type::boolean; + case '-': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return json_type::number; + default: + return TAPE_ERROR; + } +} + +simdjson_inline token_position value_iterator::start_position() const noexcept { + return _start_position; +} + +simdjson_inline token_position value_iterator::position() const noexcept { + return _json_iter->position(); +} + +simdjson_inline token_position value_iterator::end_position() const noexcept { + return _json_iter->end_position(); +} + +simdjson_inline token_position value_iterator::last_position() const noexcept { + return _json_iter->last_position(); +} + +simdjson_inline error_code value_iterator::report_error(error_code error, const char *message) noexcept { + return _json_iter->report_error(error, message); +} + +} // namespace ondemand +} // namespace arm64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(arm64::ondemand::value_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/value_iterator-inl.h for arm64 */ +/* end file simdjson/generic/ondemand/amalgamated.h for arm64 */ +/* including simdjson/arm64/end.h: #include "simdjson/arm64/end.h" */ +/* begin file simdjson/arm64/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/arm64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#undef SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT +/* undefining SIMDJSON_IMPLEMENTATION from "arm64" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/arm64/end.h */ + +#endif // SIMDJSON_ARM64_ONDEMAND_H +/* end file simdjson/arm64/ondemand.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(fallback) +/* including simdjson/fallback/ondemand.h: #include "simdjson/fallback/ondemand.h" */ +/* begin file simdjson/fallback/ondemand.h */ +#ifndef SIMDJSON_FALLBACK_ONDEMAND_H +#define SIMDJSON_FALLBACK_ONDEMAND_H + +/* including simdjson/fallback/begin.h: #include "simdjson/fallback/begin.h" */ +/* begin file simdjson/fallback/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "fallback" */ +#define SIMDJSON_IMPLEMENTATION fallback +/* including simdjson/fallback/base.h: #include "simdjson/fallback/base.h" */ +/* begin file simdjson/fallback/base.h */ +#ifndef SIMDJSON_FALLBACK_BASE_H +#define SIMDJSON_FALLBACK_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Fallback implementation (runs on any machine). + */ +namespace fallback { + +class implementation; + +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_BASE_H +/* end file simdjson/fallback/base.h */ +/* including simdjson/fallback/bitmanipulation.h: #include "simdjson/fallback/bitmanipulation.h" */ +/* begin file simdjson/fallback/bitmanipulation.h */ +#ifndef SIMDJSON_FALLBACK_BITMANIPULATION_H +#define SIMDJSON_FALLBACK_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace { + +#if defined(_MSC_VER) && !defined(_M_ARM64) && !defined(_M_X64) +static inline unsigned char _BitScanForward64(unsigned long* ret, uint64_t x) { + unsigned long x0 = (unsigned long)x, top, bottom; + _BitScanForward(&top, (unsigned long)(x >> 32)); + _BitScanForward(&bottom, x0); + *ret = x0 ? bottom : 32 + top; + return x != 0; +} +static unsigned char _BitScanReverse64(unsigned long* ret, uint64_t x) { + unsigned long x1 = (unsigned long)(x >> 32), top, bottom; + _BitScanReverse(&top, x1); + _BitScanReverse(&bottom, (unsigned long)x); + *ret = x1 ? top + 32 : bottom; + return x != 0; +} +#endif + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#ifdef _MSC_VER + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// _MSC_VER +} + +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_BITMANIPULATION_H +/* end file simdjson/fallback/bitmanipulation.h */ +/* including simdjson/fallback/stringparsing_defs.h: #include "simdjson/fallback/stringparsing_defs.h" */ +/* begin file simdjson/fallback/stringparsing_defs.h */ +#ifndef SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H +#define SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace { + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 1; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return c == '"'; } + simdjson_inline bool has_backslash() { return c == '\\'; } + simdjson_inline int quote_index() { return c == '"' ? 0 : 1; } + simdjson_inline int backslash_index() { return c == '\\' ? 0 : 1; } + + uint8_t c; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // store to dest unconditionally - we can overwrite the bits we don't like later + dst[0] = src[0]; + return { src[0] }; +} + +} // unnamed namespace +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H +/* end file simdjson/fallback/stringparsing_defs.h */ +/* including simdjson/fallback/numberparsing_defs.h: #include "simdjson/fallback/numberparsing_defs.h" */ +/* begin file simdjson/fallback/numberparsing_defs.h */ +#ifndef SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H +#define SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +#ifdef JSON_TEST_NUMBERS // for unit testing +void found_invalid_number(const uint8_t *buf); +void found_integer(int64_t result, const uint8_t *buf); +void found_unsigned_integer(uint64_t result, const uint8_t *buf); +void found_float(double result, const uint8_t *buf); +#endif + +namespace simdjson { +namespace fallback { +namespace numberparsing { + +// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const char *chars) { + uint64_t val; + memcpy(&val, chars, sizeof(uint64_t)); + val = (val & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8; + val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16; + return uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32); +} + +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + return parse_eight_digits_unrolled(reinterpret_cast(chars)); +} + +#if SIMDJSON_IS_32BITS // _umul128 for x86, arm +// this is a slow emulation routine for 32-bit +// +static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} +static simdjson_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = !!(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = __emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + !!(lo < bd); + return lo; +} +#endif + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace fallback +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H +/* end file simdjson/fallback/numberparsing_defs.h */ +/* end file simdjson/fallback/begin.h */ +/* including simdjson/generic/ondemand/amalgamated.h for fallback: #include "simdjson/generic/ondemand/amalgamated.h" */ +/* begin file simdjson/generic/ondemand/amalgamated.h for fallback */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H) +#error simdjson/generic/ondemand/dependencies.h must be included before simdjson/generic/ondemand/amalgamated.h! +#endif + +// Stuff other things depend on +/* including simdjson/generic/ondemand/base.h for fallback: #include "simdjson/generic/ondemand/base.h" */ +/* begin file simdjson/generic/ondemand/base.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +/** + * A fast, simple, DOM-like interface that parses JSON as you use it. + * + * Designed for maximum speed and a lower memory profile. + */ +namespace ondemand { + +/** Represents the depth of a JSON value (number of nested arrays/objects). */ +using depth_t = int32_t; + +/** @copydoc simdjson::fallback::number_type */ +using number_type = simdjson::fallback::number_type; + +/** @private Position in the JSON buffer indexes */ +using token_position = const uint32_t *; + +class array; +class array_iterator; +class document; +class document_reference; +class document_stream; +class field; +class json_iterator; +enum class json_type; +struct number; +class object; +class object_iterator; +class parser; +class raw_json_string; +class token_iterator; +class value; +class value_iterator; + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_BASE_H +/* end file simdjson/generic/ondemand/base.h for fallback */ +/* including simdjson/generic/ondemand/value_iterator.h for fallback: #include "simdjson/generic/ondemand/value_iterator.h" */ +/* begin file simdjson/generic/ondemand/value_iterator.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +/** + * Iterates through a single JSON value at a particular depth. + * + * Does not keep track of the type of value: provides methods for objects, arrays and scalars and expects + * the caller to call the right ones. + * + * @private This is not intended for external use. + */ +class value_iterator { +protected: + /** The underlying JSON iterator */ + json_iterator *_json_iter{}; + /** The depth of this value */ + depth_t _depth{}; + /** + * The starting token index for this value + */ + token_position _start_position{}; + +public: + simdjson_inline value_iterator() noexcept = default; + + /** + * Denote that we're starting a document. + */ + simdjson_inline void start_document() noexcept; + + /** + * Skips a non-iterated or partially-iterated JSON value, whether it is a scalar, array or object. + * + * Optimized for scalars. + */ + simdjson_warn_unused simdjson_inline error_code skip_child() noexcept; + + /** + * Tell whether the iterator is at the EOF mark + */ + simdjson_inline bool at_end() const noexcept; + + /** + * Tell whether the iterator is at the start of the value + */ + simdjson_inline bool at_start() const noexcept; + + /** + * Tell whether the value is open--if the value has not been used, or the array/object is still open. + */ + simdjson_inline bool is_open() const noexcept; + + /** + * Tell whether the value is at an object's first field (just after the {). + */ + simdjson_inline bool at_first_field() const noexcept; + + /** + * Abandon all iteration. + */ + simdjson_inline void abandon() noexcept; + + /** + * Get the child value as a value_iterator. + */ + simdjson_inline value_iterator child_value() const noexcept; + + /** + * Get the depth of this value. + */ + simdjson_inline int32_t depth() const noexcept; + + /** + * Get the JSON type of this value. + * + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() const noexcept; + + /** + * @addtogroup object Object iteration + * + * Methods to iterate and find object fields. These methods generally *assume* the value is + * actually an object; the caller is responsible for keeping track of that fact. + * + * @{ + */ + + /** + * Start an object iteration. + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCORRECT_TYPE if there is no opening { + */ + simdjson_warn_unused simdjson_inline simdjson_result start_object() noexcept; + /** + * Start an object iteration from the root. + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCORRECT_TYPE if there is no opening { + * @error TAPE_ERROR if there is no matching } at end of document + */ + simdjson_warn_unused simdjson_inline simdjson_result start_root_object() noexcept; + /** + * Checks whether an object could be started from the root. May be called by start_root_object. + * + * @returns SUCCESS if it is possible to safely start an object from the root (document level). + * @error INCORRECT_TYPE if there is no opening { + * @error TAPE_ERROR if there is no matching } at end of document + */ + simdjson_warn_unused simdjson_inline error_code check_root_object() noexcept; + /** + * Start an object iteration after the user has already checked and moved past the {. + * + * Does not move the iterator unless the object is empty ({}). + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_object() noexcept; + /** + * Start an object iteration from the root, after the user has already checked and moved past the {. + * + * Does not move the iterator unless the object is empty ({}). + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_root_object() noexcept; + + /** + * Moves to the next field in an object. + * + * Looks for , and }. If } is found, the object is finished and the iterator advances past it. + * Otherwise, it advances to the next value. + * + * @return whether there is another field in the object. + * @error TAPE_ERROR If there is a comma missing between fields. + * @error TAPE_ERROR If there is a comma, but not enough tokens remaining to have a key, :, and value. + */ + simdjson_warn_unused simdjson_inline simdjson_result has_next_field() noexcept; + + /** + * Get the current field's key. + */ + simdjson_warn_unused simdjson_inline simdjson_result field_key() noexcept; + + /** + * Pass the : in the field and move to its value. + */ + simdjson_warn_unused simdjson_inline error_code field_value() noexcept; + + /** + * Find the next field with the given key. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline error_code find_field(const std::string_view key) noexcept; + + /** + * Find the next field with the given key, *without* unescaping. This assumes object order: it + * will not find the field if it was already passed when looking for some *other* field. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline simdjson_result find_field_raw(const std::string_view key) noexcept; + + /** + * Find the field with the given key without regard to order, and *without* unescaping. + * + * This is an unordered object lookup: if the field is not found initially, it will cycle around and scan from the beginning. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline simdjson_result find_field_unordered_raw(const std::string_view key) noexcept; + + /** @} */ + + /** + * @addtogroup array Array iteration + * Methods to iterate over array elements. These methods generally *assume* the value is actually + * an object; the caller is responsible for keeping track of that fact. + * @{ + */ + + /** + * Check for an opening [ and start an array iteration. + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCORRECT_TYPE If there is no [. + */ + simdjson_warn_unused simdjson_inline simdjson_result start_array() noexcept; + /** + * Check for an opening [ and start an array iteration while at the root. + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCORRECT_TYPE If there is no [. + * @error TAPE_ERROR if there is no matching ] at end of document + */ + simdjson_warn_unused simdjson_inline simdjson_result start_root_array() noexcept; + /** + * Checks whether an array could be started from the root. May be called by start_root_array. + * + * @returns SUCCESS if it is possible to safely start an array from the root (document level). + * @error INCORRECT_TYPE If there is no [. + * @error TAPE_ERROR if there is no matching ] at end of document + */ + simdjson_warn_unused simdjson_inline error_code check_root_array() noexcept; + /** + * Start an array iteration, after the user has already checked and moved past the [. + * + * Does not move the iterator unless the array is empty ([]). + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_array() noexcept; + /** + * Start an array iteration from the root, after the user has already checked and moved past the [. + * + * Does not move the iterator unless the array is empty ([]). + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_root_array() noexcept; + + /** + * Moves to the next element in an array. + * + * Looks for , and ]. If ] is found, the array is finished and the iterator advances past it. + * Otherwise, it advances to the next value. + * + * @return Whether there is another element in the array. + * @error TAPE_ERROR If there is a comma missing between elements. + */ + simdjson_warn_unused simdjson_inline simdjson_result has_next_element() noexcept; + + /** + * Get a child value iterator. + */ + simdjson_warn_unused simdjson_inline value_iterator child() const noexcept; + + /** @} */ + + /** + * @defgroup scalar Scalar values + * @addtogroup scalar + * @{ + */ + + simdjson_warn_unused simdjson_inline simdjson_result get_string(bool allow_replacement) noexcept; + template + simdjson_warn_unused simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_int64() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_double() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_bool() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_null() noexcept; + simdjson_warn_unused simdjson_inline bool is_negative() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_integer() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + simdjson_warn_unused simdjson_inline simdjson_result get_root_string(bool check_trailing, bool allow_replacement) noexcept; + template + simdjson_warn_unused simdjson_inline error_code get_root_string(string_type& receiver, bool check_trailing, bool allow_replacement) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_wobbly_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_raw_json_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_uint64(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_uint64_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_int64(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_int64_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_double(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_double_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_bool(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline bool is_root_negative() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_root_integer(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_number_type(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_number(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_root_null(bool check_trailing) noexcept; + + simdjson_inline error_code error() const noexcept; + simdjson_inline uint8_t *&string_buf_loc() noexcept; + simdjson_inline const json_iterator &json_iter() const noexcept; + simdjson_inline json_iterator &json_iter() noexcept; + + simdjson_inline void assert_is_valid() const noexcept; + simdjson_inline bool is_valid() const noexcept; + + /** @} */ +protected: + /** + * Restarts an array iteration. + * @returns Whether the array has any elements (returns false for empty). + */ + simdjson_inline simdjson_result reset_array() noexcept; + /** + * Restarts an object iteration. + * @returns Whether the object has any fields (returns false for empty). + */ + simdjson_inline simdjson_result reset_object() noexcept; + /** + * move_at_start(): moves us so that we are pointing at the beginning of + * the container. It updates the index so that at_start() is true and it + * syncs the depth. The user can then create a new container instance. + * + * Usage: used with value::count_elements(). + **/ + simdjson_inline void move_at_start() noexcept; + + /** + * move_at_container_start(): moves us so that we are pointing at the beginning of + * the container so that assert_at_container_start() passes. + * + * Usage: used with reset_array() and reset_object(). + **/ + simdjson_inline void move_at_container_start() noexcept; + /* Useful for debugging and logging purposes. */ + inline std::string to_string() const noexcept; + simdjson_inline value_iterator(json_iterator *json_iter, depth_t depth, token_position start_index) noexcept; + + simdjson_inline simdjson_result parse_null(const uint8_t *json) const noexcept; + simdjson_inline simdjson_result parse_bool(const uint8_t *json) const noexcept; + simdjson_inline const uint8_t *peek_start() const noexcept; + simdjson_inline uint32_t peek_start_length() const noexcept; + + /** + * The general idea of the advance_... methods and the peek_* methods + * is that you first peek and check that you have desired type. If you do, + * and only if you do, then you advance. + * + * We used to unconditionally advance. But this made reasoning about our + * current state difficult. + * Suppose you always advance. Look at the 'value' matching the key + * "shadowable" in the following example... + * + * ({"globals":{"a":{"shadowable":[}}}}) + * + * If the user thinks it is a Boolean and asks for it, then we check the '[', + * decide it is not a Boolean, but still move into the next character ('}'). Now + * we are left pointing at '}' right after a '['. And we have not yet reported + * an error, only that we do not have a Boolean. + * + * If, instead, you just stand your ground until it is content that you know, then + * you will only even move beyond the '[' if the user tells you that you have an + * array. So you will be at the '}' character inside the array and, hopefully, you + * will then catch the error because an array cannot start with '}', but the code + * processing Boolean values does not know this. + * + * So the contract is: first call 'peek_...' and then call 'advance_...' only + * if you have determined that it is a type you can handle. + * + * Unfortunately, it makes the code more verbose, longer and maybe more error prone. + */ + + simdjson_inline void advance_scalar(const char *type) noexcept; + simdjson_inline void advance_root_scalar(const char *type) noexcept; + simdjson_inline void advance_non_root_scalar(const char *type) noexcept; + + simdjson_inline const uint8_t *peek_scalar(const char *type) noexcept; + simdjson_inline const uint8_t *peek_root_scalar(const char *type) noexcept; + simdjson_inline const uint8_t *peek_non_root_scalar(const char *type) noexcept; + + + simdjson_inline error_code start_container(uint8_t start_char, const char *incorrect_type_message, const char *type) noexcept; + simdjson_inline error_code end_container() noexcept; + + /** + * Advance to a place expecting a value (increasing depth). + * + * @return The current token (the one left behind). + * @error TAPE_ERROR If the document ended early. + */ + simdjson_inline simdjson_result advance_to_value() noexcept; + + simdjson_inline error_code incorrect_type_error(const char *message) const noexcept; + simdjson_inline error_code error_unless_more_tokens(uint32_t tokens=1) const noexcept; + + simdjson_inline bool is_at_start() const noexcept; + /** + * is_at_iterator_start() returns true on an array or object after it has just been + * created, whether the instance is empty or not. + * + * Usage: used by array::begin() in debug mode (SIMDJSON_DEVELOPMENT_CHECKS) + */ + simdjson_inline bool is_at_iterator_start() const noexcept; + + /** + * Assuming that we are within an object, this returns true if we + * are pointing at a key. + * + * Usage: the skip_child() method should never be used while we are pointing + * at a key inside an object. + */ + simdjson_inline bool is_at_key() const noexcept; + + inline void assert_at_start() const noexcept; + inline void assert_at_container_start() const noexcept; + inline void assert_at_root() const noexcept; + inline void assert_at_child() const noexcept; + inline void assert_at_next() const noexcept; + inline void assert_at_non_root_start() const noexcept; + + /** Get the starting position of this value */ + simdjson_inline token_position start_position() const noexcept; + + /** @copydoc error_code json_iterator::position() const noexcept; */ + simdjson_inline token_position position() const noexcept; + /** @copydoc error_code json_iterator::end_position() const noexcept; */ + simdjson_inline token_position last_position() const noexcept; + /** @copydoc error_code json_iterator::end_position() const noexcept; */ + simdjson_inline token_position end_position() const noexcept; + /** @copydoc error_code json_iterator::report_error(error_code error, const char *message) noexcept; */ + simdjson_inline error_code report_error(error_code error, const char *message) noexcept; + + friend class document; + friend class object; + friend class array; + friend class value; +}; // value_iterator + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::value_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H +/* end file simdjson/generic/ondemand/value_iterator.h for fallback */ +/* including simdjson/generic/ondemand/value.h for fallback: #include "simdjson/generic/ondemand/value.h" */ +/* begin file simdjson/generic/ondemand/value.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +/** + * An ephemeral JSON value returned during iteration. It is only valid for as long as you do + * not access more data in the JSON document. + */ +class value { +public: + /** + * Create a new invalid value. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline value() noexcept = default; + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * You may use get_double(), get_bool(), get_uint64(), get_int64(), + * get_object(), get_array(), get_raw_json_string(), or get_string() instead. + * + * @returns A value of the given type, parsed from the JSON. + * @returns INCORRECT_TYPE If the JSON value is not the given type. + */ + template simdjson_inline simdjson_result get() noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * @param out This is set to a value of the given type, parsed from the JSON. If there is an error, this may not be initialized. + * @returns INCORRECT_TYPE If the JSON value is not an object. + * @returns SUCCESS If the parse succeeded and the out parameter was set to the value. + */ + template simdjson_inline error_code get(T &out) noexcept; + + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result get_array() noexcept; + + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @returns INCORRECT_TYPE If the JSON value is not an object. + */ + simdjson_inline simdjson_result get_object() noexcept; + + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A unsigned 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64() noexcept; + + /** + * Cast this JSON value (inside string) to a unsigned integer. + * + * @returns A unsigned 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64() noexcept; + + /** + * Cast this JSON value (inside string) to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64_in_string() noexcept; + + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double() noexcept; + + /** + * Cast this JSON value (inside string) to a double + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double_in_string() noexcept; + + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Equivalent to get(). + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + + /** + * Attempts to fill the provided std::string reference with the parsed value of the current string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory. + * We recommend you avoid allocating an std::string unless you need to. + * + * @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS. + */ + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + + /** + * Cast this JSON value to a "wobbly" string. + * + * The string is may not be a valid UTF-8 string. + * See https://simonsapin.github.io/wtf-8/ + * + * Important: a value should be consumed once. Calling get_wobbly_string() twice on the same value + * is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_wobbly_string() noexcept; + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_raw_json_string() noexcept; + + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @returns INCORRECT_TYPE if the JSON value is not true or false. + */ + simdjson_inline simdjson_result get_bool() noexcept; + + /** + * Checks if this JSON value is null. If and only if the value is + * null, then it is consumed (we advance). If we find a token that + * begins with 'n' but is not 'null', then an error is returned. + * + * @returns Whether the value is null. + * @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'. + */ + simdjson_inline simdjson_result is_null() noexcept; + +#if SIMDJSON_EXCEPTIONS + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an array. + */ + simdjson_inline operator array() noexcept(false); + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an object. + */ + simdjson_inline operator object() noexcept(false); + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline operator uint64_t() noexcept(false); + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer. + */ + simdjson_inline operator int64_t() noexcept(false); + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number. + */ + simdjson_inline operator double() noexcept(false); + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Equivalent to get(). + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator std::string_view() noexcept(false); + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator raw_json_string() noexcept(false); + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false. + */ + simdjson_inline operator bool() noexcept(false); +#endif + + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + * + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result begin() & noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() & noexcept; + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * Performance hint: You should only call count_elements() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method on the object instance. + * + * Performance hint: You should only call count_fields() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Get the value at the given index in the array. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) noexcept; + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) noexcept; + + /** + * Get the type of this JSON value. It does not validate or consume the value. + * E.g., you must still call "is_null()" to check that a value is null even if + * "type()" returns json_type::null. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + * + * @return The type of JSON value (json_type::array, json_type::object, json_type::string, + * json_type::number, json_type::boolean, or json_type::null). + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() noexcept; + + /** + * Checks whether the value is a scalar (string, number, null, Boolean). + * Returns false when there it is an array or object. + * + * @returns true if the type is string, number, null, Boolean + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result is_scalar() noexcept; + + /** + * Checks whether the value is a negative number. + * + * @returns true if the number if negative. + */ + simdjson_inline bool is_negative() noexcept; + /** + * Checks whether the value is an integer number. Note that + * this requires to partially parse the number string. If + * the value is determined to be an integer, it may still + * not parse properly as an integer in subsequent steps + * (e.g., it might overflow). + * + * Performance note: if you call this function systematically + * before parsing a number, you may have fallen for a performance + * anti-pattern. + * + * @returns true if the number if negative. + */ + simdjson_inline simdjson_result is_integer() noexcept; + /** + * Determine the number type (integer or floating-point number) as quickly + * as possible. This function does not fully validate the input. It is + * useful when you only need to classify the numbers, without parsing them. + * + * If you are planning to retrieve the value or you need full validation, + * consider using the get_number() method instead: it will fully parse + * and validate the input, and give you access to the type: + * get_number().get_number_type(). + * + * get_number_type() is number_type::unsigned_integer if we have + * an integer greater or equal to 9223372036854775808 + * get_number_type() is number_type::signed_integer if we have an + * integer that is less than 9223372036854775808 + * Otherwise, get_number_type() has value number_type::floating_point_number + * + * This function requires processing the number string, but it is expected + * to be faster than get_number().get_number_type() because it is does not + * parse the number value. + * + * @returns the type of the number + */ + simdjson_inline simdjson_result get_number_type() noexcept; + + /** + * Attempt to parse an ondemand::number. An ondemand::number may + * contain an integer value or a floating-point value, the simdjson + * library will autodetect the type. Thus it is a dynamically typed + * number. Before accessing the value, you must determine the detected + * type. + * + * number.get_number_type() is number_type::signed_integer if we have + * an integer in [-9223372036854775808,9223372036854775808) + * You can recover the value by calling number.get_int64() and you + * have that number.is_int64() is true. + * + * number.get_number_type() is number_type::unsigned_integer if we have + * an integer in [9223372036854775808,18446744073709551616) + * You can recover the value by calling number.get_uint64() and you + * have that number.is_uint64() is true. + * + * Otherwise, number.get_number_type() has value number_type::floating_point_number + * and we have a binary64 number. + * You can recover the value by calling number.get_double() and you + * have that number.is_double() is true. + * + * You must check the type before accessing the value: it is an error + * to call "get_int64()" when number.get_number_type() is not + * number_type::signed_integer and when number.is_int64() is false. + * + * Performance note: this is designed with performance in mind. When + * calling 'get_number()', you scan the number string only once, determining + * efficiently the type and storing it in an efficient manner. + */ + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + + /** + * Get the raw JSON for this token. + * + * The string_view will always point into the input buffer. + * + * The string_view will start at the beginning of the token, and include the entire token + * *as well as all spaces until the next token (or EOF).* This means, for example, that a + * string token always begins with a " and is always terminated by the final ", possibly + * followed by a number of spaces. + * + * The string_view is *not* null-terminated. However, if this is a scalar (string, number, + * boolean, or null), the character after the end of the string_view is guaranteed to be + * a non-space token. + * + * Tokens include: + * - { + * - [ + * - "a string (possibly with UTF-8 or backslashed characters like \\\")". + * - -1.2e-100 + * - true + * - false + * - null + * + * See also value::raw_json(). + */ + simdjson_inline std::string_view raw_json_token() noexcept; + + /** + * Get a string_view pointing at this value in the JSON document. + * If this element is an array or an object, it consumes the array or the object + * and returns a string_view instance corresponding to the + * array as represented in JSON. It points inside the original document. + * If this element is a scalar (string, number, Boolean, null), it returns what + * raw_json_token() would return. + */ + simdjson_inline simdjson_result raw_json() noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + simdjson_inline simdjson_result current_location() noexcept; + + /** + * Returns the current depth in the document if in bounds. + * + * E.g., + * 0 = finished with document + * 1 = document root value (could be [ or {, not yet known) + * 2 = , or } inside root array/object + * 3 = key or value inside root array/object. + */ + simdjson_inline int32_t current_depth() const noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. + * + * Calling at_pointer() on non-document instances (e.g., arrays and objects) is not + * standardized (by RFC 6901). We provide some experimental support for JSON pointers + * on non-document instances. Yet it is not the case when calling at_pointer on an array + * or an object instance: there is no rewind and no invalidation. + * + * You may only call at_pointer on an array after it has been created, but before it has + * been first accessed. When calling at_pointer on an array, the pointer is advanced to + * the location indicated by the JSON pointer (in case of success). It is no longer possible + * to call at_pointer on the same array. + * + * You may call at_pointer more than once on an object, but each time the pointer is advanced + * to be within the value matched by the key indicated by the JSON pointer query. Thus any preceding + * key (as well as the current key) can no longer be used with following JSON pointer calls. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + +protected: + /** + * Create a value. + */ + simdjson_inline value(const value_iterator &iter) noexcept; + + /** + * Skip this value, allowing iteration to continue. + */ + simdjson_inline void skip() noexcept; + + /** + * Start a value at the current position. + * + * (It should already be started; this is just a self-documentation method.) + */ + static simdjson_inline value start(const value_iterator &iter) noexcept; + + /** + * Resume a value. + */ + static simdjson_inline value resume(const value_iterator &iter) noexcept; + + /** + * Get the object, starting or resuming it as necessary + */ + simdjson_inline simdjson_result start_or_resume_object() noexcept; + + // simdjson_inline void log_value(const char *type) const noexcept; + // simdjson_inline void log_error(const char *message) const noexcept; + + value_iterator iter{}; + + friend class document; + friend class array_iterator; + friend class field; + friend class object; + friend struct simdjson_result; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::value &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result get_array() noexcept; + simdjson_inline simdjson_result get_object() noexcept; + + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + + template simdjson_inline simdjson_result get() noexcept; + + template simdjson_inline error_code get(T &out) noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator fallback::ondemand::array() noexcept(false); + simdjson_inline operator fallback::ondemand::object() noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator fallback::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) noexcept; + + /** + * Get the type of this JSON value. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + */ + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + + /** @copydoc simdjson_inline std::string_view value::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + + /** @copydoc simdjson_inline simdjson_result current_location() noexcept */ + simdjson_inline simdjson_result current_location() noexcept; + /** @copydoc simdjson_inline int32_t current_depth() const noexcept */ + simdjson_inline simdjson_result current_depth() const noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_H +/* end file simdjson/generic/ondemand/value.h for fallback */ +/* including simdjson/generic/ondemand/logger.h for fallback: #include "simdjson/generic/ondemand/logger.h" */ +/* begin file simdjson/generic/ondemand/logger.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_LOGGER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_LOGGER_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +// Logging should be free unless SIMDJSON_VERBOSE_LOGGING is set. Importantly, it is critical +// that the call to the log functions be side-effect free. Thus, for example, you should not +// create temporary std::string instances. +namespace logger { + +enum class log_level : int32_t { + info = 0, + error = 1 +}; + +#if SIMDJSON_VERBOSE_LOGGING + static constexpr const bool LOG_ENABLED = true; +#else + static constexpr const bool LOG_ENABLED = false; +#endif + +// We do not want these functions to be 'really inlined' since real inlining is +// for performance purposes and if you are using the loggers, you do not care about +// performance (or should not). +static inline void log_headers() noexcept; +// If args are provided, title will be treated as format string +template +static inline void log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +template +static inline void log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; +static inline void log_event(const json_iterator &iter, const char *type, std::string_view detail="", int delta=0, int depth_delta=0) noexcept; +static inline void log_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail="") noexcept; +static inline void log_value(const json_iterator &iter, const char *type, std::string_view detail="", int delta=-1, int depth_delta=0) noexcept; +static inline void log_start_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail="") noexcept; +static inline void log_start_value(const json_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_end_value(const json_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; + +static inline void log_error(const json_iterator &iter, token_position index, depth_t depth, const char *error, const char *detail="") noexcept; +static inline void log_error(const json_iterator &iter, const char *error, const char *detail="", int delta=-1, int depth_delta=0) noexcept; + +static inline void log_event(const value_iterator &iter, const char *type, std::string_view detail="", int delta=0, int depth_delta=0) noexcept; +static inline void log_value(const value_iterator &iter, const char *type, std::string_view detail="", int delta=-1, int depth_delta=0) noexcept; +static inline void log_start_value(const value_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_end_value(const value_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_error(const value_iterator &iter, const char *error, const char *detail="", int delta=-1, int depth_delta=0) noexcept; + +} // namespace logger +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_LOGGER_H +/* end file simdjson/generic/ondemand/logger.h for fallback */ +/* including simdjson/generic/ondemand/token_iterator.h for fallback: #include "simdjson/generic/ondemand/token_iterator.h" */ +/* begin file simdjson/generic/ondemand/token_iterator.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +/** + * Iterates through JSON tokens (`{` `}` `[` `]` `,` `:` `""` `123` `true` `false` `null`) + * detected by stage 1. + * + * @private This is not intended for external use. + */ +class token_iterator { +public: + /** + * Create a new invalid token_iterator. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline token_iterator() noexcept = default; + simdjson_inline token_iterator(token_iterator &&other) noexcept = default; + simdjson_inline token_iterator &operator=(token_iterator &&other) noexcept = default; + simdjson_inline token_iterator(const token_iterator &other) noexcept = default; + simdjson_inline token_iterator &operator=(const token_iterator &other) noexcept = default; + + /** + * Advance to the next token (returning the current one). + */ + simdjson_inline const uint8_t *return_current_and_advance() noexcept; + /** + * Reports the current offset in bytes from the start of the underlying buffer. + */ + simdjson_inline uint32_t current_offset() const noexcept; + /** + * Get the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(int32_t delta=0) const noexcept; + /** + * Get the maximum length of the JSON text for a given token. + * + * The length will include any whitespace at the end of the token. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_length(int32_t delta=0) const noexcept; + + /** + * Get the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token. + * + */ + simdjson_inline const uint8_t *peek(token_position position) const noexcept; + /** + * Get the maximum length of the JSON text for a given token. + * + * The length will include any whitespace at the end of the token. + * + * @param position The position of the token. + */ + simdjson_inline uint32_t peek_length(token_position position) const noexcept; + + /** + * Return the current index. + */ + simdjson_inline token_position position() const noexcept; + /** + * Reset to a previously saved index. + */ + simdjson_inline void set_position(token_position target_position) noexcept; + + // NOTE: we don't support a full C++ iterator interface, because we expect people to make + // different calls to advance the iterator based on *their own* state. + + simdjson_inline bool operator==(const token_iterator &other) const noexcept; + simdjson_inline bool operator!=(const token_iterator &other) const noexcept; + simdjson_inline bool operator>(const token_iterator &other) const noexcept; + simdjson_inline bool operator>=(const token_iterator &other) const noexcept; + simdjson_inline bool operator<(const token_iterator &other) const noexcept; + simdjson_inline bool operator<=(const token_iterator &other) const noexcept; + +protected: + simdjson_inline token_iterator(const uint8_t *buf, token_position position) noexcept; + + /** + * Get the index of the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_index(int32_t delta=0) const noexcept; + /** + * Get the index of the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token. + * + */ + simdjson_inline uint32_t peek_index(token_position position) const noexcept; + + const uint8_t *buf{}; + token_position _position{}; + + friend class json_iterator; + friend class value_iterator; + friend class object; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +}; + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::token_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H +/* end file simdjson/generic/ondemand/token_iterator.h for fallback */ +/* including simdjson/generic/ondemand/json_iterator.h for fallback: #include "simdjson/generic/ondemand/json_iterator.h" */ +/* begin file simdjson/generic/ondemand/json_iterator.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +/** + * Iterates through JSON tokens, keeping track of depth and string buffer. + * + * @private This is not intended for external use. + */ +class json_iterator { +protected: + token_iterator token{}; + ondemand::parser *parser{}; + /** + * Next free location in the string buffer. + * + * Used by raw_json_string::unescape() to have a place to unescape strings to. + */ + uint8_t *_string_buf_loc{}; + /** + * JSON error, if there is one. + * + * INCORRECT_TYPE and NO_SUCH_FIELD are *not* stored here, ever. + * + * PERF NOTE: we *hope* this will be elided into control flow, as it is only used (a) in the first + * iteration of the loop, or (b) for the final iteration after a missing comma is found in ++. If + * this is not elided, we should make sure it's at least not using up a register. Failing that, + * we should store it in document so there's only one of them. + */ + error_code error{SUCCESS}; + /** + * Depth of the current token in the JSON. + * + * - 0 = finished with document + * - 1 = document root value (could be [ or {, not yet known) + * - 2 = , or } inside root array/object + * - 3 = key or value inside root array/object. + */ + depth_t _depth{}; + /** + * Beginning of the document indexes. + * Normally we have root == parser->implementation->structural_indexes.get() + * but this may differ, especially in streaming mode (where we have several + * documents); + */ + token_position _root{}; + /** + * Normally, a json_iterator operates over a single document, but in + * some cases, we may have a stream of documents. This attribute is meant + * as meta-data: the json_iterator works the same irrespective of the + * value of this attribute. + */ + bool _streaming{false}; + +public: + simdjson_inline json_iterator() noexcept = default; + simdjson_inline json_iterator(json_iterator &&other) noexcept; + simdjson_inline json_iterator &operator=(json_iterator &&other) noexcept; + simdjson_inline explicit json_iterator(const json_iterator &other) noexcept = default; + simdjson_inline json_iterator &operator=(const json_iterator &other) noexcept = default; + /** + * Skips a JSON value, whether it is a scalar, array or object. + */ + simdjson_warn_unused simdjson_inline error_code skip_child(depth_t parent_depth) noexcept; + + /** + * Tell whether the iterator is still at the start + */ + simdjson_inline bool at_root() const noexcept; + + /** + * Tell whether we should be expected to run in streaming + * mode (iterating over many documents). It is pure metadata + * that does not affect how the iterator works. It is used by + * start_root_array() and start_root_object(). + */ + simdjson_inline bool streaming() const noexcept; + + /** + * Get the root value iterator + */ + simdjson_inline token_position root_position() const noexcept; + /** + * Assert that we are at the document depth (== 1) + */ + simdjson_inline void assert_at_document_depth() const noexcept; + /** + * Assert that we are at the root of the document + */ + simdjson_inline void assert_at_root() const noexcept; + + /** + * Tell whether the iterator is at the EOF mark + */ + simdjson_inline bool at_end() const noexcept; + + /** + * Tell whether the iterator is live (has not been moved). + */ + simdjson_inline bool is_alive() const noexcept; + + /** + * Abandon this iterator, setting depth to 0 (as if the document is finished). + */ + simdjson_inline void abandon() noexcept; + + /** + * Advance the current token without modifying depth. + */ + simdjson_inline const uint8_t *return_current_and_advance() noexcept; + + /** + * Returns true if there is a single token in the index (i.e., it is + * a JSON with a scalar value such as a single number). + * + * @return whether there is a single token + */ + simdjson_inline bool is_single_token() const noexcept; + + /** + * Assert that there are at least the given number of tokens left. + * + * Has no effect in release builds. + */ + simdjson_inline void assert_more_tokens(uint32_t required_tokens=1) const noexcept; + /** + * Assert that the given position addresses an actual token (is within bounds). + * + * Has no effect in release builds. + */ + simdjson_inline void assert_valid_position(token_position position) const noexcept; + /** + * Get the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = next token, -1 = prev token. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(int32_t delta=0) const noexcept; + /** + * Get the maximum length of the JSON text for the current token (or relative). + * + * The length will include any whitespace at the end of the token. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_length(int32_t delta=0) const noexcept; + /** + * Get a pointer to the current location in the input buffer. + * + * This is not null-terminated; it is a view into the JSON. + * + * You may be pointing outside of the input buffer: it is not generally + * safe to dereference this pointer. + */ + simdjson_inline const uint8_t *unsafe_pointer() const noexcept; + /** + * Get the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token to retrieve. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(token_position position) const noexcept; + /** + * Get the maximum length of the JSON text for the current token (or relative). + * + * The length will include any whitespace at the end of the token. + * + * @param position The position of the token to retrieve. + */ + simdjson_inline uint32_t peek_length(token_position position) const noexcept; + /** + * Get the JSON text for the last token in the document. + * + * This is not null-terminated; it is a view into the JSON. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek_last() const noexcept; + + /** + * Ascend one level. + * + * Validates that the depth - 1 == parent_depth. + * + * @param parent_depth the expected parent depth. + */ + simdjson_inline void ascend_to(depth_t parent_depth) noexcept; + + /** + * Descend one level. + * + * Validates that the new depth == child_depth. + * + * @param child_depth the expected child depth. + */ + simdjson_inline void descend_to(depth_t child_depth) noexcept; + simdjson_inline void descend_to(depth_t child_depth, int32_t delta) noexcept; + + /** + * Get current depth. + */ + simdjson_inline depth_t depth() const noexcept; + + /** + * Get current (writeable) location in the string buffer. + */ + simdjson_inline uint8_t *&string_buf_loc() noexcept; + + /** + * Report an unrecoverable error, preventing further iteration. + * + * @param error The error to report. Must not be SUCCESS, UNINITIALIZED, INCORRECT_TYPE, or NO_SUCH_FIELD. + * @param message An error message to report with the error. + */ + simdjson_inline error_code report_error(error_code error, const char *message) noexcept; + + /** + * Log error, but don't stop iteration. + * @param error The error to report. Must be INCORRECT_TYPE, or NO_SUCH_FIELD. + * @param message An error message to report with the error. + */ + simdjson_inline error_code optional_error(error_code error, const char *message) noexcept; + + /** + * Take an input in json containing max_len characters and attempt to copy it over to tmpbuf, a buffer with + * N bytes of capacity. It will return false if N is too small (smaller than max_len) of if it is zero. + * The buffer (tmpbuf) is padded with space characters. + */ + simdjson_warn_unused simdjson_inline bool copy_to_buffer(const uint8_t *json, uint32_t max_len, uint8_t *tmpbuf, size_t N) noexcept; + + simdjson_inline token_position position() const noexcept; + /** + * Write the raw_json_string to the string buffer and return a string_view. + * Each raw_json_string should be unescaped once, or else the string buffer might + * overflow. + */ + simdjson_inline simdjson_result unescape(raw_json_string in, bool allow_replacement) noexcept; + simdjson_inline simdjson_result unescape_wobbly(raw_json_string in) noexcept; + + simdjson_inline void reenter_child(token_position position, depth_t child_depth) noexcept; + + simdjson_inline error_code consume_character(char c) noexcept; +#if SIMDJSON_DEVELOPMENT_CHECKS + simdjson_inline token_position start_position(depth_t depth) const noexcept; + simdjson_inline void set_start_position(depth_t depth, token_position position) noexcept; +#endif + + /* Useful for debugging and logging purposes. */ + inline std::string to_string() const noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + inline simdjson_result current_location() const noexcept; + + /** + * Updates this json iterator so that it is back at the beginning of the document, + * as if it had just been created. + */ + inline void rewind() noexcept; + /** + * This checks whether the {,},[,] are balanced so that the document + * ends with proper zero depth. This requires scanning the whole document + * and it may be expensive. It is expected that it will be rarely called. + * It does not attempt to match { with } and [ with ]. + */ + inline bool balanced() const noexcept; +protected: + simdjson_inline json_iterator(const uint8_t *buf, ondemand::parser *parser) noexcept; + /// The last token before the end + simdjson_inline token_position last_position() const noexcept; + /// The token *at* the end. This points at gibberish and should only be used for comparison. + simdjson_inline token_position end_position() const noexcept; + /// The end of the buffer. + simdjson_inline token_position end() const noexcept; + + friend class document; + friend class document_stream; + friend class object; + friend class array; + friend class value; + friend class raw_json_string; + friend class parser; + friend class value_iterator; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +}; // json_iterator + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::json_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H +/* end file simdjson/generic/ondemand/json_iterator.h for fallback */ +/* including simdjson/generic/ondemand/json_type.h for fallback: #include "simdjson/generic/ondemand/json_type.h" */ +/* begin file simdjson/generic/ondemand/json_type.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/numberparsing.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +/** + * The type of a JSON value. + */ +enum class json_type { + // Start at 1 to catch uninitialized / default values more easily + array=1, ///< A JSON array ( [ 1, 2, 3 ... ] ) + object, ///< A JSON object ( { "a": 1, "b" 2, ... } ) + number, ///< A JSON number ( 1 or -2.3 or 4.5e6 ...) + string, ///< A JSON string ( "a" or "hello world\n" ...) + boolean, ///< A JSON boolean (true or false) + null ///< A JSON null (null) +}; + +/** + * A type representing a JSON number. + * The design of the struct is deliberately straight-forward. All + * functions return standard values with no error check. + */ +struct number { + + /** + * return the automatically determined type of + * the number: number_type::floating_point_number, + * number_type::signed_integer or number_type::unsigned_integer. + * + * enum class number_type { + * floating_point_number=1, /// a binary64 number + * signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + * unsigned_integer /// a positive integer larger or equal to 1<<63 + * }; + */ + simdjson_inline ondemand::number_type get_number_type() const noexcept; + /** + * return true if the automatically determined type of + * the number is number_type::unsigned_integer. + */ + simdjson_inline bool is_uint64() const noexcept; + /** + * return the value as a uint64_t, only valid if is_uint64() is true. + */ + simdjson_inline uint64_t get_uint64() const noexcept; + simdjson_inline operator uint64_t() const noexcept; + + /** + * return true if the automatically determined type of + * the number is number_type::signed_integer. + */ + simdjson_inline bool is_int64() const noexcept; + /** + * return the value as a int64_t, only valid if is_int64() is true. + */ + simdjson_inline int64_t get_int64() const noexcept; + simdjson_inline operator int64_t() const noexcept; + + + /** + * return true if the automatically determined type of + * the number is number_type::floating_point_number. + */ + simdjson_inline bool is_double() const noexcept; + /** + * return the value as a double, only valid if is_double() is true. + */ + simdjson_inline double get_double() const noexcept; + simdjson_inline operator double() const noexcept; + + /** + * Convert the number to a double. Though it always succeed, the conversion + * may be lossy if the number cannot be represented exactly. + */ + simdjson_inline double as_double() const noexcept; + + +protected: + /** + * The next block of declaration is designed so that we can call the number parsing + * functions on a number type. They are protected and should never be used outside + * of the core simdjson library. + */ + friend class value_iterator; + template + friend error_code numberparsing::write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer); + template + friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer); + /** Store a signed 64-bit value to the number. */ + simdjson_inline void append_s64(int64_t value) noexcept; + /** Store an unsigned 64-bit value to the number. */ + simdjson_inline void append_u64(uint64_t value) noexcept; + /** Store a double value to the number. */ + simdjson_inline void append_double(double value) noexcept; + /** Specifies that the value is a double, but leave it undefined. */ + simdjson_inline void skip_double() noexcept; + /** + * End of friend declarations. + */ + + /** + * Our attributes are a union type (size = 64 bits) + * followed by a type indicator. + */ + union { + double floating_point_number; + int64_t signed_integer; + uint64_t unsigned_integer; + } payload{0}; + number_type type{number_type::signed_integer}; +}; + +/** + * Write the JSON type to the output stream + * + * @param out The output stream. + * @param type The json_type. + */ +inline std::ostream& operator<<(std::ostream& out, json_type type) noexcept; + +#if SIMDJSON_EXCEPTIONS +/** + * Send JSON type to an output stream. + * + * @param out The output stream. + * @param type The json_type. + * @throw simdjson_error if the result being printed has an error. If there is an error with the + * underlying output stream, that error will be propagated (simdjson_error will not be + * thrown). + */ +inline std::ostream& operator<<(std::ostream& out, simdjson_result &type) noexcept(false); +#endif + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::json_type &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H +/* end file simdjson/generic/ondemand/json_type.h for fallback */ +/* including simdjson/generic/ondemand/raw_json_string.h for fallback: #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* begin file simdjson/generic/ondemand/raw_json_string.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +/** + * A string escaped per JSON rules, terminated with quote ("). They are used to represent + * unescaped keys inside JSON documents. + * + * (In other words, a pointer to the beginning of a string, just after the start quote, inside a + * JSON file.) + * + * This class is deliberately simplistic and has little functionality. You can + * compare a raw_json_string instance with an unescaped C string, but + * that is nearly all you can do. + * + * The raw_json_string is unescaped. If you wish to write an unescaped version of it to your own + * buffer, you may do so using the parser.unescape(string, buff) method, using an ondemand::parser + * instance. Doing so requires you to have a sufficiently large buffer. + * + * The raw_json_string instances originate typically from field instance which in turn represent + * key-value pairs from object instances. From a field instance, you get the raw_json_string + * instance by calling key(). You can, if you want a more usable string_view instance, call + * the unescaped_key() method on the field instance. You may also create a raw_json_string from + * any other string value, with the value.get_raw_json_string() method. Again, you can get + * a more usable string_view instance by calling get_string(). + * + */ +class raw_json_string { +public: + /** + * Create a new invalid raw_json_string. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline raw_json_string() noexcept = default; + + /** + * Create a new invalid raw_json_string pointed at the given location in the JSON. + * + * The given location must be just *after* the beginning quote (") in the JSON file. + * + * It *must* be terminated by a ", and be a valid JSON string. + */ + simdjson_inline raw_json_string(const uint8_t * _buf) noexcept; + /** + * Get the raw pointer to the beginning of the string in the JSON (just after the "). + * + * It is possible for this function to return a null pointer if the instance + * has outlived its existence. + */ + simdjson_inline const char * raw() const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done) on target.size() characters, + * and if the raw_json_string instance has a quote character at byte index target.size(). + * We never read more than length + 1 bytes in the raw_json_string instance. + * If length is smaller than target.size(), this will return false. + * + * The std::string_view instance may contain any characters. However, the caller + * is responsible for setting length so that length bytes may be read in the + * raw_json_string. + * + * Performance: the comparison may be done using memcmp which may be efficient + * for long strings. + */ + simdjson_inline bool unsafe_is_equal(size_t length, std::string_view target) const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done). + * The std::string_view instance should not contain unescaped quote characters: + * the caller is responsible for this check. See is_free_from_unescaped_quote. + * + * Performance: the comparison is done byte-by-byte which might be inefficient for + * long strings. + * + * If target is a compile-time constant, and your compiler likes you, + * you should be able to do the following without performance penalty... + * + * static_assert(raw_json_string::is_free_from_unescaped_quote(target), ""); + * s.unsafe_is_equal(target); + */ + simdjson_inline bool unsafe_is_equal(std::string_view target) const noexcept; + + /** + * This compares the current instance to the C string target: returns true if + * they are byte-by-byte equal (no escaping is done). + * The provided C string should not contain an unescaped quote character: + * the caller is responsible for this check. See is_free_from_unescaped_quote. + * + * If target is a compile-time constant, and your compiler likes you, + * you should be able to do the following without performance penalty... + * + * static_assert(raw_json_string::is_free_from_unescaped_quote(target), ""); + * s.unsafe_is_equal(target); + */ + simdjson_inline bool unsafe_is_equal(const char* target) const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done). + */ + simdjson_inline bool is_equal(std::string_view target) const noexcept; + + /** + * This compares the current instance to the C string target: returns true if + * they are byte-by-byte equal (no escaping is done). + */ + simdjson_inline bool is_equal(const char* target) const noexcept; + + /** + * Returns true if target is free from unescaped quote. If target is known at + * compile-time, we might expect the computation to happen at compile time with + * many compilers (not all!). + */ + static simdjson_inline bool is_free_from_unescaped_quote(std::string_view target) noexcept; + static simdjson_inline bool is_free_from_unescaped_quote(const char* target) noexcept; + +private: + + + /** + * This will set the inner pointer to zero, effectively making + * this instance unusable. + */ + simdjson_inline void consume() noexcept { buf = nullptr; } + + /** + * Checks whether the inner pointer is non-null and thus usable. + */ + simdjson_inline simdjson_warn_unused bool alive() const noexcept { return buf != nullptr; } + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. + * The result will be a valid UTF-8. + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid until the next parse() call on the parser. + * + * @param iter A json_iterator, which contains a buffer where the string will be written. + * @param allow_replacement Whether we allow replacement of invalid surrogate pairs. + */ + simdjson_inline simdjson_warn_unused simdjson_result unescape(json_iterator &iter, bool allow_replacement) const noexcept; + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. + * The result may not be a valid UTF-8. https://simonsapin.github.io/wtf-8/ + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid until the next parse() call on the parser. + * + * @param iter A json_iterator, which contains a buffer where the string will be written. + */ + simdjson_inline simdjson_warn_unused simdjson_result unescape_wobbly(json_iterator &iter) const noexcept; + const uint8_t * buf{}; + friend class object; + friend class field; + friend class parser; + friend struct simdjson_result; +}; + +simdjson_unused simdjson_inline std::ostream &operator<<(std::ostream &, const raw_json_string &) noexcept; + +/** + * Comparisons between raw_json_string and std::string_view instances are potentially unsafe: the user is responsible + * for providing a string with no unescaped quote. Note that unescaped quotes cannot be present in valid JSON strings. + */ +simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept; +simdjson_unused simdjson_inline bool operator==(std::string_view c, const raw_json_string &a) noexcept; +simdjson_unused simdjson_inline bool operator!=(const raw_json_string &a, std::string_view c) noexcept; +simdjson_unused simdjson_inline bool operator!=(std::string_view c, const raw_json_string &a) noexcept; + + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::raw_json_string &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private + + simdjson_inline simdjson_result raw() const noexcept; + simdjson_inline simdjson_warn_unused simdjson_result unescape(fallback::ondemand::json_iterator &iter, bool allow_replacement) const noexcept; + simdjson_inline simdjson_warn_unused simdjson_result unescape_wobbly(fallback::ondemand::json_iterator &iter) const noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H +/* end file simdjson/generic/ondemand/raw_json_string.h for fallback */ +/* including simdjson/generic/ondemand/parser.h for fallback: #include "simdjson/generic/ondemand/parser.h" */ +/* begin file simdjson/generic/ondemand/parser.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_PARSER_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace fallback { +namespace ondemand { + +/** + * The default batch size for document_stream instances for this On Demand kernel. + * Note that different On Demand kernel may use a different DEFAULT_BATCH_SIZE value + * in the future. + */ +static constexpr size_t DEFAULT_BATCH_SIZE = 1000000; +/** + * Some adversary might try to set the batch size to 0 or 1, which might cause problems. + * We set a minimum of 32B since anything else is highly likely to be an error. In practice, + * most users will want a much larger batch size. + * + * All non-negative MINIMAL_BATCH_SIZE values should be 'safe' except that, obviously, no JSON + * document can ever span 0 or 1 byte and that very large values would create memory allocation issues. + */ +static constexpr size_t MINIMAL_BATCH_SIZE = 32; + +/** + * A JSON fragment iterator. + * + * This holds the actual iterator as well as the buffer for writing strings. + */ +class parser { +public: + /** + * Create a JSON parser. + * + * The new parser will have zero capacity. + */ + inline explicit parser(size_t max_capacity = SIMDJSON_MAXSIZE_BYTES) noexcept; + + inline parser(parser &&other) noexcept = default; + simdjson_inline parser(const parser &other) = delete; + simdjson_inline parser &operator=(const parser &other) = delete; + simdjson_inline parser &operator=(parser &&other) noexcept = default; + + /** Deallocate the JSON parser. */ + inline ~parser() noexcept = default; + + /** + * Start iterating an on-demand JSON document. + * + * ondemand::parser parser; + * document doc = parser.iterate(json); + * + * It is expected that the content is a valid UTF-8 file, containing a valid JSON document. + * Otherwise the iterate method may return an error. In particular, the whole input should be + * valid: we do not attempt to tolerate incorrect content either before or after a JSON + * document. If there is a UTF-8 BOM, the parser skips it. + * + * ### IMPORTANT: Validate what you use + * + * Calling iterate on an invalid JSON document may not immediately trigger an error. The call to + * iterate does not parse and validate the whole document. + * + * ### IMPORTANT: Buffer Lifetime + * + * Because parsing is done while you iterate, you *must* keep the JSON buffer around at least as + * long as the document iteration. + * + * ### IMPORTANT: Document Lifetime + * + * Only one iteration at a time can happen per parser, and the parser *must* be kept alive during + * iteration to ensure intermediate buffers can be accessed. Any document must be destroyed before + * you call parse() again or destroy the parser. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * @param json The JSON to parse. + * @param len The length of the JSON. + * @param capacity The number of bytes allocated in the JSON (must be at least len+SIMDJSON_PADDING). + * + * @return The document, or an error: + * - INSUFFICIENT_PADDING if the input has less than SIMDJSON_PADDING extra bytes. + * - MEMALLOC if realloc_if_needed the parser does not have enough capacity, and memory + * allocation fails. + * - EMPTY if the document is all whitespace. + * - UTF8_ERROR if the document is not valid UTF-8. + * - UNESCAPED_CHARS if a string contains control characters that must be escaped + * - UNCLOSED_STRING if there is an unclosed string in the document. + */ + simdjson_warn_unused simdjson_result iterate(padded_string_view json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const char *json, size_t len, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const uint8_t *json, size_t len, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(std::string_view json, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const std::string &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(std::string &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const simdjson_result &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const simdjson_result &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(padded_string &&json) & noexcept = delete; + + /** + * @private + * + * Start iterating an on-demand JSON document. + * + * ondemand::parser parser; + * json_iterator doc = parser.iterate(json); + * + * ### IMPORTANT: Buffer Lifetime + * + * Because parsing is done while you iterate, you *must* keep the JSON buffer around at least as + * long as the document iteration. + * + * ### IMPORTANT: Document Lifetime + * + * Only one iteration at a time can happen per parser, and the parser *must* be kept alive during + * iteration to ensure intermediate buffers can be accessed. Any document must be destroyed before + * you call parse() again or destroy the parser. + * + * The ondemand::document instance holds the iterator. The document must remain in scope + * while you are accessing instances of ondemand::value, ondemand::object, ondemand::array. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * @param json The JSON to parse. + * + * @return The iterator, or an error: + * - INSUFFICIENT_PADDING if the input has less than SIMDJSON_PADDING extra bytes. + * - MEMALLOC if realloc_if_needed the parser does not have enough capacity, and memory + * allocation fails. + * - EMPTY if the document is all whitespace. + * - UTF8_ERROR if the document is not valid UTF-8. + * - UNESCAPED_CHARS if a string contains control characters that must be escaped + * - UNCLOSED_STRING if there is an unclosed string in the document. + */ + simdjson_warn_unused simdjson_result iterate_raw(padded_string_view json) & noexcept; + + + /** + * Parse a buffer containing many JSON documents. + * + * auto json = R"({ "foo": 1 } { "foo": 2 } { "foo": 3 } )"_padded; + * ondemand::parser parser; + * ondemand::document_stream docs = parser.iterate_many(json); + * for (auto & doc : docs) { + * std::cout << doc["foo"] << std::endl; + * } + * // Prints 1 2 3 + * + * No copy of the input buffer is made. + * + * The function is lazy: it may be that no more than one JSON document at a time is parsed. + * + * The caller is responsabile to ensure that the input string data remains unchanged and is + * not deleted during the loop. + * + * ### Format + * + * The buffer must contain a series of one or more JSON documents, concatenated into a single + * buffer, separated by ASCII whitespace. It effectively parses until it has a fully valid document, + * then starts parsing the next document at that point. (It does this with more parallelism and + * lookahead than you might think, though.) + * + * documents that consist of an object or array may omit the whitespace between them, concatenating + * with no separator. Documents that consist of a single primitive (i.e. documents that are not + * arrays or objects) MUST be separated with ASCII whitespace. + * + * The characters inside a JSON document, and between JSON documents, must be valid Unicode (UTF-8). + * If there is a UTF-8 BOM, the parser skips it. + * + * The documents must not exceed batch_size bytes (by default 1MB) or they will fail to parse. + * Setting batch_size to excessively large or excessively small values may impact negatively the + * performance. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * ### Threads + * + * When compiled with SIMDJSON_THREADS_ENABLED, this method will use a single thread under the + * hood to do some lookahead. + * + * ### Parser Capacity + * + * If the parser's current capacity is less than batch_size, it will allocate enough capacity + * to handle it (up to max_capacity). + * + * @param buf The concatenated JSON to parse. + * @param len The length of the concatenated JSON. + * @param batch_size The batch size to use. MUST be larger than the largest document. The sweet + * spot is cache-related: small enough to fit in cache, yet big enough to + * parse as many documents as possible in one tight loop. + * Defaults to 10MB, which has been a reasonable sweet spot in our tests. + * @param allow_comma_separated (defaults on false) This allows a mode where the documents are + * separated by commas instead of whitespace. It comes with a performance + * penalty because the entire document is indexed at once (and the document must be + * less than 4 GB), and there is no multithreading. In this mode, the batch_size parameter + * is effectively ignored, as it is set to at least the document size. + * @return The stream, or an error. An empty input will yield 0 documents rather than an EMPTY error. Errors: + * - MEMALLOC if the parser does not have enough capacity and memory allocation fails + * - CAPACITY if the parser does not have enough capacity and batch_size > max_capacity. + * - other json errors if parsing fails. You should not rely on these errors to always the same for the + * same document: they may vary under runtime dispatch (so they may vary depending on your system and hardware). + */ + inline simdjson_result iterate_many(const uint8_t *buf, size_t len, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const char *buf, size_t len, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const std::string &s, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + inline simdjson_result iterate_many(const std::string &&s, size_t batch_size, bool allow_comma_separated = false) = delete;// unsafe + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const padded_string &s, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + inline simdjson_result iterate_many(const padded_string &&s, size_t batch_size, bool allow_comma_separated = false) = delete;// unsafe + + /** @private We do not want to allow implicit conversion from C string to std::string. */ + simdjson_result iterate_many(const char *buf, size_t batch_size = DEFAULT_BATCH_SIZE) noexcept = delete; + + /** The capacity of this parser (the largest document it can process). */ + simdjson_inline size_t capacity() const noexcept; + /** The maximum capacity of this parser (the largest document it is allowed to process). */ + simdjson_inline size_t max_capacity() const noexcept; + simdjson_inline void set_max_capacity(size_t max_capacity) noexcept; + /** + * The maximum depth of this parser (the most deeply nested objects and arrays it can process). + * This parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true. + * The document's instance current_depth() method should be used to monitor the parsing + * depth and limit it if desired. + */ + simdjson_inline size_t max_depth() const noexcept; + + /** + * Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length + * and `max_depth` depth. + * + * The max_depth parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true. + * The document's instance current_depth() method should be used to monitor the parsing + * depth and limit it if desired. + * + * @param capacity The new capacity. + * @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH. + * @return The error, if there is one. + */ + simdjson_warn_unused error_code allocate(size_t capacity, size_t max_depth=DEFAULT_MAX_DEPTH) noexcept; + + #ifdef SIMDJSON_THREADS_ENABLED + /** + * The parser instance can use threads when they are available to speed up some + * operations. It is enabled by default. Changing this attribute will change the + * behavior of the parser for future operations. + */ + bool threaded{true}; + #endif + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. to a user-provided buffer. + * The result must be valid UTF-8. + * The provided pointer is advanced to the end of the string by reference, and a string_view instance + * is returned. You can ensure that your buffer is large enough by allocating a block of memory at least + * as large as the input JSON plus SIMDJSON_PADDING and then unescape all strings to this one buffer. + * + * This unescape function is a low-level function. If you want a more user-friendly approach, you should + * avoid raw_json_string instances (e.g., by calling unescaped_key() instead of key() or get_string() + * instead of get_raw_json_string()). + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid as long as the bytes in dst. + * + * @param raw_json_string input + * @param dst A pointer to a buffer at least large enough to write this string as well as + * an additional SIMDJSON_PADDING bytes. + * @param allow_replacement Whether we allow a replacement if the input string contains unmatched surrogate pairs. + * @return A string_view pointing at the unescaped string in dst + * @error STRING_ERROR if escapes are incorrect. + */ + simdjson_inline simdjson_result unescape(raw_json_string in, uint8_t *&dst, bool allow_replacement = false) const noexcept; + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. to a user-provided buffer. + * The result may not be valid UTF-8. See https://simonsapin.github.io/wtf-8/ + * The provided pointer is advanced to the end of the string by reference, and a string_view instance + * is returned. You can ensure that your buffer is large enough by allocating a block of memory at least + * as large as the input JSON plus SIMDJSON_PADDING and then unescape all strings to this one buffer. + * + * This unescape function is a low-level function. If you want a more user-friendly approach, you should + * avoid raw_json_string instances (e.g., by calling unescaped_key() instead of key() or get_string() + * instead of get_raw_json_string()). + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid as long as the bytes in dst. + * + * @param raw_json_string input + * @param dst A pointer to a buffer at least large enough to write this string as well as + * an additional SIMDJSON_PADDING bytes. + * @return A string_view pointing at the unescaped string in dst + * @error STRING_ERROR if escapes are incorrect. + */ + simdjson_inline simdjson_result unescape_wobbly(raw_json_string in, uint8_t *&dst) const noexcept; + +private: + /** @private [for benchmarking access] The implementation to use */ + std::unique_ptr implementation{}; + size_t _capacity{0}; + size_t _max_capacity; + size_t _max_depth{DEFAULT_MAX_DEPTH}; + std::unique_ptr string_buf{}; +#if SIMDJSON_DEVELOPMENT_CHECKS + std::unique_ptr start_positions{}; +#endif + + friend class json_iterator; + friend class document_stream; +}; + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::parser &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_PARSER_H +/* end file simdjson/generic/ondemand/parser.h for fallback */ + +// All other declarations +/* including simdjson/generic/ondemand/array.h for fallback: #include "simdjson/generic/ondemand/array.h" */ +/* begin file simdjson/generic/ondemand/array.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +/** + * A forward-only JSON array. + */ +class array { +public: + /** + * Create a new invalid array. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline array() noexcept = default; + + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result begin() noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() noexcept; + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an array is empty, it is more performant to use + * the is_empty() method. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the beginning of the array and checks whether the + * array is empty. + * The runtime complexity is constant time. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + simdjson_inline simdjson_result is_empty() & noexcept; + /** + * Reset the iterator so that we are pointing back at the + * beginning of the array. You should still consume values only once even if you + * can iterate through the array more than once. If you unescape a string + * within the array more than once, you have unsafe code. Note that rewinding + * an array means that you may need to reparse it anew: it is not a free + * operation. + * + * @returns true if the array contains some elements (not empty) + */ + inline simdjson_result reset() & noexcept; + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard, interpreting the current node + * as the root of its own JSON document. + * + * ondemand::parser parser; + * auto json = R"([ { "foo": { "a": [ 10, 20, 30 ] }} ])"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/0/foo/a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. Yet it is not the case when calling at_pointer on an array + * instance: there is no rewind and no invalidation. + * + * You may only call at_pointer on an array after it has been created, but before it has + * been first accessed. When calling at_pointer on an array, the pointer is advanced to + * the location indicated by the JSON pointer (in case of success). It is no longer possible + * to call at_pointer on the same array. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching. + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + /** + * Consumes the array and returns a string_view instance corresponding to the + * array as represented in JSON. It points inside the original document. + */ + simdjson_inline simdjson_result raw_json() noexcept; + + /** + * Get the value at the given index. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) noexcept; +protected: + /** + * Go to the end of the array, no matter where you are right now. + */ + simdjson_inline error_code consume() noexcept; + + /** + * Begin array iteration. + * + * @param iter The iterator. Must be where the initial [ is expected. Will be *moved* into the + * resulting array. + * @error INCORRECT_TYPE if the iterator is not at [. + */ + static simdjson_inline simdjson_result start(value_iterator &iter) noexcept; + /** + * Begin array iteration from the root. + * + * @param iter The iterator. Must be where the initial [ is expected. Will be *moved* into the + * resulting array. + * @error INCORRECT_TYPE if the iterator is not at [. + * @error TAPE_ERROR if there is no closing ] at the end of the document. + */ + static simdjson_inline simdjson_result start_root(value_iterator &iter) noexcept; + /** + * Begin array iteration. + * + * This version of the method should be called after the initial [ has been verified, and is + * intended for use by switch statements that check the type of a value. + * + * @param iter The iterator. Must be after the initial [. Will be *moved* into the resulting array. + */ + static simdjson_inline simdjson_result started(value_iterator &iter) noexcept; + + /** + * Create an array at the given Internal array creation. Call array::start() or array::started() instead of this. + * + * @param iter The iterator. Must either be at the start of the first element with iter.is_alive() + * == true, or past the [] with is_alive() == false if the array is empty. Will be *moved* + * into the resulting array. + */ + simdjson_inline array(const value_iterator &iter) noexcept; + + /** + * Iterator marking current position. + * + * iter.is_alive() == false indicates iteration is complete. + */ + value_iterator iter{}; + + friend class value; + friend class document; + friend struct simdjson_result; + friend struct simdjson_result; + friend class array_iterator; +}; + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::array &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + inline simdjson_result count_elements() & noexcept; + inline simdjson_result is_empty() & noexcept; + inline simdjson_result reset() & noexcept; + simdjson_inline simdjson_result at(size_t index) noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_H +/* end file simdjson/generic/ondemand/array.h for fallback */ +/* including simdjson/generic/ondemand/array_iterator.h for fallback: #include "simdjson/generic/ondemand/array_iterator.h" */ +/* begin file simdjson/generic/ondemand/array_iterator.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + + +namespace simdjson { +namespace fallback { +namespace ondemand { + +/** + * A forward-only JSON array. + * + * This is an input_iterator, meaning: + * - It is forward-only + * - * must be called exactly once per element. + * - ++ must be called exactly once in between each * (*, ++, *, ++, * ...) + */ +class array_iterator { +public: + /** Create a new, invalid array iterator. */ + simdjson_inline array_iterator() noexcept = default; + + // + // Iterator interface + // + + /** + * Get the current element. + * + * Part of the std::iterator interface. + */ + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + /** + * Check if we are at the end of the JSON. + * + * Part of the std::iterator interface. + * + * @return true if there are no more elements in the JSON array. + */ + simdjson_inline bool operator==(const array_iterator &) const noexcept; + /** + * Check if there are more elements in the JSON array. + * + * Part of the std::iterator interface. + * + * @return true if there are more elements in the JSON array. + */ + simdjson_inline bool operator!=(const array_iterator &) const noexcept; + /** + * Move to the next element. + * + * Part of the std::iterator interface. + */ + simdjson_inline array_iterator &operator++() noexcept; + +private: + value_iterator iter{}; + + simdjson_inline array_iterator(const value_iterator &iter) noexcept; + + friend class array; + friend class value; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::array_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + // + // Iterator interface + // + + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + simdjson_inline bool operator==(const simdjson_result &) const noexcept; + simdjson_inline bool operator!=(const simdjson_result &) const noexcept; + simdjson_inline simdjson_result &operator++() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H +/* end file simdjson/generic/ondemand/array_iterator.h for fallback */ +/* including simdjson/generic/ondemand/document.h for fallback: #include "simdjson/generic/ondemand/document.h" */ +/* begin file simdjson/generic/ondemand/document.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +/** + * A JSON document. It holds a json_iterator instance. + * + * Used by tokens to get text, and string buffer location. + * + * You must keep the document around during iteration. + */ +class document { +public: + /** + * Create a new invalid document. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline document() noexcept = default; + simdjson_inline document(const document &other) noexcept = delete; // pass your documents by reference, not by copy + simdjson_inline document(document &&other) noexcept = default; + simdjson_inline document &operator=(const document &other) noexcept = delete; + simdjson_inline document &operator=(document &&other) noexcept = default; + + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result get_array() & noexcept; + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @returns INCORRECT_TYPE If the JSON value is not an object. + */ + simdjson_inline simdjson_result get_object() & noexcept; + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64() noexcept; + /** + * Cast this JSON value (inside string) to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64() noexcept; + /** + * Cast this JSON value (inside string) to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64_in_string() noexcept; + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double() noexcept; + + /** + * Cast this JSON value (inside string) to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double_in_string() noexcept; + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: Calling get_string() twice on the same document is an error. + * + * @param Whether to allow a replacement character for unmatched surrogate pairs. + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + /** + * Attempts to fill the provided std::string reference with the parsed value of the current string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory. + * We recommend you avoid allocating an std::string unless you need to. + * + * @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS. + */ + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + /** + * Cast this JSON value to a string. + * + * The string is not guaranteed to be valid UTF-8. See https://simonsapin.github.io/wtf-8/ + * + * Important: Calling get_wobbly_string() twice on the same document is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_wobbly_string() noexcept; + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_raw_json_string() noexcept; + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @returns INCORRECT_TYPE if the JSON value is not true or false. + */ + simdjson_inline simdjson_result get_bool() noexcept; + /** + * Cast this JSON value to a value when the document is an object or an array. + * + * You must not have begun iterating through the object or array. When + * SIMDJSON_DEVELOPMENT_CHECKS is set to 1 (which is the case when building in Debug mode + * by default), and you have already begun iterating, + * you will get an OUT_OF_ORDER_ITERATION error. If you have begun iterating, you can use + * rewind() to reset the document to its initial state before calling this method. + * + * @returns A value if a JSON array or object cannot be found. + * @returns SCALAR_DOCUMENT_AS_VALUE error is the document is a scalar (see is_scalar() function). + */ + simdjson_inline simdjson_result get_value() noexcept; + + /** + * Checks if this JSON value is null. If and only if the value is + * null, then it is consumed (we advance). If we find a token that + * begins with 'n' but is not 'null', then an error is returned. + * + * @returns Whether the value is null. + * @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'. + */ + simdjson_inline simdjson_result is_null() noexcept; + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * You may use get_double(), get_bool(), get_uint64(), get_int64(), + * get_object(), get_array(), get_raw_json_string(), or get_string() instead. + * + * @returns A value of the given type, parsed from the JSON. + * @returns INCORRECT_TYPE If the JSON value is not the given type. + */ + template simdjson_inline simdjson_result get() & noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + /** @overload template simdjson_result get() & noexcept */ + template simdjson_inline simdjson_result get() && noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool, value + * + * Be mindful that the document instance must remain in scope while you are accessing object, array and value instances. + * + * @param out This is set to a value of the given type, parsed from the JSON. If there is an error, this may not be initialized. + * @returns INCORRECT_TYPE If the JSON value is not an object. + * @returns SUCCESS If the parse succeeded and the out parameter was set to the value. + */ + template simdjson_inline error_code get(T &out) & noexcept; + /** @overload template error_code get(T &out) & noexcept */ + template simdjson_inline error_code get(T &out) && noexcept; + +#if SIMDJSON_EXCEPTIONS + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an array. + */ + simdjson_inline operator array() & noexcept(false); + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an object. + */ + simdjson_inline operator object() & noexcept(false); + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline operator uint64_t() noexcept(false); + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer. + */ + simdjson_inline operator int64_t() noexcept(false); + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number. + */ + simdjson_inline operator double() noexcept(false); + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator std::string_view() noexcept(false); + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator raw_json_string() noexcept(false); + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false. + */ + simdjson_inline operator bool() noexcept(false); + /** + * Cast this JSON value to a value when the document is an object or an array. + * + * You must not have begun iterating through the object or array. When + * SIMDJSON_DEVELOPMENT_CHECKS is defined, and you have already begun iterating, + * you will get an OUT_OF_ORDER_ITERATION error. If you have begun iterating, you can use + * rewind() to reset the document to its initial state before calling this method. + * + * @returns A value value if a JSON array or object cannot be found. + * @exception SCALAR_DOCUMENT_AS_VALUE error is the document is a scalar (see is_scalar() function). + */ + simdjson_inline operator value() noexcept(false); +#endif + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Get the value at the given index in the array. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) & noexcept; + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result begin() & noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() & noexcept; + + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. E.g., the array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to + * a key a single time. Doing object["mykey"].to_string()and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. E.g., the array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a key + * a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + + /** + * Get the type of this JSON value. It does not validate or consume the value. + * E.g., you must still call "is_null()" to check that a value is null even if + * "type()" returns json_type::null. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + * + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() noexcept; + + /** + * Checks whether the document is a scalar (string, number, null, Boolean). + * Returns false when there it is an array or object. + * + * @returns true if the type is string, number, null, Boolean + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result is_scalar() noexcept; + + /** + * Checks whether the document is a negative number. + * + * @returns true if the number if negative. + */ + simdjson_inline bool is_negative() noexcept; + /** + * Checks whether the document is an integer number. Note that + * this requires to partially parse the number string. If + * the value is determined to be an integer, it may still + * not parse properly as an integer in subsequent steps + * (e.g., it might overflow). + * + * @returns true if the number if negative. + */ + simdjson_inline simdjson_result is_integer() noexcept; + /** + * Determine the number type (integer or floating-point number) as quickly + * as possible. This function does not fully validate the input. It is + * useful when you only need to classify the numbers, without parsing them. + * + * If you are planning to retrieve the value or you need full validation, + * consider using the get_number() method instead: it will fully parse + * and validate the input, and give you access to the type: + * get_number().get_number_type(). + * + * get_number_type() is number_type::unsigned_integer if we have + * an integer greater or equal to 9223372036854775808 + * get_number_type() is number_type::signed_integer if we have an + * integer that is less than 9223372036854775808 + * Otherwise, get_number_type() has value number_type::floating_point_number + * + * This function requires processing the number string, but it is expected + * to be faster than get_number().get_number_type() because it is does not + * parse the number value. + * + * @returns the type of the number + */ + simdjson_inline simdjson_result get_number_type() noexcept; + + /** + * Attempt to parse an ondemand::number. An ondemand::number may + * contain an integer value or a floating-point value, the simdjson + * library will autodetect the type. Thus it is a dynamically typed + * number. Before accessing the value, you must determine the detected + * type. + * + * number.get_number_type() is number_type::signed_integer if we have + * an integer in [-9223372036854775808,9223372036854775808) + * You can recover the value by calling number.get_int64() and you + * have that number.is_int64() is true. + * + * number.get_number_type() is number_type::unsigned_integer if we have + * an integer in [9223372036854775808,18446744073709551616) + * You can recover the value by calling number.get_uint64() and you + * have that number.is_uint64() is true. + * + * Otherwise, number.get_number_type() has value number_type::floating_point_number + * and we have a binary64 number. + * You can recover the value by calling number.get_double() and you + * have that number.is_double() is true. + * + * You must check the type before accessing the value: it is an error + * to call "get_int64()" when number.get_number_type() is not + * number_type::signed_integer and when number.is_int64() is false. + */ + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + /** + * Get the raw JSON for this token. + * + * The string_view will always point into the input buffer. + * + * The string_view will start at the beginning of the token, and include the entire token + * *as well as all spaces until the next token (or EOF).* This means, for example, that a + * string token always begins with a " and is always terminated by the final ", possibly + * followed by a number of spaces. + * + * The string_view is *not* null-terminated. If this is a scalar (string, number, + * boolean, or null), the character after the end of the string_view may be the padded buffer. + * + * Tokens include: + * - { + * - [ + * - "a string (possibly with UTF-8 or backslashed characters like \\\")". + * - -1.2e-100 + * - true + * - false + * - null + */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + /** + * Reset the iterator inside the document instance so we are pointing back at the + * beginning of the document, as if it had just been created. It invalidates all + * values, objects and arrays that you have created so far (including unescaped strings). + */ + inline void rewind() noexcept; + /** + * Returns debugging information. + */ + inline std::string to_debug_string() noexcept; + /** + * Some unrecoverable error conditions may render the document instance unusable. + * The is_alive() method returns true when the document is still suitable. + */ + inline bool is_alive() noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + inline simdjson_result current_location() const noexcept; + + /** + * Returns true if this document has been fully parsed. + * If you have consumed the whole document and at_end() returns + * false, then there may be trailing content. + */ + inline bool at_end() const noexcept; + + /** + * Returns the current depth in the document if in bounds. + * + * E.g., + * 0 = finished with document + * 1 = document root value (could be [ or {, not yet known) + * 2 = , or } inside root array/object + * 3 = key or value inside root array/object. + */ + simdjson_inline int32_t current_depth() const noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() automatically calls rewind between each call. Thus + * all values, objects and arrays that you have created so far (including unescaped strings) + * are invalidated. After calling at_pointer, you need to consume the result: string values + * should be stored in your own variables, arrays should be decoded and stored in your own array-like + * structures and so forth. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + * - SCALAR_DOCUMENT_AS_VALUE if the json_pointer is empty and the document is not a scalar (see is_scalar() function). + */ + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + /** + * Consumes the document and returns a string_view instance corresponding to the + * document as represented in JSON. It points inside the original byte array containing + * the JSON document. + */ + simdjson_inline simdjson_result raw_json() noexcept; +protected: + /** + * Consumes the document. + */ + simdjson_inline error_code consume() noexcept; + + simdjson_inline document(ondemand::json_iterator &&iter) noexcept; + simdjson_inline const uint8_t *text(uint32_t idx) const noexcept; + + simdjson_inline value_iterator resume_value_iterator() noexcept; + simdjson_inline value_iterator get_root_value_iterator() noexcept; + simdjson_inline simdjson_result start_or_resume_object() noexcept; + static simdjson_inline document start(ondemand::json_iterator &&iter) noexcept; + + // + // Fields + // + json_iterator iter{}; ///< Current position in the document + static constexpr depth_t DOCUMENT_DEPTH = 0; ///< document depth is always 0 + + friend class array_iterator; + friend class value; + friend class ondemand::parser; + friend class object; + friend class array; + friend class field; + friend class token; + friend class document_stream; + friend class document_reference; +}; + + +/** + * A document_reference is a thin wrapper around a document reference instance. + */ +class document_reference { +public: + simdjson_inline document_reference() noexcept; + simdjson_inline document_reference(document &d) noexcept; + simdjson_inline document_reference(const document_reference &other) noexcept = default; + simdjson_inline document_reference& operator=(const document_reference &other) noexcept = default; + simdjson_inline void rewind() noexcept; + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + + simdjson_inline simdjson_result is_null() noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + simdjson_inline operator document&() const noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator array() & noexcept(false); + simdjson_inline operator object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline int32_t current_depth() const noexcept; + simdjson_inline bool is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + simdjson_inline simdjson_result raw_json_token() noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +private: + document *doc{nullptr}; +}; +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::document &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline error_code rewind() noexcept; + + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + + template simdjson_inline simdjson_result get() & noexcept; + template simdjson_inline simdjson_result get() && noexcept; + + template simdjson_inline error_code get(T &out) & noexcept; + template simdjson_inline error_code get(T &out) && noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator fallback::ondemand::array() & noexcept(false); + simdjson_inline operator fallback::ondemand::object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator fallback::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator fallback::ondemand::value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline int32_t current_depth() const noexcept; + simdjson_inline bool at_end() const noexcept; + simdjson_inline bool is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + /** @copydoc simdjson_inline std::string_view document::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + + +} // namespace simdjson + + + +namespace simdjson { + +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::document_reference value, error_code error) noexcept; + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline error_code rewind() noexcept; + + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator fallback::ondemand::array() & noexcept(false); + simdjson_inline operator fallback::ondemand::object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator fallback::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator fallback::ondemand::value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline simdjson_result current_depth() const noexcept; + simdjson_inline simdjson_result is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + /** @copydoc simdjson_inline std::string_view document_reference::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H +/* end file simdjson/generic/ondemand/document.h for fallback */ +/* including simdjson/generic/ondemand/document_stream.h for fallback: #include "simdjson/generic/ondemand/document_stream.h" */ +/* begin file simdjson/generic/ondemand/document_stream.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#ifdef SIMDJSON_THREADS_ENABLED +#include +#include +#include +#endif + +namespace simdjson { +namespace fallback { +namespace ondemand { + +#ifdef SIMDJSON_THREADS_ENABLED +/** @private Custom worker class **/ +struct stage1_worker { + stage1_worker() noexcept = default; + stage1_worker(const stage1_worker&) = delete; + stage1_worker(stage1_worker&&) = delete; + stage1_worker operator=(const stage1_worker&) = delete; + ~stage1_worker(); + /** + * We only start the thread when it is needed, not at object construction, this may throw. + * You should only call this once. + **/ + void start_thread(); + /** + * Start a stage 1 job. You should first call 'run', then 'finish'. + * You must call start_thread once before. + */ + void run(document_stream * ds, parser * stage1, size_t next_batch_start); + /** Wait for the run to finish (blocking). You should first call 'run', then 'finish'. **/ + void finish(); + +private: + + /** + * Normally, we would never stop the thread. But we do in the destructor. + * This function is only safe assuming that you are not waiting for results. You + * should have called run, then finish, and be done. + **/ + void stop_thread(); + + std::thread thread{}; + /** These three variables define the work done by the thread. **/ + ondemand::parser * stage1_thread_parser{}; + size_t _next_batch_start{}; + document_stream * owner{}; + /** + * We have two state variables. This could be streamlined to one variable in the future but + * we use two for clarity. + */ + bool has_work{false}; + bool can_work{true}; + + /** + * We lock using a mutex. + */ + std::mutex locking_mutex{}; + std::condition_variable cond_var{}; + + friend class document_stream; +}; +#endif // SIMDJSON_THREADS_ENABLED + +/** + * A forward-only stream of documents. + * + * Produced by parser::iterate_many. + * + */ +class document_stream { +public: + /** + * Construct an uninitialized document_stream. + * + * ```c++ + * document_stream docs; + * auto error = parser.iterate_many(json).get(docs); + * ``` + */ + simdjson_inline document_stream() noexcept; + /** Move one document_stream to another. */ + simdjson_inline document_stream(document_stream &&other) noexcept = default; + /** Move one document_stream to another. */ + simdjson_inline document_stream &operator=(document_stream &&other) noexcept = default; + + simdjson_inline ~document_stream() noexcept; + + /** + * Returns the input size in bytes. + */ + inline size_t size_in_bytes() const noexcept; + + /** + * After iterating through the stream, this method + * returns the number of bytes that were not parsed at the end + * of the stream. If truncated_bytes() differs from zero, + * then the input was truncated maybe because incomplete JSON + * documents were found at the end of the stream. You + * may need to process the bytes in the interval [size_in_bytes()-truncated_bytes(), size_in_bytes()). + * + * You should only call truncated_bytes() after streaming through all + * documents, like so: + * + * document_stream stream = parser.iterate_many(json,window); + * for(auto & doc : stream) { + * // do something with doc + * } + * size_t truncated = stream.truncated_bytes(); + * + */ + inline size_t truncated_bytes() const noexcept; + + class iterator { + public: + using value_type = simdjson_result; + using reference = value_type; + + using difference_type = std::ptrdiff_t; + + using iterator_category = std::input_iterator_tag; + + /** + * Default constructor. + */ + simdjson_inline iterator() noexcept; + /** + * Get the current document (or error). + */ + simdjson_inline simdjson_result operator*() noexcept; + /** + * Advance to the next document (prefix). + */ + inline iterator& operator++() noexcept; + /** + * Check if we're at the end yet. + * @param other the end iterator to compare to. + */ + simdjson_inline bool operator!=(const iterator &other) const noexcept; + /** + * @private + * + * Gives the current index in the input document in bytes. + * + * document_stream stream = parser.parse_many(json,window); + * for(auto i = stream.begin(); i != stream.end(); ++i) { + * auto doc = *i; + * size_t index = i.current_index(); + * } + * + * This function (current_index()) is experimental and the usage + * may change in future versions of simdjson: we find the API somewhat + * awkward and we would like to offer something friendlier. + */ + simdjson_inline size_t current_index() const noexcept; + + /** + * @private + * + * Gives a view of the current document at the current position. + * + * document_stream stream = parser.iterate_many(json,window); + * for(auto i = stream.begin(); i != stream.end(); ++i) { + * std::string_view v = i.source(); + * } + * + * The returned string_view instance is simply a map to the (unparsed) + * source string: it may thus include white-space characters and all manner + * of padding. + * + * This function (source()) is experimental and the usage + * may change in future versions of simdjson: we find the API somewhat + * awkward and we would like to offer something friendlier. + * + */ + simdjson_inline std::string_view source() const noexcept; + + /** + * Returns error of the stream (if any). + */ + inline error_code error() const noexcept; + + private: + simdjson_inline iterator(document_stream *s, bool finished) noexcept; + /** The document_stream we're iterating through. */ + document_stream* stream; + /** Whether we're finished or not. */ + bool finished; + + friend class document; + friend class document_stream; + friend class json_iterator; + }; + + /** + * Start iterating the documents in the stream. + */ + simdjson_inline iterator begin() noexcept; + /** + * The end of the stream, for iterator comparison purposes. + */ + simdjson_inline iterator end() noexcept; + +private: + + document_stream &operator=(const document_stream &) = delete; // Disallow copying + document_stream(const document_stream &other) = delete; // Disallow copying + + /** + * Construct a document_stream. Does not allocate or parse anything until the iterator is + * used. + * + * @param parser is a reference to the parser instance used to generate this document_stream + * @param buf is the raw byte buffer we need to process + * @param len is the length of the raw byte buffer in bytes + * @param batch_size is the size of the windows (must be strictly greater or equal to the largest JSON document) + */ + simdjson_inline document_stream( + ondemand::parser &parser, + const uint8_t *buf, + size_t len, + size_t batch_size, + bool allow_comma_separated + ) noexcept; + + /** + * Parse the first document in the buffer. Used by begin(), to handle allocation and + * initialization. + */ + inline void start() noexcept; + + /** + * Parse the next document found in the buffer previously given to document_stream. + * + * The content should be a valid JSON document encoded as UTF-8. If there is a + * UTF-8 BOM, the parser skips it. + * + * You do NOT need to pre-allocate a parser. This function takes care of + * pre-allocating a capacity defined by the batch_size defined when creating the + * document_stream object. + * + * The function returns simdjson::EMPTY if there is no more data to be parsed. + * + * The function returns simdjson::SUCCESS (as integer = 0) in case of success + * and indicates that the buffer has successfully been parsed to the end. + * Every document it contained has been parsed without error. + * + * The function returns an error code from simdjson/simdjson.h in case of failure + * such as simdjson::CAPACITY, simdjson::MEMALLOC, simdjson::DEPTH_ERROR and so forth; + * the simdjson::error_message function converts these error codes into a string). + * + * You can also check validity by calling parser.is_valid(). The same parser can + * and should be reused for the other documents in the buffer. + */ + inline void next() noexcept; + + /** Move the json_iterator of the document to the location of the next document in the stream. */ + inline void next_document() noexcept; + + /** Get the next document index. */ + inline size_t next_batch_start() const noexcept; + + /** Pass the next batch through stage 1 with the given parser. */ + inline error_code run_stage1(ondemand::parser &p, size_t batch_start) noexcept; + + // Fields + ondemand::parser *parser; + const uint8_t *buf; + size_t len; + size_t batch_size; + bool allow_comma_separated; + /** + * We are going to use just one document instance. The document owns + * the json_iterator. It implies that we only ever pass a reference + * to the document to the users. + */ + document doc{}; + /** The error (or lack thereof) from the current document. */ + error_code error; + size_t batch_start{0}; + size_t doc_index{}; + + #ifdef SIMDJSON_THREADS_ENABLED + /** Indicates whether we use threads. Note that this needs to be a constant during the execution of the parsing. */ + bool use_thread; + + inline void load_from_stage1_thread() noexcept; + + /** Start a thread to run stage 1 on the next batch. */ + inline void start_stage1_thread() noexcept; + + /** Wait for the stage 1 thread to finish and capture the results. */ + inline void finish_stage1_thread() noexcept; + + /** The error returned from the stage 1 thread. */ + error_code stage1_thread_error{UNINITIALIZED}; + /** The thread used to run stage 1 against the next batch in the background. */ + std::unique_ptr worker{new(std::nothrow) stage1_worker()}; + /** + * The parser used to run stage 1 in the background. Will be swapped + * with the regular parser when finished. + */ + ondemand::parser stage1_thread_parser{}; + + friend struct stage1_worker; + #endif // SIMDJSON_THREADS_ENABLED + + friend class parser; + friend class document; + friend class json_iterator; + friend struct simdjson_result; + friend struct internal::simdjson_result_base; +}; // document_stream + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::document_stream &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H +/* end file simdjson/generic/ondemand/document_stream.h for fallback */ +/* including simdjson/generic/ondemand/field.h for fallback: #include "simdjson/generic/ondemand/field.h" */ +/* begin file simdjson/generic/ondemand/field.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_FIELD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_FIELD_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +/** + * A JSON field (key/value pair) in an object. + * + * Returned from object iteration. + * + * Extends from std::pair so you can use C++ algorithms that rely on pairs. + */ +class field : public std::pair { +public: + /** + * Create a new invalid field. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline field() noexcept; + + /** + * Get the key as a string_view (for higher speed, consider raw_key). + * We deliberately use a more cumbersome name (unescaped_key) to force users + * to think twice about using it. + * + * This consumes the key: once you have called unescaped_key(), you cannot + * call it again nor can you call key(). + */ + simdjson_inline simdjson_warn_unused simdjson_result unescaped_key(bool allow_replacement) noexcept; + /** + * Get the key as a raw_json_string. Can be used for direct comparison with + * an unescaped C string: e.g., key() == "test". + */ + simdjson_inline raw_json_string key() const noexcept; + /** + * Get the field value. + */ + simdjson_inline ondemand::value &value() & noexcept; + /** + * @overload ondemand::value &ondemand::value() & noexcept + */ + simdjson_inline ondemand::value value() && noexcept; + +protected: + simdjson_inline field(raw_json_string key, ondemand::value &&value) noexcept; + static simdjson_inline simdjson_result start(value_iterator &parent_iter) noexcept; + static simdjson_inline simdjson_result start(const value_iterator &parent_iter, raw_json_string key) noexcept; + friend struct simdjson_result; + friend class object_iterator; +}; + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::field &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result unescaped_key(bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result key() noexcept; + simdjson_inline simdjson_result value() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_FIELD_H +/* end file simdjson/generic/ondemand/field.h for fallback */ +/* including simdjson/generic/ondemand/object.h for fallback: #include "simdjson/generic/ondemand/object.h" */ +/* begin file simdjson/generic/ondemand/object.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +/** + * A forward-only JSON object field iterator. + */ +class object { +public: + /** + * Create a new invalid object. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline object() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. The value instance you get + * from `content["bids"]` becomes invalid when you call `content["asks"]`. The array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a + * key a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field(std::string_view key) && noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. The value instance you get + * from `content["bids"]` becomes invalid when you call `content["asks"]`. The array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a key + * a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) && noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) && noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard, interpreting the current node + * as the root of its own JSON document. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. Yet it is not the case when calling at_pointer on an object + * instance: there is no rewind and no invalidation. + * + * You may call at_pointer more than once on an object, but each time the pointer is advanced + * to be within the value matched by the key indicated by the JSON pointer query. Thus any preceding + * key (as well as the current key) can no longer be used with following JSON pointer calls. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching. + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + + /** + * Reset the iterator so that we are pointing back at the + * beginning of the object. You should still consume values only once even if you + * can iterate through the object more than once. If you unescape a string within + * the object more than once, you have unsafe code. Note that rewinding an object + * means that you may need to reparse it anew: it is not a free operation. + * + * @returns true if the object contains some elements (not empty) + */ + inline simdjson_result reset() & noexcept; + /** + * This method scans the beginning of the object and checks whether the + * object is empty. + * The runtime complexity is constant time. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + inline simdjson_result is_empty() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method. + * + * Performance hint: You should only call count_fields() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Consumes the object and returns a string_view instance corresponding to the + * object as represented in JSON. It points inside the original byte array containing + * the JSON document. + */ + simdjson_inline simdjson_result raw_json() noexcept; + +protected: + /** + * Go to the end of the object, no matter where you are right now. + */ + simdjson_inline error_code consume() noexcept; + static simdjson_inline simdjson_result start(value_iterator &iter) noexcept; + static simdjson_inline simdjson_result start_root(value_iterator &iter) noexcept; + static simdjson_inline simdjson_result started(value_iterator &iter) noexcept; + static simdjson_inline object resume(const value_iterator &iter) noexcept; + simdjson_inline object(const value_iterator &iter) noexcept; + + simdjson_warn_unused simdjson_inline error_code find_field_raw(const std::string_view key) noexcept; + + value_iterator iter{}; + + friend class value; + friend class document; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::object &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) && noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) && noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) && noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + inline simdjson_result reset() noexcept; + inline simdjson_result is_empty() noexcept; + inline simdjson_result count_fields() & noexcept; + inline simdjson_result raw_json() noexcept; + +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_H +/* end file simdjson/generic/ondemand/object.h for fallback */ +/* including simdjson/generic/ondemand/object_iterator.h for fallback: #include "simdjson/generic/ondemand/object_iterator.h" */ +/* begin file simdjson/generic/ondemand/object_iterator.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +class object_iterator { +public: + /** + * Create a new invalid object_iterator. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline object_iterator() noexcept = default; + + // + // Iterator interface + // + + // Reads key and value, yielding them to the user. + // MUST ONLY BE CALLED ONCE PER ITERATION. + simdjson_inline simdjson_result operator*() noexcept; + // Assumes it's being compared with the end. true if depth < iter->depth. + simdjson_inline bool operator==(const object_iterator &) const noexcept; + // Assumes it's being compared with the end. true if depth >= iter->depth. + simdjson_inline bool operator!=(const object_iterator &) const noexcept; + // Checks for ']' and ',' + simdjson_inline object_iterator &operator++() noexcept; + +private: + /** + * The underlying JSON iterator. + * + * PERF NOTE: expected to be elided in favor of the parent document: this is set when the object + * is first used, and never changes afterwards. + */ + value_iterator iter{}; + + simdjson_inline object_iterator(const value_iterator &iter) noexcept; + friend struct simdjson_result; + friend class object; +}; + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public fallback::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(fallback::ondemand::object_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + // + // Iterator interface + // + + // Reads key and value, yielding them to the user. + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + // Assumes it's being compared with the end. true if depth < iter->depth. + simdjson_inline bool operator==(const simdjson_result &) const noexcept; + // Assumes it's being compared with the end. true if depth >= iter->depth. + simdjson_inline bool operator!=(const simdjson_result &) const noexcept; + // Checks for ']' and ',' + simdjson_inline simdjson_result &operator++() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H +/* end file simdjson/generic/ondemand/object_iterator.h for fallback */ +/* including simdjson/generic/ondemand/serialization.h for fallback: #include "simdjson/generic/ondemand/serialization.h" */ +/* begin file simdjson/generic/ondemand/serialization.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Create a string-view instance out of a document instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(fallback::ondemand::document& x) noexcept; +/** + * Create a string-view instance out of a value instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. The value must + * not have been accessed previously. It does not + * validate the content. + */ +inline simdjson_result to_json_string(fallback::ondemand::value& x) noexcept; +/** + * Create a string-view instance out of an object instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(fallback::ondemand::object& x) noexcept; +/** + * Create a string-view instance out of an array instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(fallback::ondemand::array& x) noexcept; +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +} // namespace simdjson + +/** + * We want to support argument-dependent lookup (ADL). + * Hence we should define operator<< in the namespace + * where the argument (here value, object, etc.) resides. + * Credit: @madhur4127 + * See https://github.com/simdjson/simdjson/issues/1768 + */ +namespace simdjson { namespace fallback { namespace ondemand { + +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The element. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::fallback::ondemand::value x); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The array. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::fallback::ondemand::array value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The array. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::fallback::ondemand::document& value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x); +#endif +inline std::ostream& operator<<(std::ostream& out, simdjson::fallback::ondemand::document_reference& value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The object. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::fallback::ondemand::object value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +}}} // namespace simdjson::fallback::ondemand + +#endif // SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H +/* end file simdjson/generic/ondemand/serialization.h for fallback */ + +// Inline definitions +/* including simdjson/generic/ondemand/array-inl.h for fallback: #include "simdjson/generic/ondemand/array-inl.h" */ +/* begin file simdjson/generic/ondemand/array-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +// +// ### Live States +// +// While iterating or looking up values, depth >= iter->depth. at_start may vary. Error is +// always SUCCESS: +// +// - Start: This is the state when the array is first found and the iterator is just past the `{`. +// In this state, at_start == true. +// - Next: After we hand a scalar value to the user, or an array/object which they then fully +// iterate over, the iterator is at the `,` before the next value (or `]`). In this state, +// depth == iter->depth, at_start == false, and error == SUCCESS. +// - Unfinished Business: When we hand an array/object to the user which they do not fully +// iterate over, we need to finish that iteration by skipping child values until we reach the +// Next state. In this state, depth > iter->depth, at_start == false, and error == SUCCESS. +// +// ## Error States +// +// In error states, we will yield exactly one more value before stopping. iter->depth == depth +// and at_start is always false. We decrement after yielding the error, moving to the Finished +// state. +// +// - Chained Error: When the array iterator is part of an error chain--for example, in +// `for (auto tweet : doc["tweets"])`, where the tweet element may be missing or not be an +// array--we yield that error in the loop, exactly once. In this state, error != SUCCESS and +// iter->depth == depth, and at_start == false. We decrement depth when we yield the error. +// - Missing Comma Error: When the iterator ++ method discovers there is no comma between elements, +// we flag that as an error and treat it exactly the same as a Chained Error. In this state, +// error == TAPE_ERROR, iter->depth == depth, and at_start == false. +// +// ## Terminal State +// +// The terminal state has iter->depth < depth. at_start is always false. +// +// - Finished: When we have reached a `]` or have reported an error, we are finished. We signal this +// by decrementing depth. In this state, iter->depth < depth, at_start == false, and +// error == SUCCESS. +// + +simdjson_inline array::array(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} + +simdjson_inline simdjson_result array::start(value_iterator &iter) noexcept { + // We don't need to know if the array is empty to start iteration, but we do want to know if there + // is an error--thus `simdjson_unused`. + simdjson_unused bool has_value; + SIMDJSON_TRY( iter.start_array().get(has_value) ); + return array(iter); +} +simdjson_inline simdjson_result array::start_root(value_iterator &iter) noexcept { + simdjson_unused bool has_value; + SIMDJSON_TRY( iter.start_root_array().get(has_value) ); + return array(iter); +} +simdjson_inline simdjson_result array::started(value_iterator &iter) noexcept { + bool has_value; + SIMDJSON_TRY(iter.started_array().get(has_value)); + return array(iter); +} + +simdjson_inline simdjson_result array::begin() noexcept { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + return array_iterator(iter); +} +simdjson_inline simdjson_result array::end() noexcept { + return array_iterator(iter); +} +simdjson_inline error_code array::consume() noexcept { + auto error = iter.json_iter().skip_child(iter.depth()-1); + if(error) { iter.abandon(); } + return error; +} + +simdjson_inline simdjson_result array::raw_json() noexcept { + const uint8_t * starting_point{iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + // After 'consume()', we could be left pointing just beyond the document, but that + // is ok because we are not going to dereference the final pointer position, we just + // use it to compute the length in bytes. + const uint8_t * final_point{iter._json_iter->unsafe_pointer()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline simdjson_result array::count_elements() & noexcept { + size_t count{0}; + // Important: we do not consume any of the values. + for(simdjson_unused auto v : *this) { count++; } + // The above loop will always succeed, but we want to report errors. + if(iter.error()) { return iter.error(); } + // We need to move back at the start because we expect users to iterate through + // the array after counting the number of elements. + iter.reset_array(); + return count; +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline simdjson_result array::is_empty() & noexcept { + bool is_not_empty; + auto error = iter.reset_array().get(is_not_empty); + if(error) { return error; } + return !is_not_empty; +} + +inline simdjson_result array::reset() & noexcept { + return iter.reset_array(); +} + +inline simdjson_result array::at_pointer(std::string_view json_pointer) noexcept { + if (json_pointer[0] != '/') { return INVALID_JSON_POINTER; } + json_pointer = json_pointer.substr(1); + // - 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; } + + // Read the array index + size_t array_index = 0; + size_t i; + for (i = 0; i < json_pointer.length() && json_pointer[i] != '/'; i++) { + uint8_t digit = uint8_t(json_pointer[i] - '0'); + // Check for non-digit in array index. If it's there, we're trying to get a field in an object + if (digit > 9) { return INCORRECT_TYPE; } + array_index = array_index*10 + digit; + } + + // 0 followed by other digits is invalid + if (i > 1 && json_pointer[0] == '0') { return INVALID_JSON_POINTER; } // "JSON pointer array index has other characters after 0" + + // Empty string is invalid; so is a "/" with no digits before it + if (i == 0) { return INVALID_JSON_POINTER; } // "Empty string in JSON pointer array index" + // Get the child + auto child = at(array_index); + // If there is an error, it ends here + if(child.error()) { + return child; + } + + // If there is a /, we're not done yet, call recursively. + if (i < json_pointer.length()) { + child = child.at_pointer(json_pointer.substr(i)); + } + return child; +} + +simdjson_inline simdjson_result array::at(size_t index) noexcept { + size_t i = 0; + for (auto value : *this) { + if (i == index) { return value; } + i++; + } + return INDEX_OUT_OF_BOUNDS; +} + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + fallback::ondemand::array &&value +) noexcept + : implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept + : implementation_simdjson_result_base(error) +{ +} + +simdjson_inline simdjson_result simdjson_result::begin() noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() noexcept { + if (error()) { return error(); } + return first.end(); +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::is_empty() & noexcept { + if (error()) { return error(); } + return first.is_empty(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H +/* end file simdjson/generic/ondemand/array-inl.h for fallback */ +/* including simdjson/generic/ondemand/array_iterator-inl.h for fallback: #include "simdjson/generic/ondemand/array_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/array_iterator-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +simdjson_inline array_iterator::array_iterator(const value_iterator &_iter) noexcept + : iter{_iter} +{} + +simdjson_inline simdjson_result array_iterator::operator*() noexcept { + if (iter.error()) { iter.abandon(); return iter.error(); } + return value(iter.child()); +} +simdjson_inline bool array_iterator::operator==(const array_iterator &other) const noexcept { + return !(*this != other); +} +simdjson_inline bool array_iterator::operator!=(const array_iterator &) const noexcept { + return iter.is_open(); +} +simdjson_inline array_iterator &array_iterator::operator++() noexcept { + error_code error; + // PERF NOTE this is a safety rail ... users should exit loops as soon as they receive an error, so we'll never get here. + // However, it does not seem to make a perf difference, so we add it out of an abundance of caution. + if (( error = iter.error() )) { return *this; } + if (( error = iter.skip_child() )) { return *this; } + if (( error = iter.has_next_element().error() )) { return *this; } + return *this; +} + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + fallback::ondemand::array_iterator &&value +) noexcept + : fallback::implementation_simdjson_result_base(std::forward(value)) +{ + first.iter.assert_is_valid(); +} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : fallback::implementation_simdjson_result_base({}, error) +{ +} + +simdjson_inline simdjson_result simdjson_result::operator*() noexcept { + if (error()) { return error(); } + return *first; +} +simdjson_inline bool simdjson_result::operator==(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return !error(); } + return first == other.first; +} +simdjson_inline bool simdjson_result::operator!=(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return error(); } + return first != other.first; +} +simdjson_inline simdjson_result &simdjson_result::operator++() noexcept { + // Clear the error if there is one, so we don't yield it twice + if (error()) { second = SUCCESS; return *this; } + ++(first); + return *this; +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/array_iterator-inl.h for fallback */ +/* including simdjson/generic/ondemand/document-inl.h for fallback: #include "simdjson/generic/ondemand/document-inl.h" */ +/* begin file simdjson/generic/ondemand/document-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +simdjson_inline document::document(ondemand::json_iterator &&_iter) noexcept + : iter{std::forward(_iter)} +{ + logger::log_start_value(iter, "document"); +} + +simdjson_inline document document::start(json_iterator &&iter) noexcept { + return document(std::forward(iter)); +} + +inline void document::rewind() noexcept { + iter.rewind(); +} + +inline std::string document::to_debug_string() noexcept { + return iter.to_string(); +} + +inline simdjson_result document::current_location() const noexcept { + return iter.current_location(); +} + +inline int32_t document::current_depth() const noexcept { + return iter.depth(); +} + +inline bool document::at_end() const noexcept { + return iter.at_end(); +} + + +inline bool document::is_alive() noexcept { + return iter.is_alive(); +} +simdjson_inline value_iterator document::resume_value_iterator() noexcept { + return value_iterator(&iter, 1, iter.root_position()); +} +simdjson_inline value_iterator document::get_root_value_iterator() noexcept { + return resume_value_iterator(); +} +simdjson_inline simdjson_result document::start_or_resume_object() noexcept { + if (iter.at_root()) { + return get_object(); + } else { + return object::resume(resume_value_iterator()); + } +} +simdjson_inline simdjson_result document::get_value() noexcept { + // Make sure we start any arrays or objects before returning, so that start_root_() + // gets called. + + // It is the convention throughout the code that the macro `SIMDJSON_DEVELOPMENT_CHECKS` determines whether + // we check for OUT_OF_ORDER_ITERATION. Proper on::demand code should never trigger this error. +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.at_root()) { return OUT_OF_ORDER_ITERATION; } +#endif + // assert_at_root() serves two purposes: in Debug mode, whether or not + // SIMDJSON_DEVELOPMENT_CHECKS is set or not, it checks that we are at the root of + // the document (this will typically be redundant). In release mode, it generates + // SIMDJSON_ASSUME statements to allow the compiler to make assumptions. + iter.assert_at_root(); + switch (*iter.peek()) { + case '[': { + // The following lines check that the document ends with ]. + auto value_iterator = get_root_value_iterator(); + auto error = value_iterator.check_root_array(); + if(error) { return error; } + return value(get_root_value_iterator()); + } + case '{': { + // The following lines would check that the document ends with }. + auto value_iterator = get_root_value_iterator(); + auto error = value_iterator.check_root_object(); + if(error) { return error; } + return value(get_root_value_iterator()); + } + default: + // Unfortunately, scalar documents are a special case in simdjson and they cannot + // be safely converted to value instances. + return SCALAR_DOCUMENT_AS_VALUE; + } +} +simdjson_inline simdjson_result document::get_array() & noexcept { + auto value = get_root_value_iterator(); + return array::start_root(value); +} +simdjson_inline simdjson_result document::get_object() & noexcept { + auto value = get_root_value_iterator(); + return object::start_root(value); +} + +/** + * We decided that calling 'get_double()' on the JSON document '1.233 blabla' should + * give an error, so we check for trailing content. We want to disallow trailing + * content. + * Thus, in several implementations below, we pass a 'true' parameter value to + * a get_root_value_iterator() method: this indicates that we disallow trailing content. + */ + +simdjson_inline simdjson_result document::get_uint64() noexcept { + return get_root_value_iterator().get_root_uint64(true); +} +simdjson_inline simdjson_result document::get_uint64_in_string() noexcept { + return get_root_value_iterator().get_root_uint64_in_string(true); +} +simdjson_inline simdjson_result document::get_int64() noexcept { + return get_root_value_iterator().get_root_int64(true); +} +simdjson_inline simdjson_result document::get_int64_in_string() noexcept { + return get_root_value_iterator().get_root_int64_in_string(true); +} +simdjson_inline simdjson_result document::get_double() noexcept { + return get_root_value_iterator().get_root_double(true); +} +simdjson_inline simdjson_result document::get_double_in_string() noexcept { + return get_root_value_iterator().get_root_double_in_string(true); +} +simdjson_inline simdjson_result document::get_string(bool allow_replacement) noexcept { + return get_root_value_iterator().get_root_string(true, allow_replacement); +} +template +simdjson_inline error_code document::get_string(string_type& receiver, bool allow_replacement) noexcept { + return get_root_value_iterator().get_root_string(receiver, true, allow_replacement); +} +simdjson_inline simdjson_result document::get_wobbly_string() noexcept { + return get_root_value_iterator().get_root_wobbly_string(true); +} +simdjson_inline simdjson_result document::get_raw_json_string() noexcept { + return get_root_value_iterator().get_root_raw_json_string(true); +} +simdjson_inline simdjson_result document::get_bool() noexcept { + return get_root_value_iterator().get_root_bool(true); +} +simdjson_inline simdjson_result document::is_null() noexcept { + return get_root_value_iterator().is_root_null(true); +} + +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_array(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_object(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_double(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_uint64(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_int64(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_bool(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_value(); } + +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_double(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_uint64(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_int64(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_bool(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_value(); } + +template simdjson_inline error_code document::get(T &out) & noexcept { + return get().get(out); +} +template simdjson_inline error_code document::get(T &out) && noexcept { + return std::forward(*this).get().get(out); +} + +#if SIMDJSON_EXCEPTIONS +simdjson_inline document::operator array() & noexcept(false) { return get_array(); } +simdjson_inline document::operator object() & noexcept(false) { return get_object(); } +simdjson_inline document::operator uint64_t() noexcept(false) { return get_uint64(); } +simdjson_inline document::operator int64_t() noexcept(false) { return get_int64(); } +simdjson_inline document::operator double() noexcept(false) { return get_double(); } +simdjson_inline document::operator std::string_view() noexcept(false) { return get_string(false); } +simdjson_inline document::operator raw_json_string() noexcept(false) { return get_raw_json_string(); } +simdjson_inline document::operator bool() noexcept(false) { return get_bool(); } +simdjson_inline document::operator value() noexcept(false) { return get_value(); } + +#endif +simdjson_inline simdjson_result document::count_elements() & noexcept { + auto a = get_array(); + simdjson_result answer = a.count_elements(); + /* If there was an array, we are now left pointing at its first element. */ + if(answer.error() == SUCCESS) { rewind(); } + return answer; +} +simdjson_inline simdjson_result document::count_fields() & noexcept { + auto a = get_object(); + simdjson_result answer = a.count_fields(); + /* If there was an object, we are now left pointing at its first element. */ + if(answer.error() == SUCCESS) { rewind(); } + return answer; +} +simdjson_inline simdjson_result document::at(size_t index) & noexcept { + auto a = get_array(); + return a.at(index); +} +simdjson_inline simdjson_result document::begin() & noexcept { + return get_array().begin(); +} +simdjson_inline simdjson_result document::end() & noexcept { + return {}; +} + +simdjson_inline simdjson_result document::find_field(std::string_view key) & noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result document::find_field(const char *key) & noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result document::find_field_unordered(std::string_view key) & noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result document::find_field_unordered(const char *key) & noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result document::operator[](std::string_view key) & noexcept { + return start_or_resume_object()[key]; +} +simdjson_inline simdjson_result document::operator[](const char *key) & noexcept { + return start_or_resume_object()[key]; +} + +simdjson_inline error_code document::consume() noexcept { + auto error = iter.skip_child(0); + if(error) { iter.abandon(); } + return error; +} + +simdjson_inline simdjson_result document::raw_json() noexcept { + auto _iter = get_root_value_iterator(); + const uint8_t * starting_point{_iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + // After 'consume()', we could be left pointing just beyond the document, but that + // is ok because we are not going to dereference the final pointer position, we just + // use it to compute the length in bytes. + const uint8_t * final_point{iter.unsafe_pointer()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +simdjson_inline simdjson_result document::type() noexcept { + return get_root_value_iterator().type(); +} + +simdjson_inline simdjson_result document::is_scalar() noexcept { + json_type this_type; + auto error = type().get(this_type); + if(error) { return error; } + return ! ((this_type == json_type::array) || (this_type == json_type::object)); +} + +simdjson_inline bool document::is_negative() noexcept { + return get_root_value_iterator().is_root_negative(); +} + +simdjson_inline simdjson_result document::is_integer() noexcept { + return get_root_value_iterator().is_root_integer(true); +} + +simdjson_inline simdjson_result document::get_number_type() noexcept { + return get_root_value_iterator().get_root_number_type(true); +} + +simdjson_inline simdjson_result document::get_number() noexcept { + return get_root_value_iterator().get_root_number(true); +} + + +simdjson_inline simdjson_result document::raw_json_token() noexcept { + auto _iter = get_root_value_iterator(); + return std::string_view(reinterpret_cast(_iter.peek_start()), _iter.peek_start_length()); +} + +simdjson_inline simdjson_result document::at_pointer(std::string_view json_pointer) noexcept { + rewind(); // Rewind the document each time at_pointer is called + if (json_pointer.empty()) { + return this->get_value(); + } + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: + return (*this).get_array().at_pointer(json_pointer); + case json_type::object: + return (*this).get_object().at_pointer(json_pointer); + default: + return INVALID_JSON_POINTER; + } +} + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + fallback::ondemand::document &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base( + error + ) +{ +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) & noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline error_code simdjson_result::rewind() noexcept { + if (error()) { return error(); } + first.rewind(); + return SUCCESS; +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::get_array() & noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() & noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::get_value() noexcept { + if (error()) { return error(); } + return first.get_value(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} + +template +simdjson_inline simdjson_result simdjson_result::get() & noexcept { + if (error()) { return error(); } + return first.get(); +} +template +simdjson_inline simdjson_result simdjson_result::get() && noexcept { + if (error()) { return error(); } + return std::forward(first).get(); +} +template +simdjson_inline error_code simdjson_result::get(T &out) & noexcept { + if (error()) { return error(); } + return first.get(out); +} +template +simdjson_inline error_code simdjson_result::get(T &out) && noexcept { + if (error()) { return error(); } + return std::forward(first).get(out); +} + +template<> simdjson_inline simdjson_result simdjson_result::get() & noexcept = delete; +template<> simdjson_inline simdjson_result simdjson_result::get() && noexcept { + if (error()) { return error(); } + return std::forward(first); +} +template<> simdjson_inline error_code simdjson_result::get(fallback::ondemand::document &out) & noexcept = delete; +template<> simdjson_inline error_code simdjson_result::get(fallback::ondemand::document &out) && noexcept { + if (error()) { return error(); } + out = std::forward(first); + return SUCCESS; +} + +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} + +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} + + +simdjson_inline bool simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} + +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} + +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} + +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} + + +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator fallback::ondemand::array() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator fallback::ondemand::object() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator fallback::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator fallback::ondemand::value() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline bool simdjson_result::at_end() const noexcept { + if (error()) { return error(); } + return first.at_end(); +} + + +simdjson_inline int32_t simdjson_result::current_depth() const noexcept { + if (error()) { return error(); } + return first.current_depth(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + + +} // namespace simdjson + + +namespace simdjson { +namespace fallback { +namespace ondemand { + +simdjson_inline document_reference::document_reference() noexcept : doc{nullptr} {} +simdjson_inline document_reference::document_reference(document &d) noexcept : doc(&d) {} +simdjson_inline void document_reference::rewind() noexcept { doc->rewind(); } +simdjson_inline simdjson_result document_reference::get_array() & noexcept { return doc->get_array(); } +simdjson_inline simdjson_result document_reference::get_object() & noexcept { return doc->get_object(); } +/** + * The document_reference instances are used primarily/solely for streams of JSON + * documents. + * We decided that calling 'get_double()' on the JSON document '1.233 blabla' should + * give an error, so we check for trailing content. + * + * However, for streams of JSON documents, we want to be able to start from + * "321" "321" "321" + * and parse it successfully as a stream of JSON documents, calling get_uint64_in_string() + * successfully each time. + * + * To achieve this result, we pass a 'false' to a get_root_value_iterator() method: + * this indicates that we allow trailing content. + */ +simdjson_inline simdjson_result document_reference::get_uint64() noexcept { return doc->get_root_value_iterator().get_root_uint64(false); } +simdjson_inline simdjson_result document_reference::get_uint64_in_string() noexcept { return doc->get_root_value_iterator().get_root_uint64_in_string(false); } +simdjson_inline simdjson_result document_reference::get_int64() noexcept { return doc->get_root_value_iterator().get_root_int64(false); } +simdjson_inline simdjson_result document_reference::get_int64_in_string() noexcept { return doc->get_root_value_iterator().get_root_int64_in_string(false); } +simdjson_inline simdjson_result document_reference::get_double() noexcept { return doc->get_root_value_iterator().get_root_double(false); } +simdjson_inline simdjson_result document_reference::get_double_in_string() noexcept { return doc->get_root_value_iterator().get_root_double(false); } +simdjson_inline simdjson_result document_reference::get_string(bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(false, allow_replacement); } +template +simdjson_inline error_code document_reference::get_string(string_type& receiver, bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(receiver, false, allow_replacement); } +simdjson_inline simdjson_result document_reference::get_wobbly_string() noexcept { return doc->get_root_value_iterator().get_root_wobbly_string(false); } +simdjson_inline simdjson_result document_reference::get_raw_json_string() noexcept { return doc->get_root_value_iterator().get_root_raw_json_string(false); } +simdjson_inline simdjson_result document_reference::get_bool() noexcept { return doc->get_root_value_iterator().get_root_bool(false); } +simdjson_inline simdjson_result document_reference::get_value() noexcept { return doc->get_value(); } +simdjson_inline simdjson_result document_reference::is_null() noexcept { return doc->get_root_value_iterator().is_root_null(false); } + +#if SIMDJSON_EXCEPTIONS +simdjson_inline document_reference::operator array() & noexcept(false) { return array(*doc); } +simdjson_inline document_reference::operator object() & noexcept(false) { return object(*doc); } +simdjson_inline document_reference::operator uint64_t() noexcept(false) { return get_uint64(); } +simdjson_inline document_reference::operator int64_t() noexcept(false) { return get_int64(); } +simdjson_inline document_reference::operator double() noexcept(false) { return get_double(); } +simdjson_inline document_reference::operator std::string_view() noexcept(false) { return std::string_view(*doc); } +simdjson_inline document_reference::operator raw_json_string() noexcept(false) { return raw_json_string(*doc); } +simdjson_inline document_reference::operator bool() noexcept(false) { return get_bool(); } +simdjson_inline document_reference::operator value() noexcept(false) { return value(*doc); } +#endif +simdjson_inline simdjson_result document_reference::count_elements() & noexcept { return doc->count_elements(); } +simdjson_inline simdjson_result document_reference::count_fields() & noexcept { return doc->count_fields(); } +simdjson_inline simdjson_result document_reference::at(size_t index) & noexcept { return doc->at(index); } +simdjson_inline simdjson_result document_reference::begin() & noexcept { return doc->begin(); } +simdjson_inline simdjson_result document_reference::end() & noexcept { return doc->end(); } +simdjson_inline simdjson_result document_reference::find_field(std::string_view key) & noexcept { return doc->find_field(key); } +simdjson_inline simdjson_result document_reference::find_field(const char *key) & noexcept { return doc->find_field(key); } +simdjson_inline simdjson_result document_reference::operator[](std::string_view key) & noexcept { return (*doc)[key]; } +simdjson_inline simdjson_result document_reference::operator[](const char *key) & noexcept { return (*doc)[key]; } +simdjson_inline simdjson_result document_reference::find_field_unordered(std::string_view key) & noexcept { return doc->find_field_unordered(key); } +simdjson_inline simdjson_result document_reference::find_field_unordered(const char *key) & noexcept { return doc->find_field_unordered(key); } +simdjson_inline simdjson_result document_reference::type() noexcept { return doc->type(); } +simdjson_inline simdjson_result document_reference::is_scalar() noexcept { return doc->is_scalar(); } +simdjson_inline simdjson_result document_reference::current_location() noexcept { return doc->current_location(); } +simdjson_inline int32_t document_reference::current_depth() const noexcept { return doc->current_depth(); } +simdjson_inline bool document_reference::is_negative() noexcept { return doc->is_negative(); } +simdjson_inline simdjson_result document_reference::is_integer() noexcept { return doc->get_root_value_iterator().is_root_integer(false); } +simdjson_inline simdjson_result document_reference::get_number_type() noexcept { return doc->get_root_value_iterator().get_root_number_type(false); } +simdjson_inline simdjson_result document_reference::get_number() noexcept { return doc->get_root_value_iterator().get_root_number(false); } +simdjson_inline simdjson_result document_reference::raw_json_token() noexcept { return doc->raw_json_token(); } +simdjson_inline simdjson_result document_reference::at_pointer(std::string_view json_pointer) noexcept { return doc->at_pointer(json_pointer); } +simdjson_inline simdjson_result document_reference::raw_json() noexcept { return doc->raw_json();} +simdjson_inline document_reference::operator document&() const noexcept { return *doc; } + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + + + +namespace simdjson { +simdjson_inline simdjson_result::simdjson_result(fallback::ondemand::document_reference value, error_code error) + noexcept : implementation_simdjson_result_base(std::forward(value), error) {} + + +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) & noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline error_code simdjson_result::rewind() noexcept { + if (error()) { return error(); } + first.rewind(); + return SUCCESS; +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::get_array() & noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() & noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::get_value() noexcept { + if (error()) { return error(); } + return first.get_value(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} +simdjson_inline simdjson_result simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator fallback::ondemand::array() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator fallback::ondemand::object() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator fallback::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator fallback::ondemand::value() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H +/* end file simdjson/generic/ondemand/document-inl.h for fallback */ +/* including simdjson/generic/ondemand/document_stream-inl.h for fallback: #include "simdjson/generic/ondemand/document_stream-inl.h" */ +/* begin file simdjson/generic/ondemand/document_stream-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document_stream.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include + +namespace simdjson { +namespace fallback { +namespace ondemand { + +#ifdef SIMDJSON_THREADS_ENABLED + +inline void stage1_worker::finish() { + // After calling "run" someone would call finish() to wait + // for the end of the processing. + // This function will wait until either the thread has done + // the processing or, else, the destructor has been called. + std::unique_lock lock(locking_mutex); + cond_var.wait(lock, [this]{return has_work == false;}); +} + +inline stage1_worker::~stage1_worker() { + // The thread may never outlive the stage1_worker instance + // and will always be stopped/joined before the stage1_worker + // instance is gone. + stop_thread(); +} + +inline void stage1_worker::start_thread() { + std::unique_lock lock(locking_mutex); + if(thread.joinable()) { + return; // This should never happen but we never want to create more than one thread. + } + thread = std::thread([this]{ + while(true) { + std::unique_lock thread_lock(locking_mutex); + // We wait for either "run" or "stop_thread" to be called. + cond_var.wait(thread_lock, [this]{return has_work || !can_work;}); + // If, for some reason, the stop_thread() method was called (i.e., the + // destructor of stage1_worker is called, then we want to immediately destroy + // the thread (and not do any more processing). + if(!can_work) { + break; + } + this->owner->stage1_thread_error = this->owner->run_stage1(*this->stage1_thread_parser, + this->_next_batch_start); + this->has_work = false; + // The condition variable call should be moved after thread_lock.unlock() for performance + // reasons but thread sanitizers may report it as a data race if we do. + // See https://stackoverflow.com/questions/35775501/c-should-condition-variable-be-notified-under-lock + cond_var.notify_one(); // will notify "finish" + thread_lock.unlock(); + } + } + ); +} + + +inline void stage1_worker::stop_thread() { + std::unique_lock lock(locking_mutex); + // We have to make sure that all locks can be released. + can_work = false; + has_work = false; + cond_var.notify_all(); + lock.unlock(); + if(thread.joinable()) { + thread.join(); + } +} + +inline void stage1_worker::run(document_stream * ds, parser * stage1, size_t next_batch_start) { + std::unique_lock lock(locking_mutex); + owner = ds; + _next_batch_start = next_batch_start; + stage1_thread_parser = stage1; + has_work = true; + // The condition variable call should be moved after thread_lock.unlock() for performance + // reasons but thread sanitizers may report it as a data race if we do. + // See https://stackoverflow.com/questions/35775501/c-should-condition-variable-be-notified-under-lock + cond_var.notify_one(); // will notify the thread lock that we have work + lock.unlock(); +} + +#endif // SIMDJSON_THREADS_ENABLED + +simdjson_inline document_stream::document_stream( + ondemand::parser &_parser, + const uint8_t *_buf, + size_t _len, + size_t _batch_size, + bool _allow_comma_separated +) noexcept + : parser{&_parser}, + buf{_buf}, + len{_len}, + batch_size{_batch_size <= MINIMAL_BATCH_SIZE ? MINIMAL_BATCH_SIZE : _batch_size}, + allow_comma_separated{_allow_comma_separated}, + error{SUCCESS} + #ifdef SIMDJSON_THREADS_ENABLED + , use_thread(_parser.threaded) // we need to make a copy because _parser.threaded can change + #endif +{ +#ifdef SIMDJSON_THREADS_ENABLED + if(worker.get() == nullptr) { + error = MEMALLOC; + } +#endif +} + +simdjson_inline document_stream::document_stream() noexcept + : parser{nullptr}, + buf{nullptr}, + len{0}, + batch_size{0}, + allow_comma_separated{false}, + error{UNINITIALIZED} + #ifdef SIMDJSON_THREADS_ENABLED + , use_thread(false) + #endif +{ +} + +simdjson_inline document_stream::~document_stream() noexcept +{ + #ifdef SIMDJSON_THREADS_ENABLED + worker.reset(); + #endif +} + +inline size_t document_stream::size_in_bytes() const noexcept { + return len; +} + +inline size_t document_stream::truncated_bytes() const noexcept { + if(error == CAPACITY) { return len - batch_start; } + return parser->implementation->structural_indexes[parser->implementation->n_structural_indexes] - parser->implementation->structural_indexes[parser->implementation->n_structural_indexes + 1]; +} + +simdjson_inline document_stream::iterator::iterator() noexcept + : stream{nullptr}, finished{true} { +} + +simdjson_inline document_stream::iterator::iterator(document_stream* _stream, bool is_end) noexcept + : stream{_stream}, finished{is_end} { +} + +simdjson_inline simdjson_result document_stream::iterator::operator*() noexcept { + //if(stream->error) { return stream->error; } + return simdjson_result(stream->doc, stream->error); +} + +simdjson_inline document_stream::iterator& document_stream::iterator::operator++() noexcept { + // If there is an error, then we want the iterator + // to be finished, no matter what. (E.g., we do not + // keep generating documents with errors, or go beyond + // a document with errors.) + // + // Users do not have to call "operator*()" when they use operator++, + // so we need to end the stream in the operator++ function. + // + // Note that setting finished = true is essential otherwise + // we would enter an infinite loop. + if (stream->error) { finished = true; } + // Note that stream->error() is guarded against error conditions + // (it will immediately return if stream->error casts to false). + // In effect, this next function does nothing when (stream->error) + // is true (hence the risk of an infinite loop). + stream->next(); + // If that was the last document, we're finished. + // It is the only type of error we do not want to appear + // in operator*. + if (stream->error == EMPTY) { finished = true; } + // If we had any other kind of error (not EMPTY) then we want + // to pass it along to the operator* and we cannot mark the result + // as "finished" just yet. + return *this; +} + +simdjson_inline bool document_stream::iterator::operator!=(const document_stream::iterator &other) const noexcept { + return finished != other.finished; +} + +simdjson_inline document_stream::iterator document_stream::begin() noexcept { + start(); + // If there are no documents, we're finished. + return iterator(this, error == EMPTY); +} + +simdjson_inline document_stream::iterator document_stream::end() noexcept { + return iterator(this, true); +} + +inline void document_stream::start() noexcept { + if (error) { return; } + error = parser->allocate(batch_size); + if (error) { return; } + // Always run the first stage 1 parse immediately + batch_start = 0; + error = run_stage1(*parser, batch_start); + while(error == EMPTY) { + // In exceptional cases, we may start with an empty block + batch_start = next_batch_start(); + if (batch_start >= len) { return; } + error = run_stage1(*parser, batch_start); + } + if (error) { return; } + doc_index = batch_start; + doc = document(json_iterator(&buf[batch_start], parser)); + doc.iter._streaming = true; + + #ifdef SIMDJSON_THREADS_ENABLED + if (use_thread && next_batch_start() < len) { + // Kick off the first thread on next batch if needed + error = stage1_thread_parser.allocate(batch_size); + if (error) { return; } + worker->start_thread(); + start_stage1_thread(); + if (error) { return; } + } + #endif // SIMDJSON_THREADS_ENABLED +} + +inline void document_stream::next() noexcept { + // We always enter at once once in an error condition. + if (error) { return; } + next_document(); + if (error) { return; } + auto cur_struct_index = doc.iter._root - parser->implementation->structural_indexes.get(); + doc_index = batch_start + parser->implementation->structural_indexes[cur_struct_index]; + + // Check if at end of structural indexes (i.e. at end of batch) + if(cur_struct_index >= static_cast(parser->implementation->n_structural_indexes)) { + error = EMPTY; + // Load another batch (if available) + while (error == EMPTY) { + batch_start = next_batch_start(); + if (batch_start >= len) { break; } + #ifdef SIMDJSON_THREADS_ENABLED + if(use_thread) { + load_from_stage1_thread(); + } else { + error = run_stage1(*parser, batch_start); + } + #else + error = run_stage1(*parser, batch_start); + #endif + /** + * Whenever we move to another window, we need to update all pointers to make + * it appear as if the input buffer started at the beginning of the window. + * + * Take this input: + * + * {"z":5} {"1":1,"2":2,"4":4} [7, 10, 9] [15, 11, 12, 13] [154, 110, 112, 1311] + * + * Say you process the following window... + * + * '{"z":5} {"1":1,"2":2,"4":4} [7, 10, 9]' + * + * When you do so, the json_iterator has a pointer at the beginning of the memory region + * (pointing at the beginning of '{"z"...'. + * + * When you move to the window that starts at... + * + * '[7, 10, 9] [15, 11, 12, 13] ... + * + * then it is not sufficient to just run stage 1. You also need to re-anchor the + * json_iterator so that it believes we are starting at '[7, 10, 9]...'. + * + * Under the DOM front-end, this gets done automatically because the parser owns + * the pointer the data, and when you call stage1 and then stage2 on the same + * parser, then stage2 will run on the pointer acquired by stage1. + * + * That is, stage1 calls "this->buf = _buf" so the parser remembers the buffer that + * we used. But json_iterator has no callback when stage1 is called on the parser. + * In fact, I think that the parser is unaware of json_iterator. + * + * + * So we need to re-anchor the json_iterator after each call to stage 1 so that + * all of the pointers are in sync. + */ + doc.iter = json_iterator(&buf[batch_start], parser); + doc.iter._streaming = true; + /** + * End of resync. + */ + + if (error) { continue; } // If the error was EMPTY, we may want to load another batch. + doc_index = batch_start; + } + } +} + +inline void document_stream::next_document() noexcept { + // Go to next place where depth=0 (document depth) + error = doc.iter.skip_child(0); + if (error) { return; } + // Always set depth=1 at the start of document + doc.iter._depth = 1; + // consume comma if comma separated is allowed + if (allow_comma_separated) { doc.iter.consume_character(','); } + // Resets the string buffer at the beginning, thus invalidating the strings. + doc.iter._string_buf_loc = parser->string_buf.get(); + doc.iter._root = doc.iter.position(); +} + +inline size_t document_stream::next_batch_start() const noexcept { + return batch_start + parser->implementation->structural_indexes[parser->implementation->n_structural_indexes]; +} + +inline error_code document_stream::run_stage1(ondemand::parser &p, size_t _batch_start) noexcept { + // This code only updates the structural index in the parser, it does not update any json_iterator + // instance. + size_t remaining = len - _batch_start; + if (remaining <= batch_size) { + return p.implementation->stage1(&buf[_batch_start], remaining, stage1_mode::streaming_final); + } else { + return p.implementation->stage1(&buf[_batch_start], batch_size, stage1_mode::streaming_partial); + } +} + +simdjson_inline size_t document_stream::iterator::current_index() const noexcept { + return stream->doc_index; +} + +simdjson_inline std::string_view document_stream::iterator::source() const noexcept { + auto depth = stream->doc.iter.depth(); + auto cur_struct_index = stream->doc.iter._root - stream->parser->implementation->structural_indexes.get(); + + // If at root, process the first token to determine if scalar value + if (stream->doc.iter.at_root()) { + switch (stream->buf[stream->batch_start + stream->parser->implementation->structural_indexes[cur_struct_index]]) { + case '{': case '[': // Depth=1 already at start of document + break; + case '}': case ']': + depth--; + break; + default: // Scalar value document + // TODO: Remove any trailing whitespaces + // This returns a string spanning from start of value to the beginning of the next document (excluded) + return std::string_view(reinterpret_cast(stream->buf) + current_index(), stream->parser->implementation->structural_indexes[++cur_struct_index] - current_index() - 1); + } + cur_struct_index++; + } + + while (cur_struct_index <= static_cast(stream->parser->implementation->n_structural_indexes)) { + switch (stream->buf[stream->batch_start + stream->parser->implementation->structural_indexes[cur_struct_index]]) { + case '{': case '[': + depth++; + break; + case '}': case ']': + depth--; + break; + } + if (depth == 0) { break; } + cur_struct_index++; + } + + return std::string_view(reinterpret_cast(stream->buf) + current_index(), stream->parser->implementation->structural_indexes[cur_struct_index] - current_index() + stream->batch_start + 1);; +} + +inline error_code document_stream::iterator::error() const noexcept { + return stream->error; +} + +#ifdef SIMDJSON_THREADS_ENABLED + +inline void document_stream::load_from_stage1_thread() noexcept { + worker->finish(); + // Swap to the parser that was loaded up in the thread. Make sure the parser has + // enough memory to swap to, as well. + std::swap(stage1_thread_parser,*parser); + error = stage1_thread_error; + if (error) { return; } + + // If there's anything left, start the stage 1 thread! + if (next_batch_start() < len) { + start_stage1_thread(); + } +} + +inline void document_stream::start_stage1_thread() noexcept { + // we call the thread on a lambda that will update + // this->stage1_thread_error + // there is only one thread that may write to this value + // TODO this is NOT exception-safe. + this->stage1_thread_error = UNINITIALIZED; // In case something goes wrong, make sure it's an error + size_t _next_batch_start = this->next_batch_start(); + + worker->run(this, & this->stage1_thread_parser, _next_batch_start); +} + +#endif // SIMDJSON_THREADS_ENABLED + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} +simdjson_inline simdjson_result::simdjson_result( + fallback::ondemand::document_stream &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} + +} + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H +/* end file simdjson/generic/ondemand/document_stream-inl.h for fallback */ +/* including simdjson/generic/ondemand/field-inl.h for fallback: #include "simdjson/generic/ondemand/field-inl.h" */ +/* begin file simdjson/generic/ondemand/field-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +// clang 6 doesn't think the default constructor can be noexcept, so we make it explicit +simdjson_inline field::field() noexcept : std::pair() {} + +simdjson_inline field::field(raw_json_string key, ondemand::value &&value) noexcept + : std::pair(key, std::forward(value)) +{ +} + +simdjson_inline simdjson_result field::start(value_iterator &parent_iter) noexcept { + raw_json_string key; + SIMDJSON_TRY( parent_iter.field_key().get(key) ); + SIMDJSON_TRY( parent_iter.field_value() ); + return field::start(parent_iter, key); +} + +simdjson_inline simdjson_result field::start(const value_iterator &parent_iter, raw_json_string key) noexcept { + return field(key, parent_iter.child()); +} + +simdjson_inline simdjson_warn_unused simdjson_result field::unescaped_key(bool allow_replacement) noexcept { + SIMDJSON_ASSUME(first.buf != nullptr); // We would like to call .alive() but Visual Studio won't let us. + simdjson_result answer = first.unescape(second.iter.json_iter(), allow_replacement); + first.consume(); + return answer; +} + +simdjson_inline raw_json_string field::key() const noexcept { + SIMDJSON_ASSUME(first.buf != nullptr); // We would like to call .alive() by Visual Studio won't let us. + return first; +} + +simdjson_inline value &field::value() & noexcept { + return second; +} + +simdjson_inline value field::value() && noexcept { + return std::forward(*this).second; +} + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + fallback::ondemand::field &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} + +simdjson_inline simdjson_result simdjson_result::key() noexcept { + if (error()) { return error(); } + return first.key(); +} +simdjson_inline simdjson_result simdjson_result::unescaped_key(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.unescaped_key(allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::value() noexcept { + if (error()) { return error(); } + return std::move(first.value()); +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H +/* end file simdjson/generic/ondemand/field-inl.h for fallback */ +/* including simdjson/generic/ondemand/json_iterator-inl.h for fallback: #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/json_iterator-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +simdjson_inline json_iterator::json_iterator(json_iterator &&other) noexcept + : token(std::forward(other.token)), + parser{other.parser}, + _string_buf_loc{other._string_buf_loc}, + error{other.error}, + _depth{other._depth}, + _root{other._root}, + _streaming{other._streaming} +{ + other.parser = nullptr; +} +simdjson_inline json_iterator &json_iterator::operator=(json_iterator &&other) noexcept { + token = other.token; + parser = other.parser; + _string_buf_loc = other._string_buf_loc; + error = other.error; + _depth = other._depth; + _root = other._root; + _streaming = other._streaming; + other.parser = nullptr; + return *this; +} + +simdjson_inline json_iterator::json_iterator(const uint8_t *buf, ondemand::parser *_parser) noexcept + : token(buf, &_parser->implementation->structural_indexes[0]), + parser{_parser}, + _string_buf_loc{parser->string_buf.get()}, + _depth{1}, + _root{parser->implementation->structural_indexes.get()}, + _streaming{false} + +{ + logger::log_headers(); +#if SIMDJSON_CHECK_EOF + assert_more_tokens(); +#endif +} + +inline void json_iterator::rewind() noexcept { + token.set_position( root_position() ); + logger::log_headers(); // We start again + _string_buf_loc = parser->string_buf.get(); + _depth = 1; +} + +inline bool json_iterator::balanced() const noexcept { + token_iterator ti(token); + int32_t count{0}; + ti.set_position( root_position() ); + while(ti.peek() <= peek_last()) { + switch (*ti.return_current_and_advance()) + { + case '[': case '{': + count++; + break; + case ']': case '}': + count--; + break; + default: + break; + } + } + return count == 0; +} + + +// GCC 7 warns when the first line of this function is inlined away into oblivion due to the caller +// relating depth and parent_depth, which is a desired effect. The warning does not show up if the +// skip_child() function is not marked inline). +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_warn_unused simdjson_inline error_code json_iterator::skip_child(depth_t parent_depth) noexcept { + if (depth() <= parent_depth) { return SUCCESS; } + switch (*return_current_and_advance()) { + // TODO consider whether matching braces is a requirement: if non-matching braces indicates + // *missing* braces, then future lookups are not in the object/arrays they think they are, + // violating the rule "validate enough structure that the user can be confident they are + // looking at the right values." + // PERF TODO we can eliminate the switch here with a lookup of how much to add to depth + + // For the first open array/object in a value, we've already incremented depth, so keep it the same + // We never stop at colon, but if we did, it wouldn't affect depth + case '[': case '{': case ':': + logger::log_start_value(*this, "skip"); + break; + // If there is a comma, we have just finished a value in an array/object, and need to get back in + case ',': + logger::log_value(*this, "skip"); + break; + // ] or } means we just finished a value and need to jump out of the array/object + case ']': case '}': + logger::log_end_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } +#if SIMDJSON_CHECK_EOF + // If there are no more tokens, the parent is incomplete. + if (at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "Missing [ or { at start"); } +#endif // SIMDJSON_CHECK_EOF + break; + case '"': + if(*peek() == ':') { + // We are at a key!!! + // This might happen if you just started an object and you skip it immediately. + // Performance note: it would be nice to get rid of this check as it is somewhat + // expensive. + // https://github.com/simdjson/simdjson/issues/1742 + logger::log_value(*this, "key"); + return_current_and_advance(); // eat up the ':' + break; // important!!! + } + simdjson_fallthrough; + // Anything else must be a scalar value + default: + // For the first scalar, we will have incremented depth already, so we decrement it here. + logger::log_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } + break; + } + + // Now that we've considered the first value, we only increment/decrement for arrays/objects + while (position() < end_position()) { + switch (*return_current_and_advance()) { + case '[': case '{': + logger::log_start_value(*this, "skip"); + _depth++; + break; + // TODO consider whether matching braces is a requirement: if non-matching braces indicates + // *missing* braces, then future lookups are not in the object/arrays they think they are, + // violating the rule "validate enough structure that the user can be confident they are + // looking at the right values." + // PERF TODO we can eliminate the switch here with a lookup of how much to add to depth + case ']': case '}': + logger::log_end_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } + break; + default: + logger::log_value(*this, "skip", ""); + break; + } + } + + return report_error(TAPE_ERROR, "not enough close braces"); +} + +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline bool json_iterator::at_root() const noexcept { + return position() == root_position(); +} + +simdjson_inline bool json_iterator::is_single_token() const noexcept { + return parser->implementation->n_structural_indexes == 1; +} + +simdjson_inline bool json_iterator::streaming() const noexcept { + return _streaming; +} + +simdjson_inline token_position json_iterator::root_position() const noexcept { + return _root; +} + +simdjson_inline void json_iterator::assert_at_document_depth() const noexcept { + SIMDJSON_ASSUME( _depth == 1 ); +} + +simdjson_inline void json_iterator::assert_at_root() const noexcept { + SIMDJSON_ASSUME( _depth == 1 ); +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + // Under Visual Studio, the next SIMDJSON_ASSUME fails with: the argument + // has side effects that will be discarded. + SIMDJSON_ASSUME( token.position() == _root ); +#endif +} + +simdjson_inline void json_iterator::assert_more_tokens(uint32_t required_tokens) const noexcept { + assert_valid_position(token._position + required_tokens - 1); +} + +simdjson_inline void json_iterator::assert_valid_position(token_position position) const noexcept { +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + SIMDJSON_ASSUME( position >= &parser->implementation->structural_indexes[0] ); + SIMDJSON_ASSUME( position < &parser->implementation->structural_indexes[parser->implementation->n_structural_indexes] ); +#endif +} + +simdjson_inline bool json_iterator::at_end() const noexcept { + return position() == end_position(); +} +simdjson_inline token_position json_iterator::end_position() const noexcept { + uint32_t n_structural_indexes{parser->implementation->n_structural_indexes}; + return &parser->implementation->structural_indexes[n_structural_indexes]; +} + +inline std::string json_iterator::to_string() const noexcept { + if( !is_alive() ) { return "dead json_iterator instance"; } + const char * current_structural = reinterpret_cast(token.peek()); + return std::string("json_iterator [ depth : ") + std::to_string(_depth) + + std::string(", structural : '") + std::string(current_structural,1) + + std::string("', offset : ") + std::to_string(token.current_offset()) + + std::string("', error : ") + error_message(error) + + std::string(" ]"); +} + +inline simdjson_result json_iterator::current_location() const noexcept { + if (!is_alive()) { // Unrecoverable error + if (!at_root()) { + return reinterpret_cast(token.peek(-1)); + } else { + return reinterpret_cast(token.peek()); + } + } + if (at_end()) { + return OUT_OF_BOUNDS; + } + return reinterpret_cast(token.peek()); +} + +simdjson_inline bool json_iterator::is_alive() const noexcept { + return parser; +} + +simdjson_inline void json_iterator::abandon() noexcept { + parser = nullptr; + _depth = 0; +} + +simdjson_inline const uint8_t *json_iterator::return_current_and_advance() noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(); +#endif // SIMDJSON_CHECK_EOF + return token.return_current_and_advance(); +} + +simdjson_inline const uint8_t *json_iterator::unsafe_pointer() const noexcept { + // deliberately done without safety guard: + return token.peek(); +} + +simdjson_inline const uint8_t *json_iterator::peek(int32_t delta) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(delta+1); +#endif // SIMDJSON_CHECK_EOF + return token.peek(delta); +} + +simdjson_inline uint32_t json_iterator::peek_length(int32_t delta) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(delta+1); +#endif // #if SIMDJSON_CHECK_EOF + return token.peek_length(delta); +} + +simdjson_inline const uint8_t *json_iterator::peek(token_position position) const noexcept { + // todo: currently we require end-of-string buffering, but the following + // assert_valid_position should be turned on if/when we lift that condition. + // assert_valid_position(position); + // This is almost surely related to SIMDJSON_CHECK_EOF but given that SIMDJSON_CHECK_EOF + // is ON by default, we have no choice but to disable it for real with a comment. + return token.peek(position); +} + +simdjson_inline uint32_t json_iterator::peek_length(token_position position) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_valid_position(position); +#endif // SIMDJSON_CHECK_EOF + return token.peek_length(position); +} + +simdjson_inline token_position json_iterator::last_position() const noexcept { + // The following line fails under some compilers... + // SIMDJSON_ASSUME(parser->implementation->n_structural_indexes > 0); + // since it has side-effects. + uint32_t n_structural_indexes{parser->implementation->n_structural_indexes}; + SIMDJSON_ASSUME(n_structural_indexes > 0); + return &parser->implementation->structural_indexes[n_structural_indexes - 1]; +} +simdjson_inline const uint8_t *json_iterator::peek_last() const noexcept { + return token.peek(last_position()); +} + +simdjson_inline void json_iterator::ascend_to(depth_t parent_depth) noexcept { + SIMDJSON_ASSUME(parent_depth >= 0 && parent_depth < INT32_MAX - 1); + SIMDJSON_ASSUME(_depth == parent_depth + 1); + _depth = parent_depth; +} + +simdjson_inline void json_iterator::descend_to(depth_t child_depth) noexcept { + SIMDJSON_ASSUME(child_depth >= 1 && child_depth < INT32_MAX); + SIMDJSON_ASSUME(_depth == child_depth - 1); + _depth = child_depth; +} + +simdjson_inline depth_t json_iterator::depth() const noexcept { + return _depth; +} + +simdjson_inline uint8_t *&json_iterator::string_buf_loc() noexcept { + return _string_buf_loc; +} + +simdjson_inline error_code json_iterator::report_error(error_code _error, const char *message) noexcept { + SIMDJSON_ASSUME(_error != SUCCESS && _error != UNINITIALIZED && _error != INCORRECT_TYPE && _error != NO_SUCH_FIELD); + logger::log_error(*this, message); + error = _error; + return error; +} + +simdjson_inline token_position json_iterator::position() const noexcept { + return token.position(); +} + +simdjson_inline simdjson_result json_iterator::unescape(raw_json_string in, bool allow_replacement) noexcept { + return parser->unescape(in, _string_buf_loc, allow_replacement); +} + +simdjson_inline simdjson_result json_iterator::unescape_wobbly(raw_json_string in) noexcept { + return parser->unescape_wobbly(in, _string_buf_loc); +} + +simdjson_inline void json_iterator::reenter_child(token_position position, depth_t child_depth) noexcept { + SIMDJSON_ASSUME(child_depth >= 1 && child_depth < INT32_MAX); + SIMDJSON_ASSUME(_depth == child_depth - 1); +#if SIMDJSON_DEVELOPMENT_CHECKS +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + SIMDJSON_ASSUME(size_t(child_depth) < parser->max_depth()); + SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]); +#endif +#endif + token.set_position(position); + _depth = child_depth; +} + +simdjson_inline error_code json_iterator::consume_character(char c) noexcept { + if (*peek() == c) { + return_current_and_advance(); + return SUCCESS; + } + return TAPE_ERROR; +} + +#if SIMDJSON_DEVELOPMENT_CHECKS + +simdjson_inline token_position json_iterator::start_position(depth_t depth) const noexcept { + SIMDJSON_ASSUME(size_t(depth) < parser->max_depth()); + return size_t(depth) < parser->max_depth() ? parser->start_positions[depth] : 0; +} + +simdjson_inline void json_iterator::set_start_position(depth_t depth, token_position position) noexcept { + SIMDJSON_ASSUME(size_t(depth) < parser->max_depth()); + if(size_t(depth) < parser->max_depth()) { parser->start_positions[depth] = position; } +} + +#endif + + +simdjson_inline error_code json_iterator::optional_error(error_code _error, const char *message) noexcept { + SIMDJSON_ASSUME(_error == INCORRECT_TYPE || _error == NO_SUCH_FIELD); + logger::log_error(*this, message); + return _error; +} + + +simdjson_warn_unused simdjson_inline bool json_iterator::copy_to_buffer(const uint8_t *json, uint32_t max_len, uint8_t *tmpbuf, size_t N) noexcept { + // This function is not expected to be called in performance-sensitive settings. + // Let us guard against silly cases: + if((N < max_len) || (N == 0)) { return false; } + // Copy to the buffer. + std::memcpy(tmpbuf, json, max_len); + if(N > max_len) { // We pad whatever remains with ' '. + std::memset(tmpbuf + max_len, ' ', N - max_len); + } + return true; +} + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(fallback::ondemand::json_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/json_iterator-inl.h for fallback */ +/* including simdjson/generic/ondemand/json_type-inl.h for fallback: #include "simdjson/generic/ondemand/json_type-inl.h" */ +/* begin file simdjson/generic/ondemand/json_type-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +inline std::ostream& operator<<(std::ostream& out, json_type type) noexcept { + switch (type) { + case json_type::array: out << "array"; break; + case json_type::object: out << "object"; break; + case json_type::number: out << "number"; break; + case json_type::string: out << "string"; break; + case json_type::boolean: out << "boolean"; break; + case json_type::null: out << "null"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson_result &type) noexcept(false) { + return out << type.value(); +} +#endif + + + +simdjson_inline number_type number::get_number_type() const noexcept { + return type; +} + +simdjson_inline bool number::is_uint64() const noexcept { + return get_number_type() == number_type::unsigned_integer; +} + +simdjson_inline uint64_t number::get_uint64() const noexcept { + return payload.unsigned_integer; +} + +simdjson_inline number::operator uint64_t() const noexcept { + return get_uint64(); +} + + +simdjson_inline bool number::is_int64() const noexcept { + return get_number_type() == number_type::signed_integer; +} + +simdjson_inline int64_t number::get_int64() const noexcept { + return payload.signed_integer; +} + +simdjson_inline number::operator int64_t() const noexcept { + return get_int64(); +} + +simdjson_inline bool number::is_double() const noexcept { + return get_number_type() == number_type::floating_point_number; +} + +simdjson_inline double number::get_double() const noexcept { + return payload.floating_point_number; +} + +simdjson_inline number::operator double() const noexcept { + return get_double(); +} + +simdjson_inline double number::as_double() const noexcept { + if(is_double()) { + return payload.floating_point_number; + } + if(is_int64()) { + return double(payload.signed_integer); + } + return double(payload.unsigned_integer); +} + +simdjson_inline void number::append_s64(int64_t value) noexcept { + payload.signed_integer = value; + type = number_type::signed_integer; +} + +simdjson_inline void number::append_u64(uint64_t value) noexcept { + payload.unsigned_integer = value; + type = number_type::unsigned_integer; +} + +simdjson_inline void number::append_double(double value) noexcept { + payload.floating_point_number = value; + type = number_type::floating_point_number; +} + +simdjson_inline void number::skip_double() noexcept { + type = number_type::floating_point_number; +} + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(fallback::ondemand::json_type &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H +/* end file simdjson/generic/ondemand/json_type-inl.h for fallback */ +/* including simdjson/generic/ondemand/logger-inl.h for fallback: #include "simdjson/generic/ondemand/logger-inl.h" */ +/* begin file simdjson/generic/ondemand/logger-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include + +namespace simdjson { +namespace fallback { +namespace ondemand { +namespace logger { + +static constexpr const char * DASHES = "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"; +static constexpr const int LOG_EVENT_LEN = 20; +static constexpr const int LOG_BUFFER_LEN = 30; +static constexpr const int LOG_SMALL_BUFFER_LEN = 10; +static int log_depth = 0; // Not threadsafe. Log only. + +// Helper to turn unprintable or newline characters into spaces +static inline char printable_char(char c) { + if (c >= 0x20) { + return c; + } else { + return ' '; + } +} + +template +static inline std::string string_format(const std::string& format, const Args&... args) +{ + SIMDJSON_PUSH_DISABLE_ALL_WARNINGS + int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; + auto size = static_cast(size_s); + if (size <= 0) return std::string(); + std::unique_ptr buf(new char[size]); + std::snprintf(buf.get(), size, format.c_str(), args...); + SIMDJSON_POP_DISABLE_WARNINGS + return std::string(buf.get(), buf.get() + size - 1); +} + +static inline log_level get_log_level_from_env() +{ + SIMDJSON_PUSH_DISABLE_WARNINGS + SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe + char *lvl = getenv("SIMDJSON_LOG_LEVEL"); + SIMDJSON_POP_DISABLE_WARNINGS + if (lvl && simdjson_strcasecmp(lvl, "ERROR") == 0) { return log_level::error; } + return log_level::info; +} + +static inline log_level log_threshold() +{ + static log_level threshold = get_log_level_from_env(); + return threshold; +} + +static inline bool should_log(log_level level) +{ + return level >= log_threshold(); +} + +inline void log_event(const json_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_line(iter, "", type, detail, delta, depth_delta, log_level::info); +} + +inline void log_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail) noexcept { + log_line(iter, index, depth, "", type, detail, log_level::info); +} +inline void log_value(const json_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_line(iter, "", type, detail, delta, depth_delta, log_level::info); +} + +inline void log_start_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail) noexcept { + log_line(iter, index, depth, "+", type, detail, log_level::info); + if (LOG_ENABLED) { log_depth++; } +} +inline void log_start_value(const json_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_line(iter, "+", type, "", delta, depth_delta, log_level::info); + if (LOG_ENABLED) { log_depth++; } +} + +inline void log_end_value(const json_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + if (LOG_ENABLED) { log_depth--; } + log_line(iter, "-", type, "", delta, depth_delta, log_level::info); +} + +inline void log_error(const json_iterator &iter, const char *error, const char *detail, int delta, int depth_delta) noexcept { + log_line(iter, "ERROR: ", error, detail, delta, depth_delta, log_level::error); +} +inline void log_error(const json_iterator &iter, token_position index, depth_t depth, const char *error, const char *detail) noexcept { + log_line(iter, index, depth, "ERROR: ", error, detail, log_level::error); +} + +inline void log_event(const value_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_event(iter.json_iter(), type, detail, delta, depth_delta); +} + +inline void log_value(const value_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_value(iter.json_iter(), type, detail, delta, depth_delta); +} + +inline void log_start_value(const value_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_start_value(iter.json_iter(), type, delta, depth_delta); +} + +inline void log_end_value(const value_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_end_value(iter.json_iter(), type, delta, depth_delta); +} + +inline void log_error(const value_iterator &iter, const char *error, const char *detail, int delta, int depth_delta) noexcept { + log_error(iter.json_iter(), error, detail, delta, depth_delta); +} + +inline void log_headers() noexcept { + if (LOG_ENABLED) { + if (simdjson_unlikely(should_log(log_level::info))) { + // Technically a static variable is not thread-safe, but if you are using threads and logging... well... + static bool displayed_hint{false}; + log_depth = 0; + printf("\n"); + if (!displayed_hint) { + // We only print this helpful header once. + printf("# Logging provides the depth and position of the iterator user-visible steps:\n"); + printf("# +array says 'this is where we were when we discovered the start array'\n"); + printf( + "# -array says 'this is where we were when we ended the array'\n"); + printf("# skip says 'this is a structural or value I am skipping'\n"); + printf("# +/-skip says 'this is a start/end array or object I am skipping'\n"); + printf("#\n"); + printf("# The indentation of the terms (array, string,...) indicates the depth,\n"); + printf("# in addition to the depth being displayed.\n"); + printf("#\n"); + printf("# Every token in the document has a single depth determined by the tokens before it,\n"); + printf("# and is not affected by what the token actually is.\n"); + printf("#\n"); + printf("# Not all structural elements are presented as tokens in the logs.\n"); + printf("#\n"); + printf("# We never give control to the user within an empty array or an empty object.\n"); + printf("#\n"); + printf("# Inside an array, having a depth greater than the array's depth means that\n"); + printf("# we are pointing inside a value.\n"); + printf("# Having a depth equal to the array means that we are pointing right before a value.\n"); + printf("# Having a depth smaller than the array means that we have moved beyond the array.\n"); + displayed_hint = true; + } + printf("\n"); + printf("| %-*s ", LOG_EVENT_LEN, "Event"); + printf("| %-*s ", LOG_BUFFER_LEN, "Buffer"); + printf("| %-*s ", LOG_SMALL_BUFFER_LEN, "Next"); + // printf("| %-*s ", 5, "Next#"); + printf("| %-*s ", 5, "Depth"); + printf("| Detail "); + printf("|\n"); + + printf("|%.*s", LOG_EVENT_LEN + 2, DASHES); + printf("|%.*s", LOG_BUFFER_LEN + 2, DASHES); + printf("|%.*s", LOG_SMALL_BUFFER_LEN + 2, DASHES); + // printf("|%.*s", 5+2, DASHES); + printf("|%.*s", 5 + 2, DASHES); + printf("|--------"); + printf("|\n"); + fflush(stdout); + } + } +} + +template +inline void log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, log_level level, Args&&... args) noexcept { + log_line(iter, iter.position()+delta, depth_t(iter.depth()+depth_delta), title_prefix, title, detail, level, std::forward(args)...); +} + +template +inline void log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, log_level level, Args&&... args) noexcept { + if (LOG_ENABLED) { + if (simdjson_unlikely(should_log(level))) { + const int indent = depth * 2; + const auto buf = iter.token.buf; + auto msg = string_format(title, std::forward(args)...); + printf("| %*s%s%-*s ", indent, "", title_prefix, + LOG_EVENT_LEN - indent - int(strlen(title_prefix)), msg.c_str()); + { + // Print the current structural. + printf("| "); + // Before we begin, the index might point right before the document. + // This could be unsafe, see https://github.com/simdjson/simdjson/discussions/1938 + if (index < iter._root) { + printf("%*s", LOG_BUFFER_LEN, ""); + } else { + auto current_structural = &buf[*index]; + for (int i = 0; i < LOG_BUFFER_LEN; i++) { + printf("%c", printable_char(current_structural[i])); + } + } + printf(" "); + } + { + // Print the next structural. + printf("| "); + auto next_structural = &buf[*(index + 1)]; + for (int i = 0; i < LOG_SMALL_BUFFER_LEN; i++) { + printf("%c", printable_char(next_structural[i])); + } + printf(" "); + } + // printf("| %5u ", *(index+1)); + printf("| %5i ", depth); + printf("| %6.*s ", int(detail.size()), detail.data()); + printf("|\n"); + fflush(stdout); + } + } +} + +} // namespace logger +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H +/* end file simdjson/generic/ondemand/logger-inl.h for fallback */ +/* including simdjson/generic/ondemand/object-inl.h for fallback: #include "simdjson/generic/ondemand/object-inl.h" */ +/* begin file simdjson/generic/ondemand/object-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +simdjson_inline simdjson_result object::find_field_unordered(const std::string_view key) & noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::find_field_unordered(const std::string_view key) && noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::operator[](const std::string_view key) & noexcept { + return find_field_unordered(key); +} +simdjson_inline simdjson_result object::operator[](const std::string_view key) && noexcept { + return std::forward(*this).find_field_unordered(key); +} +simdjson_inline simdjson_result object::find_field(const std::string_view key) & noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::find_field(const std::string_view key) && noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} + +simdjson_inline simdjson_result object::start(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.start_object().error() ); + return object(iter); +} +simdjson_inline simdjson_result object::start_root(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.start_root_object().error() ); + return object(iter); +} +simdjson_inline error_code object::consume() noexcept { + if(iter.is_at_key()) { + /** + * whenever you are pointing at a key, calling skip_child() is + * unsafe because you will hit a string and you will assume that + * it is string value, and this mistake will lead you to make bad + * depth computation. + */ + /** + * We want to 'consume' the key. We could really + * just do _json_iter->return_current_and_advance(); at this + * point, but, for clarity, we will use the high-level API to + * eat the key. We assume that the compiler optimizes away + * most of the work. + */ + simdjson_unused raw_json_string actual_key; + auto error = iter.field_key().get(actual_key); + if (error) { iter.abandon(); return error; }; + // Let us move to the value while we are at it. + if ((error = iter.field_value())) { iter.abandon(); return error; } + } + auto error_skip = iter.json_iter().skip_child(iter.depth()-1); + if(error_skip) { iter.abandon(); } + return error_skip; +} + +simdjson_inline simdjson_result object::raw_json() noexcept { + const uint8_t * starting_point{iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + const uint8_t * final_point{iter._json_iter->peek()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +simdjson_inline simdjson_result object::started(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.started_object().error() ); + return object(iter); +} + +simdjson_inline object object::resume(const value_iterator &iter) noexcept { + return iter; +} + +simdjson_inline object::object(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} + +simdjson_inline simdjson_result object::begin() noexcept { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + return object_iterator(iter); +} +simdjson_inline simdjson_result object::end() noexcept { + return object_iterator(iter); +} + +inline simdjson_result object::at_pointer(std::string_view json_pointer) noexcept { + if (json_pointer[0] != '/') { return INVALID_JSON_POINTER; } + json_pointer = json_pointer.substr(1); + size_t slash = json_pointer.find('/'); + std::string_view key = json_pointer.substr(0, slash); + // Grab the child with the given key + simdjson_result child; + + // If there is an escape character in the key, unescape it and then get the child. + size_t escape = key.find('~'); + if (escape != std::string_view::npos) { + // Unescape the key + std::string unescaped(key); + do { + switch (unescaped[escape+1]) { + case '0': + unescaped.replace(escape, 2, "~"); + break; + case '1': + unescaped.replace(escape, 2, "/"); + break; + default: + return INVALID_JSON_POINTER; // "Unexpected ~ escape character in JSON pointer"); + } + escape = unescaped.find('~', escape+1); + } while (escape != std::string::npos); + child = find_field(unescaped); // Take note find_field does not unescape keys when matching + } else { + child = find_field(key); + } + if(child.error()) { + return child; // we do not continue if there was an error + } + // If there is a /, we have to recurse and look up more of the path + if (slash != std::string_view::npos) { + child = child.at_pointer(json_pointer.substr(slash)); + } + return child; +} + +simdjson_inline simdjson_result object::count_fields() & noexcept { + size_t count{0}; + // Important: we do not consume any of the values. + for(simdjson_unused auto v : *this) { count++; } + // The above loop will always succeed, but we want to report errors. + if(iter.error()) { return iter.error(); } + // We need to move back at the start because we expect users to iterate through + // the object after counting the number of elements. + iter.reset_object(); + return count; +} + +simdjson_inline simdjson_result object::is_empty() & noexcept { + bool is_not_empty; + auto error = iter.reset_object().get(is_not_empty); + if(error) { return error; } + return !is_not_empty; +} + +simdjson_inline simdjson_result object::reset() & noexcept { + return iter.reset_object(); +} + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(fallback::ondemand::object &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +simdjson_inline simdjson_result simdjson_result::begin() noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() noexcept { + if (error()) { return error(); } + return first.end(); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first).find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first)[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first).find_field(key); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + +inline simdjson_result simdjson_result::reset() noexcept { + if (error()) { return error(); } + return first.reset(); +} + +inline simdjson_result simdjson_result::is_empty() noexcept { + if (error()) { return error(); } + return first.is_empty(); +} + +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H +/* end file simdjson/generic/ondemand/object-inl.h for fallback */ +/* including simdjson/generic/ondemand/object_iterator-inl.h for fallback: #include "simdjson/generic/ondemand/object_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/object_iterator-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +// +// object_iterator +// + +simdjson_inline object_iterator::object_iterator(const value_iterator &_iter) noexcept + : iter{_iter} +{} + +simdjson_inline simdjson_result object_iterator::operator*() noexcept { + error_code error = iter.error(); + if (error) { iter.abandon(); return error; } + auto result = field::start(iter); + // TODO this is a safety rail ... users should exit loops as soon as they receive an error. + // Nonetheless, let's see if performance is OK with this if statement--the compiler may give it to us for free. + if (result.error()) { iter.abandon(); } + return result; +} +simdjson_inline bool object_iterator::operator==(const object_iterator &other) const noexcept { + return !(*this != other); +} +simdjson_inline bool object_iterator::operator!=(const object_iterator &) const noexcept { + return iter.is_open(); +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline object_iterator &object_iterator::operator++() noexcept { + // TODO this is a safety rail ... users should exit loops as soon as they receive an error. + // Nonetheless, let's see if performance is OK with this if statement--the compiler may give it to us for free. + if (!iter.is_open()) { return *this; } // Iterator will be released if there is an error + + simdjson_unused error_code error; + if ((error = iter.skip_child() )) { return *this; } + + simdjson_unused bool has_value; + if ((error = iter.has_next_field().get(has_value) )) { return *this; }; + return *this; +} +SIMDJSON_POP_DISABLE_WARNINGS + +// +// ### Live States +// +// While iterating or looking up values, depth >= iter.depth. at_start may vary. Error is +// always SUCCESS: +// +// - Start: This is the state when the object is first found and the iterator is just past the {. +// In this state, at_start == true. +// - Next: After we hand a scalar value to the user, or an array/object which they then fully +// iterate over, the iterator is at the , or } before the next value. In this state, +// depth == iter.depth, at_start == false, and error == SUCCESS. +// - Unfinished Business: When we hand an array/object to the user which they do not fully +// iterate over, we need to finish that iteration by skipping child values until we reach the +// Next state. In this state, depth > iter.depth, at_start == false, and error == SUCCESS. +// +// ## Error States +// +// In error states, we will yield exactly one more value before stopping. iter.depth == depth +// and at_start is always false. We decrement after yielding the error, moving to the Finished +// state. +// +// - Chained Error: When the object iterator is part of an error chain--for example, in +// `for (auto tweet : doc["tweets"])`, where the tweet field may be missing or not be an +// object--we yield that error in the loop, exactly once. In this state, error != SUCCESS and +// iter.depth == depth, and at_start == false. We decrement depth when we yield the error. +// - Missing Comma Error: When the iterator ++ method discovers there is no comma between fields, +// we flag that as an error and treat it exactly the same as a Chained Error. In this state, +// error == TAPE_ERROR, iter.depth == depth, and at_start == false. +// +// Errors that occur while reading a field to give to the user (such as when the key is not a +// string or the field is missing a colon) are yielded immediately. Depth is then decremented, +// moving to the Finished state without transitioning through an Error state at all. +// +// ## Terminal State +// +// The terminal state has iter.depth < depth. at_start is always false. +// +// - Finished: When we have reached a }, we are finished. We signal this by decrementing depth. +// In this state, iter.depth < depth, at_start == false, and error == SUCCESS. +// + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + fallback::ondemand::object_iterator &&value +) noexcept + : implementation_simdjson_result_base(std::forward(value)) +{ + first.iter.assert_is_valid(); +} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base({}, error) +{ +} + +simdjson_inline simdjson_result simdjson_result::operator*() noexcept { + if (error()) { return error(); } + return *first; +} +// If we're iterating and there is an error, return the error once. +simdjson_inline bool simdjson_result::operator==(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return !error(); } + return first == other.first; +} +// If we're iterating and there is an error, return the error once. +simdjson_inline bool simdjson_result::operator!=(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return error(); } + return first != other.first; +} +// Checks for ']' and ',' +simdjson_inline simdjson_result &simdjson_result::operator++() noexcept { + // Clear the error if there is one, so we don't yield it twice + if (error()) { second = SUCCESS; return *this; } + ++first; + return *this; +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/object_iterator-inl.h for fallback */ +/* including simdjson/generic/ondemand/parser-inl.h for fallback: #include "simdjson/generic/ondemand/parser-inl.h" */ +/* begin file simdjson/generic/ondemand/parser-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/padded_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/padded_string_view.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/dom/base.h" // for MINIMAL_DOCUMENT_CAPACITY */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document_stream.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +simdjson_inline parser::parser(size_t max_capacity) noexcept + : _max_capacity{max_capacity} { +} + +simdjson_warn_unused simdjson_inline error_code parser::allocate(size_t new_capacity, size_t new_max_depth) noexcept { + if (new_capacity > max_capacity()) { return CAPACITY; } + if (string_buf && new_capacity == capacity() && new_max_depth == max_depth()) { return SUCCESS; } + + // string_capacity copied from document::allocate + _capacity = 0; + size_t string_capacity = SIMDJSON_ROUNDUP_N(5 * new_capacity / 3 + SIMDJSON_PADDING, 64); + string_buf.reset(new (std::nothrow) uint8_t[string_capacity]); +#if SIMDJSON_DEVELOPMENT_CHECKS + start_positions.reset(new (std::nothrow) token_position[new_max_depth]); +#endif + if (implementation) { + SIMDJSON_TRY( implementation->set_capacity(new_capacity) ); + SIMDJSON_TRY( implementation->set_max_depth(new_max_depth) ); + } else { + SIMDJSON_TRY( simdjson::get_active_implementation()->create_dom_parser_implementation(new_capacity, new_max_depth, implementation) ); + } + _capacity = new_capacity; + _max_depth = new_max_depth; + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(padded_string_view json) & noexcept { + if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; } + + json.remove_utf8_bom(); + + // Allocate if needed + if (capacity() < json.length() || !string_buf) { + SIMDJSON_TRY( allocate(json.length(), max_depth()) ); + } + + // Run stage 1. + SIMDJSON_TRY( implementation->stage1(reinterpret_cast(json.data()), json.length(), stage1_mode::regular) ); + return document::start({ reinterpret_cast(json.data()), this }); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const char *json, size_t len, size_t allocated) & noexcept { + return iterate(padded_string_view(json, len, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const uint8_t *json, size_t len, size_t allocated) & noexcept { + return iterate(padded_string_view(json, len, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(std::string_view json, size_t allocated) & noexcept { + return iterate(padded_string_view(json, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(std::string &json) & noexcept { + if(json.capacity() - json.size() < SIMDJSON_PADDING) { + json.reserve(json.size() + SIMDJSON_PADDING); + } + return iterate(padded_string_view(json)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const std::string &json) & noexcept { + return iterate(padded_string_view(json)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const simdjson_result &result) & noexcept { + // We don't presently have a way to temporarily get a const T& from a simdjson_result without throwing an exception + SIMDJSON_TRY( result.error() ); + padded_string_view json = result.value_unsafe(); + return iterate(json); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const simdjson_result &result) & noexcept { + // We don't presently have a way to temporarily get a const T& from a simdjson_result without throwing an exception + SIMDJSON_TRY( result.error() ); + const padded_string &json = result.value_unsafe(); + return iterate(json); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate_raw(padded_string_view json) & noexcept { + if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; } + + json.remove_utf8_bom(); + + // Allocate if needed + if (capacity() < json.length()) { + SIMDJSON_TRY( allocate(json.length(), max_depth()) ); + } + + // Run stage 1. + SIMDJSON_TRY( implementation->stage1(reinterpret_cast(json.data()), json.length(), stage1_mode::regular) ); + return json_iterator(reinterpret_cast(json.data()), this); +} + +inline simdjson_result parser::iterate_many(const uint8_t *buf, size_t len, size_t batch_size, bool allow_comma_separated) noexcept { + if(batch_size < MINIMAL_BATCH_SIZE) { batch_size = MINIMAL_BATCH_SIZE; } + if((len >= 3) && (std::memcmp(buf, "\xEF\xBB\xBF", 3) == 0)) { + buf += 3; + len -= 3; + } + if(allow_comma_separated && batch_size < len) { batch_size = len; } + return document_stream(*this, buf, len, batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const char *buf, size_t len, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(reinterpret_cast(buf), len, batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const std::string &s, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(s.data(), s.length(), batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const padded_string &s, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(s.data(), s.length(), batch_size, allow_comma_separated); +} + +simdjson_inline size_t parser::capacity() const noexcept { + return _capacity; +} +simdjson_inline size_t parser::max_capacity() const noexcept { + return _max_capacity; +} +simdjson_inline size_t parser::max_depth() const noexcept { + return _max_depth; +} + +simdjson_inline void parser::set_max_capacity(size_t max_capacity) noexcept { + if(max_capacity < dom::MINIMAL_DOCUMENT_CAPACITY) { + _max_capacity = max_capacity; + } else { + _max_capacity = dom::MINIMAL_DOCUMENT_CAPACITY; + } +} + +simdjson_inline simdjson_warn_unused simdjson_result parser::unescape(raw_json_string in, uint8_t *&dst, bool allow_replacement) const noexcept { + uint8_t *end = implementation->parse_string(in.buf, dst, allow_replacement); + if (!end) { return STRING_ERROR; } + std::string_view result(reinterpret_cast(dst), end-dst); + dst = end; + return result; +} + +simdjson_inline simdjson_warn_unused simdjson_result parser::unescape_wobbly(raw_json_string in, uint8_t *&dst) const noexcept { + uint8_t *end = implementation->parse_wobbly_string(in.buf, dst); + if (!end) { return STRING_ERROR; } + std::string_view result(reinterpret_cast(dst), end-dst); + dst = end; + return result; +} + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(fallback::ondemand::parser &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H +/* end file simdjson/generic/ondemand/parser-inl.h for fallback */ +/* including simdjson/generic/ondemand/raw_json_string-inl.h for fallback: #include "simdjson/generic/ondemand/raw_json_string-inl.h" */ +/* begin file simdjson/generic/ondemand/raw_json_string-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +namespace fallback { +namespace ondemand { + +simdjson_inline raw_json_string::raw_json_string(const uint8_t * _buf) noexcept : buf{_buf} {} + +simdjson_inline const char * raw_json_string::raw() const noexcept { return reinterpret_cast(buf); } + + +simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(std::string_view target) noexcept { + size_t pos{0}; + // if the content has no escape character, just scan through it quickly! + for(;pos < target.size() && target[pos] != '\\';pos++) {} + // slow path may begin. + bool escaping{false}; + for(;pos < target.size();pos++) { + if((target[pos] == '"') && !escaping) { + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + return true; +} + +simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(const char* target) noexcept { + size_t pos{0}; + // if the content has no escape character, just scan through it quickly! + for(;target[pos] && target[pos] != '\\';pos++) {} + // slow path may begin. + bool escaping{false}; + for(;target[pos];pos++) { + if((target[pos] == '"') && !escaping) { + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + return true; +} + + +simdjson_inline bool raw_json_string::unsafe_is_equal(size_t length, std::string_view target) const noexcept { + // If we are going to call memcmp, then we must know something about the length of the raw_json_string. + return (length >= target.size()) && (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size()); +} + +simdjson_inline bool raw_json_string::unsafe_is_equal(std::string_view target) const noexcept { + // Assumptions: does not contain unescaped quote characters, and + // the raw content is quote terminated within a valid JSON string. + if(target.size() <= SIMDJSON_PADDING) { + return (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size()); + } + const char * r{raw()}; + size_t pos{0}; + for(;pos < target.size();pos++) { + if(r[pos] != target[pos]) { return false; } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_inline bool raw_json_string::is_equal(std::string_view target) const noexcept { + const char * r{raw()}; + size_t pos{0}; + bool escaping{false}; + for(;pos < target.size();pos++) { + if(r[pos] != target[pos]) { return false; } + // if target is a compile-time constant and it is free from + // quotes, then the next part could get optimized away through + // inlining. + if((target[pos] == '"') && !escaping) { + // We have reached the end of the raw_json_string but + // the target is not done. + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + if(r[pos] != '"') { return false; } + return true; +} + + +simdjson_inline bool raw_json_string::unsafe_is_equal(const char * target) const noexcept { + // Assumptions: 'target' does not contain unescaped quote characters, is null terminated and + // the raw content is quote terminated within a valid JSON string. + const char * r{raw()}; + size_t pos{0}; + for(;target[pos];pos++) { + if(r[pos] != target[pos]) { return false; } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_inline bool raw_json_string::is_equal(const char* target) const noexcept { + // Assumptions: does not contain unescaped quote characters, and + // the raw content is quote terminated within a valid JSON string. + const char * r{raw()}; + size_t pos{0}; + bool escaping{false}; + for(;target[pos];pos++) { + if(r[pos] != target[pos]) { return false; } + // if target is a compile-time constant and it is free from + // quotes, then the next part could get optimized away through + // inlining. + if((target[pos] == '"') && !escaping) { + // We have reached the end of the raw_json_string but + // the target is not done. + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept { + return a.unsafe_is_equal(c); +} + +simdjson_unused simdjson_inline bool operator==(std::string_view c, const raw_json_string &a) noexcept { + return a == c; +} + +simdjson_unused simdjson_inline bool operator!=(const raw_json_string &a, std::string_view c) noexcept { + return !(a == c); +} + +simdjson_unused simdjson_inline bool operator!=(std::string_view c, const raw_json_string &a) noexcept { + return !(a == c); +} + + +simdjson_inline simdjson_warn_unused simdjson_result raw_json_string::unescape(json_iterator &iter, bool allow_replacement) const noexcept { + return iter.unescape(*this, allow_replacement); +} + +simdjson_inline simdjson_warn_unused simdjson_result raw_json_string::unescape_wobbly(json_iterator &iter) const noexcept { + return iter.unescape_wobbly(*this); +} + +simdjson_unused simdjson_inline std::ostream &operator<<(std::ostream &out, const raw_json_string &str) noexcept { + bool in_escape = false; + const char *s = str.raw(); + while (true) { + switch (*s) { + case '\\': in_escape = !in_escape; break; + case '"': if (in_escape) { in_escape = false; } else { return out; } break; + default: if (in_escape) { in_escape = false; } + } + out << *s; + s++; + } +} + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(fallback::ondemand::raw_json_string &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +simdjson_inline simdjson_result simdjson_result::raw() const noexcept { + if (error()) { return error(); } + return first.raw(); +} +simdjson_inline simdjson_warn_unused simdjson_result simdjson_result::unescape(fallback::ondemand::json_iterator &iter, bool allow_replacement) const noexcept { + if (error()) { return error(); } + return first.unescape(iter, allow_replacement); +} +simdjson_inline simdjson_warn_unused simdjson_result simdjson_result::unescape_wobbly(fallback::ondemand::json_iterator &iter) const noexcept { + if (error()) { return error(); } + return first.unescape_wobbly(iter); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H +/* end file simdjson/generic/ondemand/raw_json_string-inl.h for fallback */ +/* including simdjson/generic/ondemand/serialization-inl.h for fallback: #include "simdjson/generic/ondemand/serialization-inl.h" */ +/* begin file simdjson/generic/ondemand/serialization-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/serialization.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +inline std::string_view trim(const std::string_view str) noexcept { + // We can almost surely do better by rolling our own find_first_not_of function. + size_t first = str.find_first_not_of(" \t\n\r"); + // If we have the empty string (just white space), then no trimming is possible, and + // we return the empty string_view. + if (std::string_view::npos == first) { return std::string_view(); } + size_t last = str.find_last_not_of(" \t\n\r"); + return str.substr(first, (last - first + 1)); +} + + +inline simdjson_result to_json_string(fallback::ondemand::document& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(fallback::ondemand::document_reference& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(fallback::ondemand::value& x) noexcept { + /** + * If we somehow receive a value that has already been consumed, + * then the following code could be in trouble. E.g., we create + * an array as needed, but if an array was already created, then + * it could be bad. + */ + using namespace fallback::ondemand; + fallback::ondemand::json_type t; + auto error = x.type().get(t); + if(error != SUCCESS) { return error; } + switch (t) + { + case json_type::array: + { + fallback::ondemand::array array; + error = x.get_array().get(array); + if(error) { return error; } + return to_json_string(array); + } + case json_type::object: + { + fallback::ondemand::object object; + error = x.get_object().get(object); + if(error) { return error; } + return to_json_string(object); + } + default: + return trim(x.raw_json_token()); + } +} + +inline simdjson_result to_json_string(fallback::ondemand::object& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(fallback::ondemand::array& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} +} // namespace simdjson + +namespace simdjson { namespace fallback { namespace ondemand { + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::fallback::ondemand::value x) { + std::string_view v; + auto error = simdjson::to_json_string(x).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::fallback::ondemand::value x) { + std::string_view v; + auto error = simdjson::to_json_string(x).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::fallback::ondemand::array value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::fallback::ondemand::array value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::fallback::ondemand::document& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::fallback::ondemand::document_reference& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::fallback::ondemand::document& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::fallback::ondemand::object value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::fallback::ondemand::object value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif +}}} // namespace simdjson::fallback::ondemand + +#endif // SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H +/* end file simdjson/generic/ondemand/serialization-inl.h for fallback */ +/* including simdjson/generic/ondemand/token_iterator-inl.h for fallback: #include "simdjson/generic/ondemand/token_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/token_iterator-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +simdjson_inline token_iterator::token_iterator( + const uint8_t *_buf, + token_position position +) noexcept : buf{_buf}, _position{position} +{ +} + +simdjson_inline uint32_t token_iterator::current_offset() const noexcept { + return *(_position); +} + + +simdjson_inline const uint8_t *token_iterator::return_current_and_advance() noexcept { + return &buf[*(_position++)]; +} + +simdjson_inline const uint8_t *token_iterator::peek(token_position position) const noexcept { + return &buf[*position]; +} +simdjson_inline uint32_t token_iterator::peek_index(token_position position) const noexcept { + return *position; +} +simdjson_inline uint32_t token_iterator::peek_length(token_position position) const noexcept { + return *(position+1) - *position; +} + +simdjson_inline const uint8_t *token_iterator::peek(int32_t delta) const noexcept { + return &buf[*(_position+delta)]; +} +simdjson_inline uint32_t token_iterator::peek_index(int32_t delta) const noexcept { + return *(_position+delta); +} +simdjson_inline uint32_t token_iterator::peek_length(int32_t delta) const noexcept { + return *(_position+delta+1) - *(_position+delta); +} + +simdjson_inline token_position token_iterator::position() const noexcept { + return _position; +} +simdjson_inline void token_iterator::set_position(token_position target_position) noexcept { + _position = target_position; +} + +simdjson_inline bool token_iterator::operator==(const token_iterator &other) const noexcept { + return _position == other._position; +} +simdjson_inline bool token_iterator::operator!=(const token_iterator &other) const noexcept { + return _position != other._position; +} +simdjson_inline bool token_iterator::operator>(const token_iterator &other) const noexcept { + return _position > other._position; +} +simdjson_inline bool token_iterator::operator>=(const token_iterator &other) const noexcept { + return _position >= other._position; +} +simdjson_inline bool token_iterator::operator<(const token_iterator &other) const noexcept { + return _position < other._position; +} +simdjson_inline bool token_iterator::operator<=(const token_iterator &other) const noexcept { + return _position <= other._position; +} + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(fallback::ondemand::token_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/token_iterator-inl.h for fallback */ +/* including simdjson/generic/ondemand/value-inl.h for fallback: #include "simdjson/generic/ondemand/value-inl.h" */ +/* begin file simdjson/generic/ondemand/value-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +simdjson_inline value::value(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} +simdjson_inline value value::start(const value_iterator &iter) noexcept { + return iter; +} +simdjson_inline value value::resume(const value_iterator &iter) noexcept { + return iter; +} + +simdjson_inline simdjson_result value::get_array() noexcept { + return array::start(iter); +} +simdjson_inline simdjson_result value::get_object() noexcept { + return object::start(iter); +} +simdjson_inline simdjson_result value::start_or_resume_object() noexcept { + if (iter.at_start()) { + return get_object(); + } else { + return object::resume(iter); + } +} + +simdjson_inline simdjson_result value::get_raw_json_string() noexcept { + return iter.get_raw_json_string(); +} +simdjson_inline simdjson_result value::get_string(bool allow_replacement) noexcept { + return iter.get_string(allow_replacement); +} +template +simdjson_inline error_code value::get_string(string_type& receiver, bool allow_replacement) noexcept { + return iter.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result value::get_wobbly_string() noexcept { + return iter.get_wobbly_string(); +} +simdjson_inline simdjson_result value::get_double() noexcept { + return iter.get_double(); +} +simdjson_inline simdjson_result value::get_double_in_string() noexcept { + return iter.get_double_in_string(); +} +simdjson_inline simdjson_result value::get_uint64() noexcept { + return iter.get_uint64(); +} +simdjson_inline simdjson_result value::get_uint64_in_string() noexcept { + return iter.get_uint64_in_string(); +} +simdjson_inline simdjson_result value::get_int64() noexcept { + return iter.get_int64(); +} +simdjson_inline simdjson_result value::get_int64_in_string() noexcept { + return iter.get_int64_in_string(); +} +simdjson_inline simdjson_result value::get_bool() noexcept { + return iter.get_bool(); +} +simdjson_inline simdjson_result value::is_null() noexcept { + return iter.is_null(); +} +template<> simdjson_inline simdjson_result value::get() noexcept { return get_array(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_object(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_number(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_double(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_uint64(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_int64(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_bool(); } + +template simdjson_inline error_code value::get(T &out) noexcept { + return get().get(out); +} + +#if SIMDJSON_EXCEPTIONS +simdjson_inline value::operator array() noexcept(false) { + return get_array(); +} +simdjson_inline value::operator object() noexcept(false) { + return get_object(); +} +simdjson_inline value::operator uint64_t() noexcept(false) { + return get_uint64(); +} +simdjson_inline value::operator int64_t() noexcept(false) { + return get_int64(); +} +simdjson_inline value::operator double() noexcept(false) { + return get_double(); +} +simdjson_inline value::operator std::string_view() noexcept(false) { + return get_string(false); +} +simdjson_inline value::operator raw_json_string() noexcept(false) { + return get_raw_json_string(); +} +simdjson_inline value::operator bool() noexcept(false) { + return get_bool(); +} +#endif + +simdjson_inline simdjson_result value::begin() & noexcept { + return get_array().begin(); +} +simdjson_inline simdjson_result value::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result value::count_elements() & noexcept { + simdjson_result answer; + auto a = get_array(); + answer = a.count_elements(); + // count_elements leaves you pointing inside the array, at the first element. + // We need to move back so that the user can create a new array (which requires that + // we point at '['). + iter.move_at_start(); + return answer; +} +simdjson_inline simdjson_result value::count_fields() & noexcept { + simdjson_result answer; + auto a = get_object(); + answer = a.count_fields(); + iter.move_at_start(); + return answer; +} +simdjson_inline simdjson_result value::at(size_t index) noexcept { + auto a = get_array(); + return a.at(index); +} + +simdjson_inline simdjson_result value::find_field(std::string_view key) noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result value::find_field(const char *key) noexcept { + return start_or_resume_object().find_field(key); +} + +simdjson_inline simdjson_result value::find_field_unordered(std::string_view key) noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result value::find_field_unordered(const char *key) noexcept { + return start_or_resume_object().find_field_unordered(key); +} + +simdjson_inline simdjson_result value::operator[](std::string_view key) noexcept { + return start_or_resume_object()[key]; +} +simdjson_inline simdjson_result value::operator[](const char *key) noexcept { + return start_or_resume_object()[key]; +} + +simdjson_inline simdjson_result value::type() noexcept { + return iter.type(); +} + +simdjson_inline simdjson_result value::is_scalar() noexcept { + json_type this_type; + auto error = type().get(this_type); + if(error) { return error; } + return ! ((this_type == json_type::array) || (this_type == json_type::object)); +} + +simdjson_inline bool value::is_negative() noexcept { + return iter.is_negative(); +} + +simdjson_inline simdjson_result value::is_integer() noexcept { + return iter.is_integer(); +} +simdjson_warn_unused simdjson_inline simdjson_result value::get_number_type() noexcept { + return iter.get_number_type(); +} +simdjson_warn_unused simdjson_inline simdjson_result value::get_number() noexcept { + return iter.get_number(); +} + +simdjson_inline std::string_view value::raw_json_token() noexcept { + return std::string_view(reinterpret_cast(iter.peek_start()), iter.peek_start_length()); +} + +simdjson_inline simdjson_result value::raw_json() noexcept { + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: { + ondemand::array array; + SIMDJSON_TRY(get_array().get(array)); + return array.raw_json(); + } + case json_type::object: { + ondemand::object object; + SIMDJSON_TRY(get_object().get(object)); + return object.raw_json(); + } + default: + return raw_json_token(); + } +} + +simdjson_inline simdjson_result value::current_location() noexcept { + return iter.json_iter().current_location(); +} + +simdjson_inline int32_t value::current_depth() const noexcept{ + return iter.json_iter().depth(); +} + +simdjson_inline simdjson_result value::at_pointer(std::string_view json_pointer) noexcept { + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: + return (*this).get_array().at_pointer(json_pointer); + case json_type::object: + return (*this).get_object().at_pointer(json_pointer); + default: + return INVALID_JSON_POINTER; + } +} + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + fallback::ondemand::value &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + if (error()) { return error(); } + return {}; +} + +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) noexcept { + if (error()) { return error(); } + return first.find_field(key); +} + +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} + +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) noexcept { + if (error()) { return error(); } + return first[key]; +} + +simdjson_inline simdjson_result simdjson_result::get_array() noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} + +template simdjson_inline simdjson_result simdjson_result::get() noexcept { + if (error()) { return error(); } + return first.get(); +} +template simdjson_inline error_code simdjson_result::get(T &out) noexcept { + if (error()) { return error(); } + return first.get(out); +} + +template<> simdjson_inline simdjson_result simdjson_result::get() noexcept { + if (error()) { return error(); } + return std::move(first); +} +template<> simdjson_inline error_code simdjson_result::get(fallback::ondemand::value &out) noexcept { + if (error()) { return error(); } + out = first; + return SUCCESS; +} + +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} +simdjson_inline simdjson_result simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator fallback::ondemand::array() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator fallback::ondemand::object() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator fallback::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline simdjson_result simdjson_result::current_depth() const noexcept { + if (error()) { return error(); } + return first.current_depth(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H +/* end file simdjson/generic/ondemand/value-inl.h for fallback */ +/* including simdjson/generic/ondemand/value_iterator-inl.h for fallback: #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/value_iterator-inl.h for fallback */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/atomparsing.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/numberparsing.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace fallback { +namespace ondemand { + +simdjson_inline value_iterator::value_iterator( + json_iterator *json_iter, + depth_t depth, + token_position start_position +) noexcept : _json_iter{json_iter}, _depth{depth}, _start_position{start_position} +{ +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_object() noexcept { + SIMDJSON_TRY( start_container('{', "Not an object", "object") ); + return started_object(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_root_object() noexcept { + SIMDJSON_TRY( start_container('{', "Not an object", "object") ); + return started_root_object(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_object() noexcept { + assert_at_container_start(); +#if SIMDJSON_DEVELOPMENT_CHECKS + _json_iter->set_start_position(_depth, start_position()); +#endif + if (*_json_iter->peek() == '}') { + logger::log_value(*_json_iter, "empty object"); + _json_iter->return_current_and_advance(); + end_container(); + return false; + } + return true; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::check_root_object() noexcept { + // When in streaming mode, we cannot expect peek_last() to be the last structural element of the + // current document. It only works in the normal mode where we have indexed a single document. + // Note that adding a check for 'streaming' is not expensive since we only have at most + // one root element. + if ( ! _json_iter->streaming() ) { + // The following lines do not fully protect against garbage content within the + // object: e.g., `{"a":2} foo }`. Users concerned with garbage content should + // call `at_end()` on the document instance at the end of the processing to + // ensure that the processing has finished at the end. + // + if (*_json_iter->peek_last() != '}') { + _json_iter->abandon(); + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing } at end"); + } + // If the last character is } *and* the first gibberish character is also '}' + // then on-demand could accidentally go over. So we need additional checks. + // https://github.com/simdjson/simdjson/issues/1834 + // Checking that the document is balanced requires a full scan which is potentially + // expensive, but it only happens in edge cases where the first padding character is + // a closing bracket. + if ((*_json_iter->peek(_json_iter->end_position()) == '}') && (!_json_iter->balanced())) { + _json_iter->abandon(); + // The exact error would require more work. It will typically be an unclosed object. + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "the document is unbalanced"); + } + } + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_root_object() noexcept { + auto error = check_root_object(); + if(error) { return error; } + return started_object(); +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::end_container() noexcept { +#if SIMDJSON_CHECK_EOF + if (depth() > 1 && at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing parent ] or }"); } + // if (depth() <= 1 && !at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing [ or { at start"); } +#endif // SIMDJSON_CHECK_EOF + _json_iter->ascend_to(depth()-1); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::has_next_field() noexcept { + assert_at_next(); + + // It's illegal to call this unless there are more tokens: anything that ends in } or ] is + // obligated to verify there are more tokens if they are not the top level. + switch (*_json_iter->return_current_and_advance()) { + case '}': + logger::log_end_value(*_json_iter, "object"); + SIMDJSON_TRY( end_container() ); + return false; + case ',': + return true; + default: + return report_error(TAPE_ERROR, "Missing comma between object fields"); + } +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::find_field_raw(const std::string_view key) noexcept { + error_code error; + bool has_value; + // + // Initially, the object can be in one of a few different places: + // + // 1. The start of the object, at the first field: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2, index 1) + // ``` + if (at_first_field()) { + has_value = true; + + // + // 2. When a previous search did not yield a value or the object is empty: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // { } + // ^ (depth 0, index 2) + // ``` + // + } else if (!is_open()) { +#if SIMDJSON_DEVELOPMENT_CHECKS + // If we're past the end of the object, we're being iterated out of order. + // Note: this isn't perfect detection. It's possible the user is inside some other object; if so, + // this object iterator will blithely scan that object for fields. + if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; } +#endif + return false; + + // 3. When a previous search found a field or an iterator yielded a value: + // + // ``` + // // When a field was not fully consumed (or not even touched at all) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2) + // // When a field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // When the last field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // ``` + // + } else { + if ((error = skip_child() )) { abandon(); return error; } + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } +#if SIMDJSON_DEVELOPMENT_CHECKS + if (_json_iter->start_position(_depth) != start_position()) { return OUT_OF_ORDER_ITERATION; } +#endif + } + while (has_value) { + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + if ((error = field_key().get(actual_key) )) { abandon(); return error; }; + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + if ((error = field_value() )) { abandon(); return error; } + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + //if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); // Skip the value entirely + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } + } + + // If the loop ended, we're out of fields to look at. + return false; +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::find_field_unordered_raw(const std::string_view key) noexcept { + /** + * When find_field_unordered_raw is called, we can either be pointing at the + * first key, pointing outside (at the closing brace) or if a key was matched + * we can be either pointing right afterthe ':' right before the value (that we need skip), + * or we may have consumed the value and we might be at a comma or at the + * final brace (ready for a call to has_next_field()). + */ + error_code error; + bool has_value; + + // First, we scan from that point to the end. + // If we don't find a match, we may loop back around, and scan from the beginning to that point. + token_position search_start = _json_iter->position(); + + // We want to know whether we need to go back to the beginning. + bool at_first = at_first_field(); + /////////////// + // Initially, the object can be in one of a few different places: + // + // 1. At the first key: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2, index 1) + // ``` + // + if (at_first) { + has_value = true; + + // 2. When a previous search did not yield a value or the object is empty: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // { } + // ^ (depth 0, index 2) + // ``` + // + } else if (!is_open()) { + +#if SIMDJSON_DEVELOPMENT_CHECKS + // If we're past the end of the object, we're being iterated out of order. + // Note: this isn't perfect detection. It's possible the user is inside some other object; if so, + // this object iterator will blithely scan that object for fields. + if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; } +#endif + SIMDJSON_TRY(reset_object().get(has_value)); + at_first = true; + // 3. When a previous search found a field or an iterator yielded a value: + // + // ``` + // // When a field was not fully consumed (or not even touched at all) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2) + // // When a field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // When the last field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // ``` + // + } else { + // If someone queried a key but they not did access the value, then we are left pointing + // at the ':' and we need to move forward through the value... If the value was + // processed then skip_child() does not move the iterator (but may adjust the depth). + if ((error = skip_child() )) { abandon(); return error; } + search_start = _json_iter->position(); + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } +#if SIMDJSON_DEVELOPMENT_CHECKS + if (_json_iter->start_position(_depth) != start_position()) { return OUT_OF_ORDER_ITERATION; } +#endif + } + + // After initial processing, we will be in one of two states: + // + // ``` + // // At the beginning of a field + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // At the end of the object + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // ``` + // + // Next, we find a match starting from the current position. + while (has_value) { + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); // We must be at the start of a field + + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + if ((error = field_key().get(actual_key) )) { abandon(); return error; }; + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + if ((error = field_value() )) { abandon(); return error; } + + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + // if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } + } + // Performance note: it maybe wasteful to rewind to the beginning when there might be + // no other query following. Indeed, it would require reskipping the whole object. + // Instead, you can just stay where you are. If there is a new query, there is always time + // to rewind. + if(at_first) { return false; } + + // If we reach the end without finding a match, search the rest of the fields starting at the + // beginning of the object. + // (We have already run through the object before, so we've already validated its structure. We + // don't check errors in this bit.) + SIMDJSON_TRY(reset_object().get(has_value)); + while (true) { + SIMDJSON_ASSUME(has_value); // we should reach search_start before ever reaching the end of the object + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); // We must be at the start of a field + + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + error = field_key().get(actual_key); SIMDJSON_ASSUME(!error); + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + error = field_value(); SIMDJSON_ASSUME(!error); + + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + // if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); + // If we reached the end of the key-value pair we started from, then we know + // that the key is not there so we return false. We are either right before + // the next comma or the final brace. + if(_json_iter->position() == search_start) { return false; } + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + error = has_next_field().get(has_value); SIMDJSON_ASSUME(!error); + // If we make the mistake of exiting here, then we could be left pointing at a key + // in the middle of an object. That's not an allowable state. + } + // If the loop ended, we're out of fields to look at. The program should + // never reach this point. + return false; +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::field_key() noexcept { + assert_at_next(); + + const uint8_t *key = _json_iter->return_current_and_advance(); + if (*(key++) != '"') { return report_error(TAPE_ERROR, "Object key is not a string"); } + return raw_json_string(key); +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::field_value() noexcept { + assert_at_next(); + + if (*_json_iter->return_current_and_advance() != ':') { return report_error(TAPE_ERROR, "Missing colon in object field"); } + _json_iter->descend_to(depth()+1); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_array() noexcept { + SIMDJSON_TRY( start_container('[', "Not an array", "array") ); + return started_array(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_root_array() noexcept { + SIMDJSON_TRY( start_container('[', "Not an array", "array") ); + return started_root_array(); +} + +inline std::string value_iterator::to_string() const noexcept { + auto answer = std::string("value_iterator [ depth : ") + std::to_string(_depth) + std::string(", "); + if(_json_iter != nullptr) { answer += _json_iter->to_string(); } + answer += std::string(" ]"); + return answer; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_array() noexcept { + assert_at_container_start(); + if (*_json_iter->peek() == ']') { + logger::log_value(*_json_iter, "empty array"); + _json_iter->return_current_and_advance(); + SIMDJSON_TRY( end_container() ); + return false; + } + _json_iter->descend_to(depth()+1); +#if SIMDJSON_DEVELOPMENT_CHECKS + _json_iter->set_start_position(_depth, start_position()); +#endif + return true; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::check_root_array() noexcept { + // When in streaming mode, we cannot expect peek_last() to be the last structural element of the + // current document. It only works in the normal mode where we have indexed a single document. + // Note that adding a check for 'streaming' is not expensive since we only have at most + // one root element. + if ( ! _json_iter->streaming() ) { + // The following lines do not fully protect against garbage content within the + // array: e.g., `[1, 2] foo]`. Users concerned with garbage content should + // also call `at_end()` on the document instance at the end of the processing to + // ensure that the processing has finished at the end. + // + if (*_json_iter->peek_last() != ']') { + _json_iter->abandon(); + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing ] at end"); + } + // If the last character is ] *and* the first gibberish character is also ']' + // then on-demand could accidentally go over. So we need additional checks. + // https://github.com/simdjson/simdjson/issues/1834 + // Checking that the document is balanced requires a full scan which is potentially + // expensive, but it only happens in edge cases where the first padding character is + // a closing bracket. + if ((*_json_iter->peek(_json_iter->end_position()) == ']') && (!_json_iter->balanced())) { + _json_iter->abandon(); + // The exact error would require more work. It will typically be an unclosed array. + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "the document is unbalanced"); + } + } + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_root_array() noexcept { + auto error = check_root_array(); + if (error) { return error; } + return started_array(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::has_next_element() noexcept { + assert_at_next(); + + logger::log_event(*this, "has_next_element"); + switch (*_json_iter->return_current_and_advance()) { + case ']': + logger::log_end_value(*_json_iter, "array"); + SIMDJSON_TRY( end_container() ); + return false; + case ',': + _json_iter->descend_to(depth()+1); + return true; + default: + return report_error(TAPE_ERROR, "Missing comma between array elements"); + } +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::parse_bool(const uint8_t *json) const noexcept { + auto not_true = atomparsing::str4ncmp(json, "true"); + auto not_false = atomparsing::str4ncmp(json, "fals") | (json[4] ^ 'e'); + bool error = (not_true && not_false) || jsoncharutils::is_not_structural_or_whitespace(json[not_true ? 5 : 4]); + if (error) { return incorrect_type_error("Not a boolean"); } + return simdjson_result(!not_true); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::parse_null(const uint8_t *json) const noexcept { + bool is_null_string = !atomparsing::str4ncmp(json, "null") && jsoncharutils::is_structural_or_whitespace(json[4]); + // if we start with 'n', we must be a null + if(!is_null_string && json[0]=='n') { return incorrect_type_error("Not a null but starts with n"); } + return is_null_string; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_string(bool allow_replacement) noexcept { + return get_raw_json_string().unescape(json_iter(), allow_replacement); +} +template +simdjson_warn_unused simdjson_inline error_code value_iterator::get_string(string_type& receiver, bool allow_replacement) noexcept { + std::string_view content; + auto err = get_string(allow_replacement).get(content); + if (err) { return err; } + receiver = content; + return SUCCESS; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_wobbly_string() noexcept { + return get_raw_json_string().unescape_wobbly(json_iter()); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_raw_json_string() noexcept { + auto json = peek_scalar("string"); + if (*json != '"') { return incorrect_type_error("Not a string"); } + advance_scalar("string"); + return raw_json_string(json+1); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_uint64() noexcept { + auto result = numberparsing::parse_unsigned(peek_non_root_scalar("uint64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("uint64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_uint64_in_string() noexcept { + auto result = numberparsing::parse_unsigned_in_string(peek_non_root_scalar("uint64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("uint64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_int64() noexcept { + auto result = numberparsing::parse_integer(peek_non_root_scalar("int64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("int64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_int64_in_string() noexcept { + auto result = numberparsing::parse_integer_in_string(peek_non_root_scalar("int64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("int64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_double() noexcept { + auto result = numberparsing::parse_double(peek_non_root_scalar("double")); + if(result.error() == SUCCESS) { advance_non_root_scalar("double"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_double_in_string() noexcept { + auto result = numberparsing::parse_double_in_string(peek_non_root_scalar("double")); + if(result.error() == SUCCESS) { advance_non_root_scalar("double"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_bool() noexcept { + auto result = parse_bool(peek_non_root_scalar("bool")); + if(result.error() == SUCCESS) { advance_non_root_scalar("bool"); } + return result; +} +simdjson_inline simdjson_result value_iterator::is_null() noexcept { + bool is_null_value; + SIMDJSON_TRY(parse_null(peek_non_root_scalar("null")).get(is_null_value)); + if(is_null_value) { advance_non_root_scalar("null"); } + return is_null_value; +} +simdjson_inline bool value_iterator::is_negative() noexcept { + return numberparsing::is_negative(peek_non_root_scalar("numbersign")); +} +simdjson_inline bool value_iterator::is_root_negative() noexcept { + return numberparsing::is_negative(peek_root_scalar("numbersign")); +} +simdjson_inline simdjson_result value_iterator::is_integer() noexcept { + return numberparsing::is_integer(peek_non_root_scalar("integer")); +} +simdjson_inline simdjson_result value_iterator::get_number_type() noexcept { + return numberparsing::get_number_type(peek_non_root_scalar("integer")); +} +simdjson_inline simdjson_result value_iterator::get_number() noexcept { + number num; + error_code error = numberparsing::parse_number(peek_non_root_scalar("number"), num); + if(error) { return error; } + return num; +} + +simdjson_inline simdjson_result value_iterator::is_root_integer(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("is_root_integer"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + return false; // if there are more than 20 characters, it cannot be represented as an integer. + } + auto answer = numberparsing::is_integer(tmpbuf); + // If the parsing was a success, we must still check that it is + // a single scalar. Note that we parse first because of cases like '[]' where + // getting TRAILING_CONTENT is wrong. + if(check_trailing && (answer.error() == SUCCESS) && (!_json_iter->is_single_token())) { return TRAILING_CONTENT; } + return answer; +} + +simdjson_inline simdjson_result value_iterator::get_root_number_type(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("number"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto answer = numberparsing::get_number_type(tmpbuf); + if (check_trailing && (answer.error() == SUCCESS) && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + return answer; +} +simdjson_inline simdjson_result value_iterator::get_root_number(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("number"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + number num; + error_code error = numberparsing::parse_number(tmpbuf, num); + if(error) { return error; } + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("number"); + return num; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_string(bool check_trailing, bool allow_replacement) noexcept { + return get_root_raw_json_string(check_trailing).unescape(json_iter(), allow_replacement); +} +template +simdjson_warn_unused simdjson_inline error_code value_iterator::get_root_string(string_type& receiver, bool check_trailing, bool allow_replacement) noexcept { + std::string_view content; + auto err = get_root_string(check_trailing, allow_replacement).get(content); + if (err) { return err; } + receiver = content; + return SUCCESS; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_wobbly_string(bool check_trailing) noexcept { + return get_root_raw_json_string(check_trailing).unescape_wobbly(json_iter()); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_raw_json_string(bool check_trailing) noexcept { + auto json = peek_scalar("string"); + if (*json != '"') { return incorrect_type_error("Not a string"); } + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_scalar("string"); + return raw_json_string(json+1); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_uint64(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("uint64"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_unsigned(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("uint64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_uint64_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("uint64"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_unsigned_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("uint64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_int64(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("int64"); + uint8_t tmpbuf[20+1+1]; // -<19 digits> is the longest possible integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + + auto result = numberparsing::parse_integer(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("int64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_int64_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("int64"); + uint8_t tmpbuf[20+1+1]; // -<19 digits> is the longest possible integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + + auto result = numberparsing::parse_integer_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("int64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_double(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("double"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; // +1 for null termination. + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_double(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("double"); + } + return result; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_double_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("double"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; // +1 for null termination. + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_double_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("double"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_bool(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("bool"); + uint8_t tmpbuf[5+1+1]; // +1 for null termination + tmpbuf[5+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 5+1)) { return incorrect_type_error("Not a boolean"); } + auto result = parse_bool(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("bool"); + } + return result; +} +simdjson_inline simdjson_result value_iterator::is_root_null(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("null"); + bool result = (max_len >= 4 && !atomparsing::str4ncmp(json, "null") && + (max_len == 4 || jsoncharutils::is_structural_or_whitespace(json[4]))); + if(result) { // we have something that looks like a null. + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("null"); + } + return result; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::skip_child() noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth >= _depth ); + + return _json_iter->skip_child(depth()); +} + +simdjson_inline value_iterator value_iterator::child() const noexcept { + assert_at_child(); + return { _json_iter, depth()+1, _json_iter->token.position() }; +} + +// GCC 7 warns when the first line of this function is inlined away into oblivion due to the caller +// relating depth and iterator depth, which is a desired effect. It does not happen if is_open is +// marked non-inline. +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline bool value_iterator::is_open() const noexcept { + return _json_iter->depth() >= depth(); +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline bool value_iterator::at_end() const noexcept { + return _json_iter->at_end(); +} + +simdjson_inline bool value_iterator::at_start() const noexcept { + return _json_iter->token.position() == start_position(); +} + +simdjson_inline bool value_iterator::at_first_field() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + return _json_iter->token.position() == start_position() + 1; +} + +simdjson_inline void value_iterator::abandon() noexcept { + _json_iter->abandon(); +} + +simdjson_warn_unused simdjson_inline depth_t value_iterator::depth() const noexcept { + return _depth; +} +simdjson_warn_unused simdjson_inline error_code value_iterator::error() const noexcept { + return _json_iter->error; +} +simdjson_warn_unused simdjson_inline uint8_t *&value_iterator::string_buf_loc() noexcept { + return _json_iter->string_buf_loc(); +} +simdjson_warn_unused simdjson_inline const json_iterator &value_iterator::json_iter() const noexcept { + return *_json_iter; +} +simdjson_warn_unused simdjson_inline json_iterator &value_iterator::json_iter() noexcept { + return *_json_iter; +} + +simdjson_inline const uint8_t *value_iterator::peek_start() const noexcept { + return _json_iter->peek(start_position()); +} +simdjson_inline uint32_t value_iterator::peek_start_length() const noexcept { + return _json_iter->peek_length(start_position()); +} + +simdjson_inline const uint8_t *value_iterator::peek_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + if (!is_at_start()) { return peek_start(); } + + // Get the JSON and advance the cursor, decreasing depth to signify that we have retrieved the value. + assert_at_start(); + return _json_iter->peek(); +} + +simdjson_inline void value_iterator::advance_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + if (!is_at_start()) { return; } + + // Get the JSON and advance the cursor, decreasing depth to signify that we have retrieved the value. + assert_at_start(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} + +simdjson_inline error_code value_iterator::start_container(uint8_t start_char, const char *incorrect_type_message, const char *type) noexcept { + logger::log_start_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + const uint8_t *json; + if (!is_at_start()) { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + json = peek_start(); + if (*json != start_char) { return incorrect_type_error(incorrect_type_message); } + } else { + assert_at_start(); + /** + * We should be prudent. Let us peek. If it is not the right type, we + * return an error. Only once we have determined that we have the right + * type are we allowed to advance! + */ + json = _json_iter->peek(); + if (*json != start_char) { return incorrect_type_error(incorrect_type_message); } + _json_iter->return_current_and_advance(); + } + + + return SUCCESS; +} + + +simdjson_inline const uint8_t *value_iterator::peek_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return peek_start(); } + + assert_at_root(); + return _json_iter->peek(); +} +simdjson_inline const uint8_t *value_iterator::peek_non_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return peek_start(); } + + assert_at_non_root_start(); + return _json_iter->peek(); +} + +simdjson_inline void value_iterator::advance_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return; } + + assert_at_root(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} +simdjson_inline void value_iterator::advance_non_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return; } + + assert_at_non_root_start(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} + +simdjson_inline error_code value_iterator::incorrect_type_error(const char *message) const noexcept { + logger::log_error(*_json_iter, start_position(), depth(), message); + return INCORRECT_TYPE; +} + +simdjson_inline bool value_iterator::is_at_start() const noexcept { + return position() == start_position(); +} + +simdjson_inline bool value_iterator::is_at_key() const noexcept { + // Keys are at the same depth as the object. + // Note here that we could be safer and check that we are within an object, + // but we do not. + return _depth == _json_iter->_depth && *_json_iter->peek() == '"'; +} + +simdjson_inline bool value_iterator::is_at_iterator_start() const noexcept { + // We can legitimately be either at the first value ([1]), or after the array if it's empty ([]). + auto delta = position() - start_position(); + return delta == 1 || delta == 2; +} + +inline void value_iterator::assert_at_start() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position == _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_container_start() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position == _start_position + 1 ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_next() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +simdjson_inline void value_iterator::move_at_start() noexcept { + _json_iter->_depth = _depth; + _json_iter->token.set_position(_start_position); +} + +simdjson_inline void value_iterator::move_at_container_start() noexcept { + _json_iter->_depth = _depth; + _json_iter->token.set_position(_start_position + 1); +} + +simdjson_inline simdjson_result value_iterator::reset_array() noexcept { + if(error()) { return error(); } + move_at_container_start(); + return started_array(); +} + +simdjson_inline simdjson_result value_iterator::reset_object() noexcept { + if(error()) { return error(); } + move_at_container_start(); + return started_object(); +} + +inline void value_iterator::assert_at_child() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth + 1 ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_root() const noexcept { + assert_at_start(); + SIMDJSON_ASSUME( _depth == 1 ); +} + +inline void value_iterator::assert_at_non_root_start() const noexcept { + assert_at_start(); + SIMDJSON_ASSUME( _depth > 1 ); +} + +inline void value_iterator::assert_is_valid() const noexcept { + SIMDJSON_ASSUME( _json_iter != nullptr ); +} + +simdjson_inline bool value_iterator::is_valid() const noexcept { + return _json_iter != nullptr; +} + +simdjson_inline simdjson_result value_iterator::type() const noexcept { + switch (*peek_start()) { + case '{': + return json_type::object; + case '[': + return json_type::array; + case '"': + return json_type::string; + case 'n': + return json_type::null; + case 't': case 'f': + return json_type::boolean; + case '-': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return json_type::number; + default: + return TAPE_ERROR; + } +} + +simdjson_inline token_position value_iterator::start_position() const noexcept { + return _start_position; +} + +simdjson_inline token_position value_iterator::position() const noexcept { + return _json_iter->position(); +} + +simdjson_inline token_position value_iterator::end_position() const noexcept { + return _json_iter->end_position(); +} + +simdjson_inline token_position value_iterator::last_position() const noexcept { + return _json_iter->last_position(); +} + +simdjson_inline error_code value_iterator::report_error(error_code error, const char *message) noexcept { + return _json_iter->report_error(error, message); +} + +} // namespace ondemand +} // namespace fallback +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(fallback::ondemand::value_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/value_iterator-inl.h for fallback */ +/* end file simdjson/generic/ondemand/amalgamated.h for fallback */ +/* including simdjson/fallback/end.h: #include "simdjson/fallback/end.h" */ +/* begin file simdjson/fallback/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/fallback/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +/* undefining SIMDJSON_IMPLEMENTATION from "fallback" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/fallback/end.h */ + +#endif // SIMDJSON_FALLBACK_ONDEMAND_H +/* end file simdjson/fallback/ondemand.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(haswell) +/* including simdjson/haswell/ondemand.h: #include "simdjson/haswell/ondemand.h" */ +/* begin file simdjson/haswell/ondemand.h */ +#ifndef SIMDJSON_HASWELL_ONDEMAND_H +#define SIMDJSON_HASWELL_ONDEMAND_H + +/* including simdjson/haswell/begin.h: #include "simdjson/haswell/begin.h" */ +/* begin file simdjson/haswell/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "haswell" */ +#define SIMDJSON_IMPLEMENTATION haswell + +/* including simdjson/haswell/base.h: #include "simdjson/haswell/base.h" */ +/* begin file simdjson/haswell/base.h */ +#ifndef SIMDJSON_HASWELL_BASE_H +#define SIMDJSON_HASWELL_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_HASWELL +namespace simdjson { +/** + * Implementation for Haswell (Intel AVX2). + */ +namespace haswell { + +class implementation; + +namespace { +namespace simd { +template struct simd8; +template struct simd8x64; +} // namespace simd +} // unnamed namespace + +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_BASE_H +/* end file simdjson/haswell/base.h */ +/* including simdjson/haswell/intrinsics.h: #include "simdjson/haswell/intrinsics.h" */ +/* begin file simdjson/haswell/intrinsics.h */ +#ifndef SIMDJSON_HASWELL_INTRINSICS_H +#define SIMDJSON_HASWELL_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + * e.g., if __AVX2__ is set... in turn, we normally set these + * macros by compiling against the corresponding architecture + * (e.g., arch:AVX2, -mavx2, etc.) which compiles the whole + * software with these advanced instructions. In simdjson, we + * want to compile the whole program for a generic target, + * and only target our specific kernels. As a workaround, + * we directly include the needed headers. These headers would + * normally guard against such usage, but we carefully included + * (or ) before, so the headers + * are fooled. + */ +#include // for _blsr_u64 +#include // for __lzcnt64 +#include // for most things (AVX2, AVX512, _popcnt64) +#include +#include +#include +#include +#include // for _mm_clmulepi64_si128 +// unfortunately, we may not get _blsr_u64, but, thankfully, clang +// has it as a macro. +#ifndef _blsr_u64 +// we roll our own +#define _blsr_u64(n) ((n - 1) & n) +#endif // _blsr_u64 +#endif // SIMDJSON_CLANG_VISUAL_STUDIO + +static_assert(sizeof(__m256i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for haswell kernel."); + +#endif // SIMDJSON_HASWELL_INTRINSICS_H +/* end file simdjson/haswell/intrinsics.h */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_HASWELL +SIMDJSON_TARGET_REGION("avx2,bmi,pclmul,lzcnt,popcnt") +#endif + +/* including simdjson/haswell/bitmanipulation.h: #include "simdjson/haswell/bitmanipulation.h" */ +/* begin file simdjson/haswell/bitmanipulation.h */ +#ifndef SIMDJSON_HASWELL_BITMANIPULATION_H +#define SIMDJSON_HASWELL_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/bitmask.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return (int)_tzcnt_u64(input_num); +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + //////// + // You might expect the next line to be equivalent to + // return (int)_tzcnt_u64(input_num); + // but the generated code differs and might be less efficient? + //////// + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return _blsr_u64(input_num); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { + return int(_lzcnt_u64(input_num)); +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_BITMANIPULATION_H +/* end file simdjson/haswell/bitmanipulation.h */ +/* including simdjson/haswell/bitmask.h: #include "simdjson/haswell/bitmask.h" */ +/* begin file simdjson/haswell/bitmask.h */ +#ifndef SIMDJSON_HASWELL_BITMASK_H +#define SIMDJSON_HASWELL_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(const uint64_t bitmask) { + // There should be no such thing with a processor supporting avx2 + // but not clmul. + __m128i all_ones = _mm_set1_epi8('\xFF'); + __m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0ULL, bitmask), all_ones, 0); + return _mm_cvtsi128_si64(result); +} + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_BITMASK_H +/* end file simdjson/haswell/bitmask.h */ +/* including simdjson/haswell/numberparsing_defs.h: #include "simdjson/haswell/numberparsing_defs.h" */ +/* begin file simdjson/haswell/numberparsing_defs.h */ +#ifndef SIMDJSON_HASWELL_NUMBERPARSING_DEFS_H +#define SIMDJSON_HASWELL_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace numberparsing { + +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + // this actually computes *16* values so we are being wasteful. + const __m128i ascii0 = _mm_set1_epi8('0'); + const __m128i mul_1_10 = + _mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1); + const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1); + const __m128i mul_1_10000 = + _mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1); + const __m128i input = _mm_sub_epi8( + _mm_loadu_si128(reinterpret_cast(chars)), ascii0); + const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10); + const __m128i t2 = _mm_madd_epi16(t1, mul_1_100); + const __m128i t3 = _mm_packus_epi32(t2, t2); + const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000); + return _mm_cvtsi128_si32( + t4); // only captures the sum of the first 8 digits, drop the rest +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace haswell +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_HASWELL_NUMBERPARSING_DEFS_H +/* end file simdjson/haswell/numberparsing_defs.h */ +/* including simdjson/haswell/simd.h: #include "simdjson/haswell/simd.h" */ +/* begin file simdjson/haswell/simd.h */ +#ifndef SIMDJSON_HASWELL_SIMD_H +#define SIMDJSON_HASWELL_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { +namespace simd { + + // Forward-declared so they can be used by splat and friends. + template + struct base { + __m256i value; + + // Zero constructor + simdjson_inline base() : value{__m256i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m256i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m256i&() const { return this->value; } + simdjson_inline operator __m256i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm256_or_si256(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm256_and_si256(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm256_xor_si256(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm256_andnot_si256(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + // Forward-declared so they can be used by splat and friends. + template + struct simd8; + + template> + struct base8: base> { + typedef uint32_t bitmask_t; + typedef uint64_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m256i _value) : base>(_value) {} + + friend simdjson_really_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return _mm256_cmpeq_epi8(lhs, rhs); } + + static const int SIZE = sizeof(base::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return _mm256_alignr_epi8(*this, _mm256_permute2x128_si256(prev_chunk, *this, 0x21), 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm256_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m256i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { return _mm256_movemask_epi8(*this); } + simdjson_inline bool any() const { return !_mm256_testz_si256(*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm256_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm256_setzero_si256(); } + static simdjson_inline simd8 load(const T values[32]) { + return _mm256_loadu_si256(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m256i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[32]) const { return _mm256_storeu_si256(reinterpret_cast<__m256i *>(dst), *this); } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm256_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm256_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm256_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 32 - count_ones(mask) bytes of the result are significant but 32 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint32_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in four steps, first 8 bytes and then second 8 bytes... + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // second least significant 8 bits + uint8_t mask3 = uint8_t(mask >> 16); // ... + uint8_t mask4 = uint8_t(mask >> 24); // ... + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + __m256i shufmask = _mm256_set_epi64x(thintable_epi8[mask4], thintable_epi8[mask3], + thintable_epi8[mask2], thintable_epi8[mask1]); + // we increment by 0x08 the second half of the mask and so forth + shufmask = + _mm256_add_epi8(shufmask, _mm256_set_epi32(0x18181818, 0x18181818, + 0x10101010, 0x10101010, 0x08080808, 0x08080808, 0, 0)); + // this is the version "nearly pruned" + __m256i pruned = _mm256_shuffle_epi8(*this, shufmask); + // we still need to put the pieces back together. + // we compute the popcount of the first words: + int pop1 = BitsSetTable256mul2[mask1]; + int pop3 = BitsSetTable256mul2[mask3]; + + // then load the corresponding mask + // could be done with _mm256_loadu2_m128i but many standard libraries omit this intrinsic. + __m256i v256 = _mm256_castsi128_si256( + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop1 * 8))); + __m256i compactmask = _mm256_insertf128_si256(v256, + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop3 * 8)), 1); + __m256i almostthere = _mm256_shuffle_epi8(pruned, compactmask); + // We just need to write out the result. + // This is the tricky bit that is hard to do + // if we want to return a SIMD register, since there + // is no single-instruction approach to recombine + // the two 128-bit lanes with an offset. + __m128i v128; + v128 = _mm256_castsi256_si128(almostthere); + _mm_storeu_si128( reinterpret_cast<__m128i *>(output), v128); + v128 = _mm256_extractf128_si256(almostthere, 1); + _mm_storeu_si128( reinterpret_cast<__m128i *>(output + 16 - count_ones(mask & 0xFFFF)), v128); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m256i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t values[32]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15, + int8_t v16, int8_t v17, int8_t v18, int8_t v19, int8_t v20, int8_t v21, int8_t v22, int8_t v23, + int8_t v24, int8_t v25, int8_t v26, int8_t v27, int8_t v28, int8_t v29, int8_t v30, int8_t v31 + ) : simd8(_mm256_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v16,v17,v18,v19,v20,v21,v22,v23, + v24,v25,v26,v27,v28,v29,v30,v31 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm256_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm256_min_epi8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return _mm256_cmpgt_epi8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm256_cmpgt_epi8(other, *this); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m256i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t values[32]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15, + uint8_t v16, uint8_t v17, uint8_t v18, uint8_t v19, uint8_t v20, uint8_t v21, uint8_t v22, uint8_t v23, + uint8_t v24, uint8_t v25, uint8_t v26, uint8_t v27, uint8_t v28, uint8_t v29, uint8_t v30, uint8_t v31 + ) : simd8(_mm256_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v16,v17,v18,v19,v20,v21,v22,v23, + v24,v25,v26,v27,v28,v29,v30,v31 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm256_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm256_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm256_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm256_min_epu8(other, *this); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline simd8 operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline simd8 operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->lt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return *this == uint8_t(0); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + simdjson_inline bool is_ascii() const { return _mm256_movemask_epi8(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { return _mm256_testz_si256(*this, *this); } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return _mm256_testz_si256(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm256_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm256_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline int get_bit() const { return _mm256_movemask_epi8(_mm256_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 2, "Haswell kernel should use two registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1) : chunks{chunk0, chunk1} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+32)} {} + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + uint32_t mask1 = uint32_t(mask); + uint32_t mask2 = uint32_t(mask >> 32); + this->chunks[0].compress(mask1, output); + this->chunks[1].compress(mask2, output + 32 - count_ones(mask1)); + return 64 - count_ones(mask); + } + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r_lo = uint32_t(this->chunks[0].to_bitmask()); + uint64_t r_hi = this->chunks[1].to_bitmask(); + return r_lo | (r_hi << 32); + } + + simdjson_inline simd8 reduce_or() const { + return this->chunks[0] | this->chunks[1]; + } + + simdjson_inline simd8x64 bit_or(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] | mask, + this->chunks[1] | mask + ); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64( + this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1] + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_SIMD_H +/* end file simdjson/haswell/simd.h */ +/* including simdjson/haswell/stringparsing_defs.h: #include "simdjson/haswell/stringparsing_defs.h" */ +/* begin file simdjson/haswell/stringparsing_defs.h */ +#ifndef SIMDJSON_HASWELL_STRINGPARSING_DEFS_H +#define SIMDJSON_HASWELL_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/simd.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return ((quote_bits - 1) & bs_bits) != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 15 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v(src); + // store to dest unconditionally - we can overwrite the bits we don't like later + v.store(dst); + return { + static_cast((v == '\\').to_bitmask()), // bs_bits + static_cast((v == '"').to_bitmask()), // quote_bits + }; +} + +} // unnamed namespace +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_HASWELL_STRINGPARSING_DEFS_H +/* end file simdjson/haswell/stringparsing_defs.h */ +/* end file simdjson/haswell/begin.h */ +/* including simdjson/generic/ondemand/amalgamated.h for haswell: #include "simdjson/generic/ondemand/amalgamated.h" */ +/* begin file simdjson/generic/ondemand/amalgamated.h for haswell */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H) +#error simdjson/generic/ondemand/dependencies.h must be included before simdjson/generic/ondemand/amalgamated.h! +#endif + +// Stuff other things depend on +/* including simdjson/generic/ondemand/base.h for haswell: #include "simdjson/generic/ondemand/base.h" */ +/* begin file simdjson/generic/ondemand/base.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +/** + * A fast, simple, DOM-like interface that parses JSON as you use it. + * + * Designed for maximum speed and a lower memory profile. + */ +namespace ondemand { + +/** Represents the depth of a JSON value (number of nested arrays/objects). */ +using depth_t = int32_t; + +/** @copydoc simdjson::haswell::number_type */ +using number_type = simdjson::haswell::number_type; + +/** @private Position in the JSON buffer indexes */ +using token_position = const uint32_t *; + +class array; +class array_iterator; +class document; +class document_reference; +class document_stream; +class field; +class json_iterator; +enum class json_type; +struct number; +class object; +class object_iterator; +class parser; +class raw_json_string; +class token_iterator; +class value; +class value_iterator; + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_BASE_H +/* end file simdjson/generic/ondemand/base.h for haswell */ +/* including simdjson/generic/ondemand/value_iterator.h for haswell: #include "simdjson/generic/ondemand/value_iterator.h" */ +/* begin file simdjson/generic/ondemand/value_iterator.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +/** + * Iterates through a single JSON value at a particular depth. + * + * Does not keep track of the type of value: provides methods for objects, arrays and scalars and expects + * the caller to call the right ones. + * + * @private This is not intended for external use. + */ +class value_iterator { +protected: + /** The underlying JSON iterator */ + json_iterator *_json_iter{}; + /** The depth of this value */ + depth_t _depth{}; + /** + * The starting token index for this value + */ + token_position _start_position{}; + +public: + simdjson_inline value_iterator() noexcept = default; + + /** + * Denote that we're starting a document. + */ + simdjson_inline void start_document() noexcept; + + /** + * Skips a non-iterated or partially-iterated JSON value, whether it is a scalar, array or object. + * + * Optimized for scalars. + */ + simdjson_warn_unused simdjson_inline error_code skip_child() noexcept; + + /** + * Tell whether the iterator is at the EOF mark + */ + simdjson_inline bool at_end() const noexcept; + + /** + * Tell whether the iterator is at the start of the value + */ + simdjson_inline bool at_start() const noexcept; + + /** + * Tell whether the value is open--if the value has not been used, or the array/object is still open. + */ + simdjson_inline bool is_open() const noexcept; + + /** + * Tell whether the value is at an object's first field (just after the {). + */ + simdjson_inline bool at_first_field() const noexcept; + + /** + * Abandon all iteration. + */ + simdjson_inline void abandon() noexcept; + + /** + * Get the child value as a value_iterator. + */ + simdjson_inline value_iterator child_value() const noexcept; + + /** + * Get the depth of this value. + */ + simdjson_inline int32_t depth() const noexcept; + + /** + * Get the JSON type of this value. + * + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() const noexcept; + + /** + * @addtogroup object Object iteration + * + * Methods to iterate and find object fields. These methods generally *assume* the value is + * actually an object; the caller is responsible for keeping track of that fact. + * + * @{ + */ + + /** + * Start an object iteration. + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCORRECT_TYPE if there is no opening { + */ + simdjson_warn_unused simdjson_inline simdjson_result start_object() noexcept; + /** + * Start an object iteration from the root. + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCORRECT_TYPE if there is no opening { + * @error TAPE_ERROR if there is no matching } at end of document + */ + simdjson_warn_unused simdjson_inline simdjson_result start_root_object() noexcept; + /** + * Checks whether an object could be started from the root. May be called by start_root_object. + * + * @returns SUCCESS if it is possible to safely start an object from the root (document level). + * @error INCORRECT_TYPE if there is no opening { + * @error TAPE_ERROR if there is no matching } at end of document + */ + simdjson_warn_unused simdjson_inline error_code check_root_object() noexcept; + /** + * Start an object iteration after the user has already checked and moved past the {. + * + * Does not move the iterator unless the object is empty ({}). + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_object() noexcept; + /** + * Start an object iteration from the root, after the user has already checked and moved past the {. + * + * Does not move the iterator unless the object is empty ({}). + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_root_object() noexcept; + + /** + * Moves to the next field in an object. + * + * Looks for , and }. If } is found, the object is finished and the iterator advances past it. + * Otherwise, it advances to the next value. + * + * @return whether there is another field in the object. + * @error TAPE_ERROR If there is a comma missing between fields. + * @error TAPE_ERROR If there is a comma, but not enough tokens remaining to have a key, :, and value. + */ + simdjson_warn_unused simdjson_inline simdjson_result has_next_field() noexcept; + + /** + * Get the current field's key. + */ + simdjson_warn_unused simdjson_inline simdjson_result field_key() noexcept; + + /** + * Pass the : in the field and move to its value. + */ + simdjson_warn_unused simdjson_inline error_code field_value() noexcept; + + /** + * Find the next field with the given key. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline error_code find_field(const std::string_view key) noexcept; + + /** + * Find the next field with the given key, *without* unescaping. This assumes object order: it + * will not find the field if it was already passed when looking for some *other* field. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline simdjson_result find_field_raw(const std::string_view key) noexcept; + + /** + * Find the field with the given key without regard to order, and *without* unescaping. + * + * This is an unordered object lookup: if the field is not found initially, it will cycle around and scan from the beginning. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline simdjson_result find_field_unordered_raw(const std::string_view key) noexcept; + + /** @} */ + + /** + * @addtogroup array Array iteration + * Methods to iterate over array elements. These methods generally *assume* the value is actually + * an object; the caller is responsible for keeping track of that fact. + * @{ + */ + + /** + * Check for an opening [ and start an array iteration. + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCORRECT_TYPE If there is no [. + */ + simdjson_warn_unused simdjson_inline simdjson_result start_array() noexcept; + /** + * Check for an opening [ and start an array iteration while at the root. + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCORRECT_TYPE If there is no [. + * @error TAPE_ERROR if there is no matching ] at end of document + */ + simdjson_warn_unused simdjson_inline simdjson_result start_root_array() noexcept; + /** + * Checks whether an array could be started from the root. May be called by start_root_array. + * + * @returns SUCCESS if it is possible to safely start an array from the root (document level). + * @error INCORRECT_TYPE If there is no [. + * @error TAPE_ERROR if there is no matching ] at end of document + */ + simdjson_warn_unused simdjson_inline error_code check_root_array() noexcept; + /** + * Start an array iteration, after the user has already checked and moved past the [. + * + * Does not move the iterator unless the array is empty ([]). + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_array() noexcept; + /** + * Start an array iteration from the root, after the user has already checked and moved past the [. + * + * Does not move the iterator unless the array is empty ([]). + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_root_array() noexcept; + + /** + * Moves to the next element in an array. + * + * Looks for , and ]. If ] is found, the array is finished and the iterator advances past it. + * Otherwise, it advances to the next value. + * + * @return Whether there is another element in the array. + * @error TAPE_ERROR If there is a comma missing between elements. + */ + simdjson_warn_unused simdjson_inline simdjson_result has_next_element() noexcept; + + /** + * Get a child value iterator. + */ + simdjson_warn_unused simdjson_inline value_iterator child() const noexcept; + + /** @} */ + + /** + * @defgroup scalar Scalar values + * @addtogroup scalar + * @{ + */ + + simdjson_warn_unused simdjson_inline simdjson_result get_string(bool allow_replacement) noexcept; + template + simdjson_warn_unused simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_int64() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_double() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_bool() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_null() noexcept; + simdjson_warn_unused simdjson_inline bool is_negative() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_integer() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + simdjson_warn_unused simdjson_inline simdjson_result get_root_string(bool check_trailing, bool allow_replacement) noexcept; + template + simdjson_warn_unused simdjson_inline error_code get_root_string(string_type& receiver, bool check_trailing, bool allow_replacement) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_wobbly_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_raw_json_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_uint64(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_uint64_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_int64(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_int64_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_double(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_double_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_bool(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline bool is_root_negative() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_root_integer(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_number_type(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_number(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_root_null(bool check_trailing) noexcept; + + simdjson_inline error_code error() const noexcept; + simdjson_inline uint8_t *&string_buf_loc() noexcept; + simdjson_inline const json_iterator &json_iter() const noexcept; + simdjson_inline json_iterator &json_iter() noexcept; + + simdjson_inline void assert_is_valid() const noexcept; + simdjson_inline bool is_valid() const noexcept; + + /** @} */ +protected: + /** + * Restarts an array iteration. + * @returns Whether the array has any elements (returns false for empty). + */ + simdjson_inline simdjson_result reset_array() noexcept; + /** + * Restarts an object iteration. + * @returns Whether the object has any fields (returns false for empty). + */ + simdjson_inline simdjson_result reset_object() noexcept; + /** + * move_at_start(): moves us so that we are pointing at the beginning of + * the container. It updates the index so that at_start() is true and it + * syncs the depth. The user can then create a new container instance. + * + * Usage: used with value::count_elements(). + **/ + simdjson_inline void move_at_start() noexcept; + + /** + * move_at_container_start(): moves us so that we are pointing at the beginning of + * the container so that assert_at_container_start() passes. + * + * Usage: used with reset_array() and reset_object(). + **/ + simdjson_inline void move_at_container_start() noexcept; + /* Useful for debugging and logging purposes. */ + inline std::string to_string() const noexcept; + simdjson_inline value_iterator(json_iterator *json_iter, depth_t depth, token_position start_index) noexcept; + + simdjson_inline simdjson_result parse_null(const uint8_t *json) const noexcept; + simdjson_inline simdjson_result parse_bool(const uint8_t *json) const noexcept; + simdjson_inline const uint8_t *peek_start() const noexcept; + simdjson_inline uint32_t peek_start_length() const noexcept; + + /** + * The general idea of the advance_... methods and the peek_* methods + * is that you first peek and check that you have desired type. If you do, + * and only if you do, then you advance. + * + * We used to unconditionally advance. But this made reasoning about our + * current state difficult. + * Suppose you always advance. Look at the 'value' matching the key + * "shadowable" in the following example... + * + * ({"globals":{"a":{"shadowable":[}}}}) + * + * If the user thinks it is a Boolean and asks for it, then we check the '[', + * decide it is not a Boolean, but still move into the next character ('}'). Now + * we are left pointing at '}' right after a '['. And we have not yet reported + * an error, only that we do not have a Boolean. + * + * If, instead, you just stand your ground until it is content that you know, then + * you will only even move beyond the '[' if the user tells you that you have an + * array. So you will be at the '}' character inside the array and, hopefully, you + * will then catch the error because an array cannot start with '}', but the code + * processing Boolean values does not know this. + * + * So the contract is: first call 'peek_...' and then call 'advance_...' only + * if you have determined that it is a type you can handle. + * + * Unfortunately, it makes the code more verbose, longer and maybe more error prone. + */ + + simdjson_inline void advance_scalar(const char *type) noexcept; + simdjson_inline void advance_root_scalar(const char *type) noexcept; + simdjson_inline void advance_non_root_scalar(const char *type) noexcept; + + simdjson_inline const uint8_t *peek_scalar(const char *type) noexcept; + simdjson_inline const uint8_t *peek_root_scalar(const char *type) noexcept; + simdjson_inline const uint8_t *peek_non_root_scalar(const char *type) noexcept; + + + simdjson_inline error_code start_container(uint8_t start_char, const char *incorrect_type_message, const char *type) noexcept; + simdjson_inline error_code end_container() noexcept; + + /** + * Advance to a place expecting a value (increasing depth). + * + * @return The current token (the one left behind). + * @error TAPE_ERROR If the document ended early. + */ + simdjson_inline simdjson_result advance_to_value() noexcept; + + simdjson_inline error_code incorrect_type_error(const char *message) const noexcept; + simdjson_inline error_code error_unless_more_tokens(uint32_t tokens=1) const noexcept; + + simdjson_inline bool is_at_start() const noexcept; + /** + * is_at_iterator_start() returns true on an array or object after it has just been + * created, whether the instance is empty or not. + * + * Usage: used by array::begin() in debug mode (SIMDJSON_DEVELOPMENT_CHECKS) + */ + simdjson_inline bool is_at_iterator_start() const noexcept; + + /** + * Assuming that we are within an object, this returns true if we + * are pointing at a key. + * + * Usage: the skip_child() method should never be used while we are pointing + * at a key inside an object. + */ + simdjson_inline bool is_at_key() const noexcept; + + inline void assert_at_start() const noexcept; + inline void assert_at_container_start() const noexcept; + inline void assert_at_root() const noexcept; + inline void assert_at_child() const noexcept; + inline void assert_at_next() const noexcept; + inline void assert_at_non_root_start() const noexcept; + + /** Get the starting position of this value */ + simdjson_inline token_position start_position() const noexcept; + + /** @copydoc error_code json_iterator::position() const noexcept; */ + simdjson_inline token_position position() const noexcept; + /** @copydoc error_code json_iterator::end_position() const noexcept; */ + simdjson_inline token_position last_position() const noexcept; + /** @copydoc error_code json_iterator::end_position() const noexcept; */ + simdjson_inline token_position end_position() const noexcept; + /** @copydoc error_code json_iterator::report_error(error_code error, const char *message) noexcept; */ + simdjson_inline error_code report_error(error_code error, const char *message) noexcept; + + friend class document; + friend class object; + friend class array; + friend class value; +}; // value_iterator + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::value_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H +/* end file simdjson/generic/ondemand/value_iterator.h for haswell */ +/* including simdjson/generic/ondemand/value.h for haswell: #include "simdjson/generic/ondemand/value.h" */ +/* begin file simdjson/generic/ondemand/value.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +/** + * An ephemeral JSON value returned during iteration. It is only valid for as long as you do + * not access more data in the JSON document. + */ +class value { +public: + /** + * Create a new invalid value. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline value() noexcept = default; + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * You may use get_double(), get_bool(), get_uint64(), get_int64(), + * get_object(), get_array(), get_raw_json_string(), or get_string() instead. + * + * @returns A value of the given type, parsed from the JSON. + * @returns INCORRECT_TYPE If the JSON value is not the given type. + */ + template simdjson_inline simdjson_result get() noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * @param out This is set to a value of the given type, parsed from the JSON. If there is an error, this may not be initialized. + * @returns INCORRECT_TYPE If the JSON value is not an object. + * @returns SUCCESS If the parse succeeded and the out parameter was set to the value. + */ + template simdjson_inline error_code get(T &out) noexcept; + + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result get_array() noexcept; + + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @returns INCORRECT_TYPE If the JSON value is not an object. + */ + simdjson_inline simdjson_result get_object() noexcept; + + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A unsigned 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64() noexcept; + + /** + * Cast this JSON value (inside string) to a unsigned integer. + * + * @returns A unsigned 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64() noexcept; + + /** + * Cast this JSON value (inside string) to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64_in_string() noexcept; + + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double() noexcept; + + /** + * Cast this JSON value (inside string) to a double + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double_in_string() noexcept; + + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Equivalent to get(). + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + + /** + * Attempts to fill the provided std::string reference with the parsed value of the current string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory. + * We recommend you avoid allocating an std::string unless you need to. + * + * @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS. + */ + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + + /** + * Cast this JSON value to a "wobbly" string. + * + * The string is may not be a valid UTF-8 string. + * See https://simonsapin.github.io/wtf-8/ + * + * Important: a value should be consumed once. Calling get_wobbly_string() twice on the same value + * is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_wobbly_string() noexcept; + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_raw_json_string() noexcept; + + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @returns INCORRECT_TYPE if the JSON value is not true or false. + */ + simdjson_inline simdjson_result get_bool() noexcept; + + /** + * Checks if this JSON value is null. If and only if the value is + * null, then it is consumed (we advance). If we find a token that + * begins with 'n' but is not 'null', then an error is returned. + * + * @returns Whether the value is null. + * @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'. + */ + simdjson_inline simdjson_result is_null() noexcept; + +#if SIMDJSON_EXCEPTIONS + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an array. + */ + simdjson_inline operator array() noexcept(false); + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an object. + */ + simdjson_inline operator object() noexcept(false); + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline operator uint64_t() noexcept(false); + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer. + */ + simdjson_inline operator int64_t() noexcept(false); + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number. + */ + simdjson_inline operator double() noexcept(false); + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Equivalent to get(). + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator std::string_view() noexcept(false); + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator raw_json_string() noexcept(false); + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false. + */ + simdjson_inline operator bool() noexcept(false); +#endif + + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + * + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result begin() & noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() & noexcept; + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * Performance hint: You should only call count_elements() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method on the object instance. + * + * Performance hint: You should only call count_fields() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Get the value at the given index in the array. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) noexcept; + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) noexcept; + + /** + * Get the type of this JSON value. It does not validate or consume the value. + * E.g., you must still call "is_null()" to check that a value is null even if + * "type()" returns json_type::null. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + * + * @return The type of JSON value (json_type::array, json_type::object, json_type::string, + * json_type::number, json_type::boolean, or json_type::null). + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() noexcept; + + /** + * Checks whether the value is a scalar (string, number, null, Boolean). + * Returns false when there it is an array or object. + * + * @returns true if the type is string, number, null, Boolean + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result is_scalar() noexcept; + + /** + * Checks whether the value is a negative number. + * + * @returns true if the number if negative. + */ + simdjson_inline bool is_negative() noexcept; + /** + * Checks whether the value is an integer number. Note that + * this requires to partially parse the number string. If + * the value is determined to be an integer, it may still + * not parse properly as an integer in subsequent steps + * (e.g., it might overflow). + * + * Performance note: if you call this function systematically + * before parsing a number, you may have fallen for a performance + * anti-pattern. + * + * @returns true if the number if negative. + */ + simdjson_inline simdjson_result is_integer() noexcept; + /** + * Determine the number type (integer or floating-point number) as quickly + * as possible. This function does not fully validate the input. It is + * useful when you only need to classify the numbers, without parsing them. + * + * If you are planning to retrieve the value or you need full validation, + * consider using the get_number() method instead: it will fully parse + * and validate the input, and give you access to the type: + * get_number().get_number_type(). + * + * get_number_type() is number_type::unsigned_integer if we have + * an integer greater or equal to 9223372036854775808 + * get_number_type() is number_type::signed_integer if we have an + * integer that is less than 9223372036854775808 + * Otherwise, get_number_type() has value number_type::floating_point_number + * + * This function requires processing the number string, but it is expected + * to be faster than get_number().get_number_type() because it is does not + * parse the number value. + * + * @returns the type of the number + */ + simdjson_inline simdjson_result get_number_type() noexcept; + + /** + * Attempt to parse an ondemand::number. An ondemand::number may + * contain an integer value or a floating-point value, the simdjson + * library will autodetect the type. Thus it is a dynamically typed + * number. Before accessing the value, you must determine the detected + * type. + * + * number.get_number_type() is number_type::signed_integer if we have + * an integer in [-9223372036854775808,9223372036854775808) + * You can recover the value by calling number.get_int64() and you + * have that number.is_int64() is true. + * + * number.get_number_type() is number_type::unsigned_integer if we have + * an integer in [9223372036854775808,18446744073709551616) + * You can recover the value by calling number.get_uint64() and you + * have that number.is_uint64() is true. + * + * Otherwise, number.get_number_type() has value number_type::floating_point_number + * and we have a binary64 number. + * You can recover the value by calling number.get_double() and you + * have that number.is_double() is true. + * + * You must check the type before accessing the value: it is an error + * to call "get_int64()" when number.get_number_type() is not + * number_type::signed_integer and when number.is_int64() is false. + * + * Performance note: this is designed with performance in mind. When + * calling 'get_number()', you scan the number string only once, determining + * efficiently the type and storing it in an efficient manner. + */ + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + + /** + * Get the raw JSON for this token. + * + * The string_view will always point into the input buffer. + * + * The string_view will start at the beginning of the token, and include the entire token + * *as well as all spaces until the next token (or EOF).* This means, for example, that a + * string token always begins with a " and is always terminated by the final ", possibly + * followed by a number of spaces. + * + * The string_view is *not* null-terminated. However, if this is a scalar (string, number, + * boolean, or null), the character after the end of the string_view is guaranteed to be + * a non-space token. + * + * Tokens include: + * - { + * - [ + * - "a string (possibly with UTF-8 or backslashed characters like \\\")". + * - -1.2e-100 + * - true + * - false + * - null + * + * See also value::raw_json(). + */ + simdjson_inline std::string_view raw_json_token() noexcept; + + /** + * Get a string_view pointing at this value in the JSON document. + * If this element is an array or an object, it consumes the array or the object + * and returns a string_view instance corresponding to the + * array as represented in JSON. It points inside the original document. + * If this element is a scalar (string, number, Boolean, null), it returns what + * raw_json_token() would return. + */ + simdjson_inline simdjson_result raw_json() noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + simdjson_inline simdjson_result current_location() noexcept; + + /** + * Returns the current depth in the document if in bounds. + * + * E.g., + * 0 = finished with document + * 1 = document root value (could be [ or {, not yet known) + * 2 = , or } inside root array/object + * 3 = key or value inside root array/object. + */ + simdjson_inline int32_t current_depth() const noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. + * + * Calling at_pointer() on non-document instances (e.g., arrays and objects) is not + * standardized (by RFC 6901). We provide some experimental support for JSON pointers + * on non-document instances. Yet it is not the case when calling at_pointer on an array + * or an object instance: there is no rewind and no invalidation. + * + * You may only call at_pointer on an array after it has been created, but before it has + * been first accessed. When calling at_pointer on an array, the pointer is advanced to + * the location indicated by the JSON pointer (in case of success). It is no longer possible + * to call at_pointer on the same array. + * + * You may call at_pointer more than once on an object, but each time the pointer is advanced + * to be within the value matched by the key indicated by the JSON pointer query. Thus any preceding + * key (as well as the current key) can no longer be used with following JSON pointer calls. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + +protected: + /** + * Create a value. + */ + simdjson_inline value(const value_iterator &iter) noexcept; + + /** + * Skip this value, allowing iteration to continue. + */ + simdjson_inline void skip() noexcept; + + /** + * Start a value at the current position. + * + * (It should already be started; this is just a self-documentation method.) + */ + static simdjson_inline value start(const value_iterator &iter) noexcept; + + /** + * Resume a value. + */ + static simdjson_inline value resume(const value_iterator &iter) noexcept; + + /** + * Get the object, starting or resuming it as necessary + */ + simdjson_inline simdjson_result start_or_resume_object() noexcept; + + // simdjson_inline void log_value(const char *type) const noexcept; + // simdjson_inline void log_error(const char *message) const noexcept; + + value_iterator iter{}; + + friend class document; + friend class array_iterator; + friend class field; + friend class object; + friend struct simdjson_result; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::value &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result get_array() noexcept; + simdjson_inline simdjson_result get_object() noexcept; + + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + + template simdjson_inline simdjson_result get() noexcept; + + template simdjson_inline error_code get(T &out) noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator haswell::ondemand::array() noexcept(false); + simdjson_inline operator haswell::ondemand::object() noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator haswell::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) noexcept; + + /** + * Get the type of this JSON value. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + */ + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + + /** @copydoc simdjson_inline std::string_view value::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + + /** @copydoc simdjson_inline simdjson_result current_location() noexcept */ + simdjson_inline simdjson_result current_location() noexcept; + /** @copydoc simdjson_inline int32_t current_depth() const noexcept */ + simdjson_inline simdjson_result current_depth() const noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_H +/* end file simdjson/generic/ondemand/value.h for haswell */ +/* including simdjson/generic/ondemand/logger.h for haswell: #include "simdjson/generic/ondemand/logger.h" */ +/* begin file simdjson/generic/ondemand/logger.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_LOGGER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_LOGGER_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +// Logging should be free unless SIMDJSON_VERBOSE_LOGGING is set. Importantly, it is critical +// that the call to the log functions be side-effect free. Thus, for example, you should not +// create temporary std::string instances. +namespace logger { + +enum class log_level : int32_t { + info = 0, + error = 1 +}; + +#if SIMDJSON_VERBOSE_LOGGING + static constexpr const bool LOG_ENABLED = true; +#else + static constexpr const bool LOG_ENABLED = false; +#endif + +// We do not want these functions to be 'really inlined' since real inlining is +// for performance purposes and if you are using the loggers, you do not care about +// performance (or should not). +static inline void log_headers() noexcept; +// If args are provided, title will be treated as format string +template +static inline void log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +template +static inline void log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; +static inline void log_event(const json_iterator &iter, const char *type, std::string_view detail="", int delta=0, int depth_delta=0) noexcept; +static inline void log_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail="") noexcept; +static inline void log_value(const json_iterator &iter, const char *type, std::string_view detail="", int delta=-1, int depth_delta=0) noexcept; +static inline void log_start_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail="") noexcept; +static inline void log_start_value(const json_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_end_value(const json_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; + +static inline void log_error(const json_iterator &iter, token_position index, depth_t depth, const char *error, const char *detail="") noexcept; +static inline void log_error(const json_iterator &iter, const char *error, const char *detail="", int delta=-1, int depth_delta=0) noexcept; + +static inline void log_event(const value_iterator &iter, const char *type, std::string_view detail="", int delta=0, int depth_delta=0) noexcept; +static inline void log_value(const value_iterator &iter, const char *type, std::string_view detail="", int delta=-1, int depth_delta=0) noexcept; +static inline void log_start_value(const value_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_end_value(const value_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_error(const value_iterator &iter, const char *error, const char *detail="", int delta=-1, int depth_delta=0) noexcept; + +} // namespace logger +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_LOGGER_H +/* end file simdjson/generic/ondemand/logger.h for haswell */ +/* including simdjson/generic/ondemand/token_iterator.h for haswell: #include "simdjson/generic/ondemand/token_iterator.h" */ +/* begin file simdjson/generic/ondemand/token_iterator.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +/** + * Iterates through JSON tokens (`{` `}` `[` `]` `,` `:` `""` `123` `true` `false` `null`) + * detected by stage 1. + * + * @private This is not intended for external use. + */ +class token_iterator { +public: + /** + * Create a new invalid token_iterator. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline token_iterator() noexcept = default; + simdjson_inline token_iterator(token_iterator &&other) noexcept = default; + simdjson_inline token_iterator &operator=(token_iterator &&other) noexcept = default; + simdjson_inline token_iterator(const token_iterator &other) noexcept = default; + simdjson_inline token_iterator &operator=(const token_iterator &other) noexcept = default; + + /** + * Advance to the next token (returning the current one). + */ + simdjson_inline const uint8_t *return_current_and_advance() noexcept; + /** + * Reports the current offset in bytes from the start of the underlying buffer. + */ + simdjson_inline uint32_t current_offset() const noexcept; + /** + * Get the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(int32_t delta=0) const noexcept; + /** + * Get the maximum length of the JSON text for a given token. + * + * The length will include any whitespace at the end of the token. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_length(int32_t delta=0) const noexcept; + + /** + * Get the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token. + * + */ + simdjson_inline const uint8_t *peek(token_position position) const noexcept; + /** + * Get the maximum length of the JSON text for a given token. + * + * The length will include any whitespace at the end of the token. + * + * @param position The position of the token. + */ + simdjson_inline uint32_t peek_length(token_position position) const noexcept; + + /** + * Return the current index. + */ + simdjson_inline token_position position() const noexcept; + /** + * Reset to a previously saved index. + */ + simdjson_inline void set_position(token_position target_position) noexcept; + + // NOTE: we don't support a full C++ iterator interface, because we expect people to make + // different calls to advance the iterator based on *their own* state. + + simdjson_inline bool operator==(const token_iterator &other) const noexcept; + simdjson_inline bool operator!=(const token_iterator &other) const noexcept; + simdjson_inline bool operator>(const token_iterator &other) const noexcept; + simdjson_inline bool operator>=(const token_iterator &other) const noexcept; + simdjson_inline bool operator<(const token_iterator &other) const noexcept; + simdjson_inline bool operator<=(const token_iterator &other) const noexcept; + +protected: + simdjson_inline token_iterator(const uint8_t *buf, token_position position) noexcept; + + /** + * Get the index of the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_index(int32_t delta=0) const noexcept; + /** + * Get the index of the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token. + * + */ + simdjson_inline uint32_t peek_index(token_position position) const noexcept; + + const uint8_t *buf{}; + token_position _position{}; + + friend class json_iterator; + friend class value_iterator; + friend class object; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +}; + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::token_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H +/* end file simdjson/generic/ondemand/token_iterator.h for haswell */ +/* including simdjson/generic/ondemand/json_iterator.h for haswell: #include "simdjson/generic/ondemand/json_iterator.h" */ +/* begin file simdjson/generic/ondemand/json_iterator.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +/** + * Iterates through JSON tokens, keeping track of depth and string buffer. + * + * @private This is not intended for external use. + */ +class json_iterator { +protected: + token_iterator token{}; + ondemand::parser *parser{}; + /** + * Next free location in the string buffer. + * + * Used by raw_json_string::unescape() to have a place to unescape strings to. + */ + uint8_t *_string_buf_loc{}; + /** + * JSON error, if there is one. + * + * INCORRECT_TYPE and NO_SUCH_FIELD are *not* stored here, ever. + * + * PERF NOTE: we *hope* this will be elided into control flow, as it is only used (a) in the first + * iteration of the loop, or (b) for the final iteration after a missing comma is found in ++. If + * this is not elided, we should make sure it's at least not using up a register. Failing that, + * we should store it in document so there's only one of them. + */ + error_code error{SUCCESS}; + /** + * Depth of the current token in the JSON. + * + * - 0 = finished with document + * - 1 = document root value (could be [ or {, not yet known) + * - 2 = , or } inside root array/object + * - 3 = key or value inside root array/object. + */ + depth_t _depth{}; + /** + * Beginning of the document indexes. + * Normally we have root == parser->implementation->structural_indexes.get() + * but this may differ, especially in streaming mode (where we have several + * documents); + */ + token_position _root{}; + /** + * Normally, a json_iterator operates over a single document, but in + * some cases, we may have a stream of documents. This attribute is meant + * as meta-data: the json_iterator works the same irrespective of the + * value of this attribute. + */ + bool _streaming{false}; + +public: + simdjson_inline json_iterator() noexcept = default; + simdjson_inline json_iterator(json_iterator &&other) noexcept; + simdjson_inline json_iterator &operator=(json_iterator &&other) noexcept; + simdjson_inline explicit json_iterator(const json_iterator &other) noexcept = default; + simdjson_inline json_iterator &operator=(const json_iterator &other) noexcept = default; + /** + * Skips a JSON value, whether it is a scalar, array or object. + */ + simdjson_warn_unused simdjson_inline error_code skip_child(depth_t parent_depth) noexcept; + + /** + * Tell whether the iterator is still at the start + */ + simdjson_inline bool at_root() const noexcept; + + /** + * Tell whether we should be expected to run in streaming + * mode (iterating over many documents). It is pure metadata + * that does not affect how the iterator works. It is used by + * start_root_array() and start_root_object(). + */ + simdjson_inline bool streaming() const noexcept; + + /** + * Get the root value iterator + */ + simdjson_inline token_position root_position() const noexcept; + /** + * Assert that we are at the document depth (== 1) + */ + simdjson_inline void assert_at_document_depth() const noexcept; + /** + * Assert that we are at the root of the document + */ + simdjson_inline void assert_at_root() const noexcept; + + /** + * Tell whether the iterator is at the EOF mark + */ + simdjson_inline bool at_end() const noexcept; + + /** + * Tell whether the iterator is live (has not been moved). + */ + simdjson_inline bool is_alive() const noexcept; + + /** + * Abandon this iterator, setting depth to 0 (as if the document is finished). + */ + simdjson_inline void abandon() noexcept; + + /** + * Advance the current token without modifying depth. + */ + simdjson_inline const uint8_t *return_current_and_advance() noexcept; + + /** + * Returns true if there is a single token in the index (i.e., it is + * a JSON with a scalar value such as a single number). + * + * @return whether there is a single token + */ + simdjson_inline bool is_single_token() const noexcept; + + /** + * Assert that there are at least the given number of tokens left. + * + * Has no effect in release builds. + */ + simdjson_inline void assert_more_tokens(uint32_t required_tokens=1) const noexcept; + /** + * Assert that the given position addresses an actual token (is within bounds). + * + * Has no effect in release builds. + */ + simdjson_inline void assert_valid_position(token_position position) const noexcept; + /** + * Get the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = next token, -1 = prev token. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(int32_t delta=0) const noexcept; + /** + * Get the maximum length of the JSON text for the current token (or relative). + * + * The length will include any whitespace at the end of the token. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_length(int32_t delta=0) const noexcept; + /** + * Get a pointer to the current location in the input buffer. + * + * This is not null-terminated; it is a view into the JSON. + * + * You may be pointing outside of the input buffer: it is not generally + * safe to dereference this pointer. + */ + simdjson_inline const uint8_t *unsafe_pointer() const noexcept; + /** + * Get the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token to retrieve. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(token_position position) const noexcept; + /** + * Get the maximum length of the JSON text for the current token (or relative). + * + * The length will include any whitespace at the end of the token. + * + * @param position The position of the token to retrieve. + */ + simdjson_inline uint32_t peek_length(token_position position) const noexcept; + /** + * Get the JSON text for the last token in the document. + * + * This is not null-terminated; it is a view into the JSON. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek_last() const noexcept; + + /** + * Ascend one level. + * + * Validates that the depth - 1 == parent_depth. + * + * @param parent_depth the expected parent depth. + */ + simdjson_inline void ascend_to(depth_t parent_depth) noexcept; + + /** + * Descend one level. + * + * Validates that the new depth == child_depth. + * + * @param child_depth the expected child depth. + */ + simdjson_inline void descend_to(depth_t child_depth) noexcept; + simdjson_inline void descend_to(depth_t child_depth, int32_t delta) noexcept; + + /** + * Get current depth. + */ + simdjson_inline depth_t depth() const noexcept; + + /** + * Get current (writeable) location in the string buffer. + */ + simdjson_inline uint8_t *&string_buf_loc() noexcept; + + /** + * Report an unrecoverable error, preventing further iteration. + * + * @param error The error to report. Must not be SUCCESS, UNINITIALIZED, INCORRECT_TYPE, or NO_SUCH_FIELD. + * @param message An error message to report with the error. + */ + simdjson_inline error_code report_error(error_code error, const char *message) noexcept; + + /** + * Log error, but don't stop iteration. + * @param error The error to report. Must be INCORRECT_TYPE, or NO_SUCH_FIELD. + * @param message An error message to report with the error. + */ + simdjson_inline error_code optional_error(error_code error, const char *message) noexcept; + + /** + * Take an input in json containing max_len characters and attempt to copy it over to tmpbuf, a buffer with + * N bytes of capacity. It will return false if N is too small (smaller than max_len) of if it is zero. + * The buffer (tmpbuf) is padded with space characters. + */ + simdjson_warn_unused simdjson_inline bool copy_to_buffer(const uint8_t *json, uint32_t max_len, uint8_t *tmpbuf, size_t N) noexcept; + + simdjson_inline token_position position() const noexcept; + /** + * Write the raw_json_string to the string buffer and return a string_view. + * Each raw_json_string should be unescaped once, or else the string buffer might + * overflow. + */ + simdjson_inline simdjson_result unescape(raw_json_string in, bool allow_replacement) noexcept; + simdjson_inline simdjson_result unescape_wobbly(raw_json_string in) noexcept; + + simdjson_inline void reenter_child(token_position position, depth_t child_depth) noexcept; + + simdjson_inline error_code consume_character(char c) noexcept; +#if SIMDJSON_DEVELOPMENT_CHECKS + simdjson_inline token_position start_position(depth_t depth) const noexcept; + simdjson_inline void set_start_position(depth_t depth, token_position position) noexcept; +#endif + + /* Useful for debugging and logging purposes. */ + inline std::string to_string() const noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + inline simdjson_result current_location() const noexcept; + + /** + * Updates this json iterator so that it is back at the beginning of the document, + * as if it had just been created. + */ + inline void rewind() noexcept; + /** + * This checks whether the {,},[,] are balanced so that the document + * ends with proper zero depth. This requires scanning the whole document + * and it may be expensive. It is expected that it will be rarely called. + * It does not attempt to match { with } and [ with ]. + */ + inline bool balanced() const noexcept; +protected: + simdjson_inline json_iterator(const uint8_t *buf, ondemand::parser *parser) noexcept; + /// The last token before the end + simdjson_inline token_position last_position() const noexcept; + /// The token *at* the end. This points at gibberish and should only be used for comparison. + simdjson_inline token_position end_position() const noexcept; + /// The end of the buffer. + simdjson_inline token_position end() const noexcept; + + friend class document; + friend class document_stream; + friend class object; + friend class array; + friend class value; + friend class raw_json_string; + friend class parser; + friend class value_iterator; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +}; // json_iterator + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::json_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H +/* end file simdjson/generic/ondemand/json_iterator.h for haswell */ +/* including simdjson/generic/ondemand/json_type.h for haswell: #include "simdjson/generic/ondemand/json_type.h" */ +/* begin file simdjson/generic/ondemand/json_type.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/numberparsing.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +/** + * The type of a JSON value. + */ +enum class json_type { + // Start at 1 to catch uninitialized / default values more easily + array=1, ///< A JSON array ( [ 1, 2, 3 ... ] ) + object, ///< A JSON object ( { "a": 1, "b" 2, ... } ) + number, ///< A JSON number ( 1 or -2.3 or 4.5e6 ...) + string, ///< A JSON string ( "a" or "hello world\n" ...) + boolean, ///< A JSON boolean (true or false) + null ///< A JSON null (null) +}; + +/** + * A type representing a JSON number. + * The design of the struct is deliberately straight-forward. All + * functions return standard values with no error check. + */ +struct number { + + /** + * return the automatically determined type of + * the number: number_type::floating_point_number, + * number_type::signed_integer or number_type::unsigned_integer. + * + * enum class number_type { + * floating_point_number=1, /// a binary64 number + * signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + * unsigned_integer /// a positive integer larger or equal to 1<<63 + * }; + */ + simdjson_inline ondemand::number_type get_number_type() const noexcept; + /** + * return true if the automatically determined type of + * the number is number_type::unsigned_integer. + */ + simdjson_inline bool is_uint64() const noexcept; + /** + * return the value as a uint64_t, only valid if is_uint64() is true. + */ + simdjson_inline uint64_t get_uint64() const noexcept; + simdjson_inline operator uint64_t() const noexcept; + + /** + * return true if the automatically determined type of + * the number is number_type::signed_integer. + */ + simdjson_inline bool is_int64() const noexcept; + /** + * return the value as a int64_t, only valid if is_int64() is true. + */ + simdjson_inline int64_t get_int64() const noexcept; + simdjson_inline operator int64_t() const noexcept; + + + /** + * return true if the automatically determined type of + * the number is number_type::floating_point_number. + */ + simdjson_inline bool is_double() const noexcept; + /** + * return the value as a double, only valid if is_double() is true. + */ + simdjson_inline double get_double() const noexcept; + simdjson_inline operator double() const noexcept; + + /** + * Convert the number to a double. Though it always succeed, the conversion + * may be lossy if the number cannot be represented exactly. + */ + simdjson_inline double as_double() const noexcept; + + +protected: + /** + * The next block of declaration is designed so that we can call the number parsing + * functions on a number type. They are protected and should never be used outside + * of the core simdjson library. + */ + friend class value_iterator; + template + friend error_code numberparsing::write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer); + template + friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer); + /** Store a signed 64-bit value to the number. */ + simdjson_inline void append_s64(int64_t value) noexcept; + /** Store an unsigned 64-bit value to the number. */ + simdjson_inline void append_u64(uint64_t value) noexcept; + /** Store a double value to the number. */ + simdjson_inline void append_double(double value) noexcept; + /** Specifies that the value is a double, but leave it undefined. */ + simdjson_inline void skip_double() noexcept; + /** + * End of friend declarations. + */ + + /** + * Our attributes are a union type (size = 64 bits) + * followed by a type indicator. + */ + union { + double floating_point_number; + int64_t signed_integer; + uint64_t unsigned_integer; + } payload{0}; + number_type type{number_type::signed_integer}; +}; + +/** + * Write the JSON type to the output stream + * + * @param out The output stream. + * @param type The json_type. + */ +inline std::ostream& operator<<(std::ostream& out, json_type type) noexcept; + +#if SIMDJSON_EXCEPTIONS +/** + * Send JSON type to an output stream. + * + * @param out The output stream. + * @param type The json_type. + * @throw simdjson_error if the result being printed has an error. If there is an error with the + * underlying output stream, that error will be propagated (simdjson_error will not be + * thrown). + */ +inline std::ostream& operator<<(std::ostream& out, simdjson_result &type) noexcept(false); +#endif + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::json_type &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H +/* end file simdjson/generic/ondemand/json_type.h for haswell */ +/* including simdjson/generic/ondemand/raw_json_string.h for haswell: #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* begin file simdjson/generic/ondemand/raw_json_string.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +/** + * A string escaped per JSON rules, terminated with quote ("). They are used to represent + * unescaped keys inside JSON documents. + * + * (In other words, a pointer to the beginning of a string, just after the start quote, inside a + * JSON file.) + * + * This class is deliberately simplistic and has little functionality. You can + * compare a raw_json_string instance with an unescaped C string, but + * that is nearly all you can do. + * + * The raw_json_string is unescaped. If you wish to write an unescaped version of it to your own + * buffer, you may do so using the parser.unescape(string, buff) method, using an ondemand::parser + * instance. Doing so requires you to have a sufficiently large buffer. + * + * The raw_json_string instances originate typically from field instance which in turn represent + * key-value pairs from object instances. From a field instance, you get the raw_json_string + * instance by calling key(). You can, if you want a more usable string_view instance, call + * the unescaped_key() method on the field instance. You may also create a raw_json_string from + * any other string value, with the value.get_raw_json_string() method. Again, you can get + * a more usable string_view instance by calling get_string(). + * + */ +class raw_json_string { +public: + /** + * Create a new invalid raw_json_string. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline raw_json_string() noexcept = default; + + /** + * Create a new invalid raw_json_string pointed at the given location in the JSON. + * + * The given location must be just *after* the beginning quote (") in the JSON file. + * + * It *must* be terminated by a ", and be a valid JSON string. + */ + simdjson_inline raw_json_string(const uint8_t * _buf) noexcept; + /** + * Get the raw pointer to the beginning of the string in the JSON (just after the "). + * + * It is possible for this function to return a null pointer if the instance + * has outlived its existence. + */ + simdjson_inline const char * raw() const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done) on target.size() characters, + * and if the raw_json_string instance has a quote character at byte index target.size(). + * We never read more than length + 1 bytes in the raw_json_string instance. + * If length is smaller than target.size(), this will return false. + * + * The std::string_view instance may contain any characters. However, the caller + * is responsible for setting length so that length bytes may be read in the + * raw_json_string. + * + * Performance: the comparison may be done using memcmp which may be efficient + * for long strings. + */ + simdjson_inline bool unsafe_is_equal(size_t length, std::string_view target) const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done). + * The std::string_view instance should not contain unescaped quote characters: + * the caller is responsible for this check. See is_free_from_unescaped_quote. + * + * Performance: the comparison is done byte-by-byte which might be inefficient for + * long strings. + * + * If target is a compile-time constant, and your compiler likes you, + * you should be able to do the following without performance penalty... + * + * static_assert(raw_json_string::is_free_from_unescaped_quote(target), ""); + * s.unsafe_is_equal(target); + */ + simdjson_inline bool unsafe_is_equal(std::string_view target) const noexcept; + + /** + * This compares the current instance to the C string target: returns true if + * they are byte-by-byte equal (no escaping is done). + * The provided C string should not contain an unescaped quote character: + * the caller is responsible for this check. See is_free_from_unescaped_quote. + * + * If target is a compile-time constant, and your compiler likes you, + * you should be able to do the following without performance penalty... + * + * static_assert(raw_json_string::is_free_from_unescaped_quote(target), ""); + * s.unsafe_is_equal(target); + */ + simdjson_inline bool unsafe_is_equal(const char* target) const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done). + */ + simdjson_inline bool is_equal(std::string_view target) const noexcept; + + /** + * This compares the current instance to the C string target: returns true if + * they are byte-by-byte equal (no escaping is done). + */ + simdjson_inline bool is_equal(const char* target) const noexcept; + + /** + * Returns true if target is free from unescaped quote. If target is known at + * compile-time, we might expect the computation to happen at compile time with + * many compilers (not all!). + */ + static simdjson_inline bool is_free_from_unescaped_quote(std::string_view target) noexcept; + static simdjson_inline bool is_free_from_unescaped_quote(const char* target) noexcept; + +private: + + + /** + * This will set the inner pointer to zero, effectively making + * this instance unusable. + */ + simdjson_inline void consume() noexcept { buf = nullptr; } + + /** + * Checks whether the inner pointer is non-null and thus usable. + */ + simdjson_inline simdjson_warn_unused bool alive() const noexcept { return buf != nullptr; } + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. + * The result will be a valid UTF-8. + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid until the next parse() call on the parser. + * + * @param iter A json_iterator, which contains a buffer where the string will be written. + * @param allow_replacement Whether we allow replacement of invalid surrogate pairs. + */ + simdjson_inline simdjson_warn_unused simdjson_result unescape(json_iterator &iter, bool allow_replacement) const noexcept; + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. + * The result may not be a valid UTF-8. https://simonsapin.github.io/wtf-8/ + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid until the next parse() call on the parser. + * + * @param iter A json_iterator, which contains a buffer where the string will be written. + */ + simdjson_inline simdjson_warn_unused simdjson_result unescape_wobbly(json_iterator &iter) const noexcept; + const uint8_t * buf{}; + friend class object; + friend class field; + friend class parser; + friend struct simdjson_result; +}; + +simdjson_unused simdjson_inline std::ostream &operator<<(std::ostream &, const raw_json_string &) noexcept; + +/** + * Comparisons between raw_json_string and std::string_view instances are potentially unsafe: the user is responsible + * for providing a string with no unescaped quote. Note that unescaped quotes cannot be present in valid JSON strings. + */ +simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept; +simdjson_unused simdjson_inline bool operator==(std::string_view c, const raw_json_string &a) noexcept; +simdjson_unused simdjson_inline bool operator!=(const raw_json_string &a, std::string_view c) noexcept; +simdjson_unused simdjson_inline bool operator!=(std::string_view c, const raw_json_string &a) noexcept; + + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::raw_json_string &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private + + simdjson_inline simdjson_result raw() const noexcept; + simdjson_inline simdjson_warn_unused simdjson_result unescape(haswell::ondemand::json_iterator &iter, bool allow_replacement) const noexcept; + simdjson_inline simdjson_warn_unused simdjson_result unescape_wobbly(haswell::ondemand::json_iterator &iter) const noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H +/* end file simdjson/generic/ondemand/raw_json_string.h for haswell */ +/* including simdjson/generic/ondemand/parser.h for haswell: #include "simdjson/generic/ondemand/parser.h" */ +/* begin file simdjson/generic/ondemand/parser.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_PARSER_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace haswell { +namespace ondemand { + +/** + * The default batch size for document_stream instances for this On Demand kernel. + * Note that different On Demand kernel may use a different DEFAULT_BATCH_SIZE value + * in the future. + */ +static constexpr size_t DEFAULT_BATCH_SIZE = 1000000; +/** + * Some adversary might try to set the batch size to 0 or 1, which might cause problems. + * We set a minimum of 32B since anything else is highly likely to be an error. In practice, + * most users will want a much larger batch size. + * + * All non-negative MINIMAL_BATCH_SIZE values should be 'safe' except that, obviously, no JSON + * document can ever span 0 or 1 byte and that very large values would create memory allocation issues. + */ +static constexpr size_t MINIMAL_BATCH_SIZE = 32; + +/** + * A JSON fragment iterator. + * + * This holds the actual iterator as well as the buffer for writing strings. + */ +class parser { +public: + /** + * Create a JSON parser. + * + * The new parser will have zero capacity. + */ + inline explicit parser(size_t max_capacity = SIMDJSON_MAXSIZE_BYTES) noexcept; + + inline parser(parser &&other) noexcept = default; + simdjson_inline parser(const parser &other) = delete; + simdjson_inline parser &operator=(const parser &other) = delete; + simdjson_inline parser &operator=(parser &&other) noexcept = default; + + /** Deallocate the JSON parser. */ + inline ~parser() noexcept = default; + + /** + * Start iterating an on-demand JSON document. + * + * ondemand::parser parser; + * document doc = parser.iterate(json); + * + * It is expected that the content is a valid UTF-8 file, containing a valid JSON document. + * Otherwise the iterate method may return an error. In particular, the whole input should be + * valid: we do not attempt to tolerate incorrect content either before or after a JSON + * document. If there is a UTF-8 BOM, the parser skips it. + * + * ### IMPORTANT: Validate what you use + * + * Calling iterate on an invalid JSON document may not immediately trigger an error. The call to + * iterate does not parse and validate the whole document. + * + * ### IMPORTANT: Buffer Lifetime + * + * Because parsing is done while you iterate, you *must* keep the JSON buffer around at least as + * long as the document iteration. + * + * ### IMPORTANT: Document Lifetime + * + * Only one iteration at a time can happen per parser, and the parser *must* be kept alive during + * iteration to ensure intermediate buffers can be accessed. Any document must be destroyed before + * you call parse() again or destroy the parser. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * @param json The JSON to parse. + * @param len The length of the JSON. + * @param capacity The number of bytes allocated in the JSON (must be at least len+SIMDJSON_PADDING). + * + * @return The document, or an error: + * - INSUFFICIENT_PADDING if the input has less than SIMDJSON_PADDING extra bytes. + * - MEMALLOC if realloc_if_needed the parser does not have enough capacity, and memory + * allocation fails. + * - EMPTY if the document is all whitespace. + * - UTF8_ERROR if the document is not valid UTF-8. + * - UNESCAPED_CHARS if a string contains control characters that must be escaped + * - UNCLOSED_STRING if there is an unclosed string in the document. + */ + simdjson_warn_unused simdjson_result iterate(padded_string_view json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const char *json, size_t len, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const uint8_t *json, size_t len, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(std::string_view json, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const std::string &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(std::string &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const simdjson_result &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const simdjson_result &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(padded_string &&json) & noexcept = delete; + + /** + * @private + * + * Start iterating an on-demand JSON document. + * + * ondemand::parser parser; + * json_iterator doc = parser.iterate(json); + * + * ### IMPORTANT: Buffer Lifetime + * + * Because parsing is done while you iterate, you *must* keep the JSON buffer around at least as + * long as the document iteration. + * + * ### IMPORTANT: Document Lifetime + * + * Only one iteration at a time can happen per parser, and the parser *must* be kept alive during + * iteration to ensure intermediate buffers can be accessed. Any document must be destroyed before + * you call parse() again or destroy the parser. + * + * The ondemand::document instance holds the iterator. The document must remain in scope + * while you are accessing instances of ondemand::value, ondemand::object, ondemand::array. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * @param json The JSON to parse. + * + * @return The iterator, or an error: + * - INSUFFICIENT_PADDING if the input has less than SIMDJSON_PADDING extra bytes. + * - MEMALLOC if realloc_if_needed the parser does not have enough capacity, and memory + * allocation fails. + * - EMPTY if the document is all whitespace. + * - UTF8_ERROR if the document is not valid UTF-8. + * - UNESCAPED_CHARS if a string contains control characters that must be escaped + * - UNCLOSED_STRING if there is an unclosed string in the document. + */ + simdjson_warn_unused simdjson_result iterate_raw(padded_string_view json) & noexcept; + + + /** + * Parse a buffer containing many JSON documents. + * + * auto json = R"({ "foo": 1 } { "foo": 2 } { "foo": 3 } )"_padded; + * ondemand::parser parser; + * ondemand::document_stream docs = parser.iterate_many(json); + * for (auto & doc : docs) { + * std::cout << doc["foo"] << std::endl; + * } + * // Prints 1 2 3 + * + * No copy of the input buffer is made. + * + * The function is lazy: it may be that no more than one JSON document at a time is parsed. + * + * The caller is responsabile to ensure that the input string data remains unchanged and is + * not deleted during the loop. + * + * ### Format + * + * The buffer must contain a series of one or more JSON documents, concatenated into a single + * buffer, separated by ASCII whitespace. It effectively parses until it has a fully valid document, + * then starts parsing the next document at that point. (It does this with more parallelism and + * lookahead than you might think, though.) + * + * documents that consist of an object or array may omit the whitespace between them, concatenating + * with no separator. Documents that consist of a single primitive (i.e. documents that are not + * arrays or objects) MUST be separated with ASCII whitespace. + * + * The characters inside a JSON document, and between JSON documents, must be valid Unicode (UTF-8). + * If there is a UTF-8 BOM, the parser skips it. + * + * The documents must not exceed batch_size bytes (by default 1MB) or they will fail to parse. + * Setting batch_size to excessively large or excessively small values may impact negatively the + * performance. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * ### Threads + * + * When compiled with SIMDJSON_THREADS_ENABLED, this method will use a single thread under the + * hood to do some lookahead. + * + * ### Parser Capacity + * + * If the parser's current capacity is less than batch_size, it will allocate enough capacity + * to handle it (up to max_capacity). + * + * @param buf The concatenated JSON to parse. + * @param len The length of the concatenated JSON. + * @param batch_size The batch size to use. MUST be larger than the largest document. The sweet + * spot is cache-related: small enough to fit in cache, yet big enough to + * parse as many documents as possible in one tight loop. + * Defaults to 10MB, which has been a reasonable sweet spot in our tests. + * @param allow_comma_separated (defaults on false) This allows a mode where the documents are + * separated by commas instead of whitespace. It comes with a performance + * penalty because the entire document is indexed at once (and the document must be + * less than 4 GB), and there is no multithreading. In this mode, the batch_size parameter + * is effectively ignored, as it is set to at least the document size. + * @return The stream, or an error. An empty input will yield 0 documents rather than an EMPTY error. Errors: + * - MEMALLOC if the parser does not have enough capacity and memory allocation fails + * - CAPACITY if the parser does not have enough capacity and batch_size > max_capacity. + * - other json errors if parsing fails. You should not rely on these errors to always the same for the + * same document: they may vary under runtime dispatch (so they may vary depending on your system and hardware). + */ + inline simdjson_result iterate_many(const uint8_t *buf, size_t len, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const char *buf, size_t len, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const std::string &s, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + inline simdjson_result iterate_many(const std::string &&s, size_t batch_size, bool allow_comma_separated = false) = delete;// unsafe + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const padded_string &s, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + inline simdjson_result iterate_many(const padded_string &&s, size_t batch_size, bool allow_comma_separated = false) = delete;// unsafe + + /** @private We do not want to allow implicit conversion from C string to std::string. */ + simdjson_result iterate_many(const char *buf, size_t batch_size = DEFAULT_BATCH_SIZE) noexcept = delete; + + /** The capacity of this parser (the largest document it can process). */ + simdjson_inline size_t capacity() const noexcept; + /** The maximum capacity of this parser (the largest document it is allowed to process). */ + simdjson_inline size_t max_capacity() const noexcept; + simdjson_inline void set_max_capacity(size_t max_capacity) noexcept; + /** + * The maximum depth of this parser (the most deeply nested objects and arrays it can process). + * This parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true. + * The document's instance current_depth() method should be used to monitor the parsing + * depth and limit it if desired. + */ + simdjson_inline size_t max_depth() const noexcept; + + /** + * Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length + * and `max_depth` depth. + * + * The max_depth parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true. + * The document's instance current_depth() method should be used to monitor the parsing + * depth and limit it if desired. + * + * @param capacity The new capacity. + * @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH. + * @return The error, if there is one. + */ + simdjson_warn_unused error_code allocate(size_t capacity, size_t max_depth=DEFAULT_MAX_DEPTH) noexcept; + + #ifdef SIMDJSON_THREADS_ENABLED + /** + * The parser instance can use threads when they are available to speed up some + * operations. It is enabled by default. Changing this attribute will change the + * behavior of the parser for future operations. + */ + bool threaded{true}; + #endif + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. to a user-provided buffer. + * The result must be valid UTF-8. + * The provided pointer is advanced to the end of the string by reference, and a string_view instance + * is returned. You can ensure that your buffer is large enough by allocating a block of memory at least + * as large as the input JSON plus SIMDJSON_PADDING and then unescape all strings to this one buffer. + * + * This unescape function is a low-level function. If you want a more user-friendly approach, you should + * avoid raw_json_string instances (e.g., by calling unescaped_key() instead of key() or get_string() + * instead of get_raw_json_string()). + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid as long as the bytes in dst. + * + * @param raw_json_string input + * @param dst A pointer to a buffer at least large enough to write this string as well as + * an additional SIMDJSON_PADDING bytes. + * @param allow_replacement Whether we allow a replacement if the input string contains unmatched surrogate pairs. + * @return A string_view pointing at the unescaped string in dst + * @error STRING_ERROR if escapes are incorrect. + */ + simdjson_inline simdjson_result unescape(raw_json_string in, uint8_t *&dst, bool allow_replacement = false) const noexcept; + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. to a user-provided buffer. + * The result may not be valid UTF-8. See https://simonsapin.github.io/wtf-8/ + * The provided pointer is advanced to the end of the string by reference, and a string_view instance + * is returned. You can ensure that your buffer is large enough by allocating a block of memory at least + * as large as the input JSON plus SIMDJSON_PADDING and then unescape all strings to this one buffer. + * + * This unescape function is a low-level function. If you want a more user-friendly approach, you should + * avoid raw_json_string instances (e.g., by calling unescaped_key() instead of key() or get_string() + * instead of get_raw_json_string()). + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid as long as the bytes in dst. + * + * @param raw_json_string input + * @param dst A pointer to a buffer at least large enough to write this string as well as + * an additional SIMDJSON_PADDING bytes. + * @return A string_view pointing at the unescaped string in dst + * @error STRING_ERROR if escapes are incorrect. + */ + simdjson_inline simdjson_result unescape_wobbly(raw_json_string in, uint8_t *&dst) const noexcept; + +private: + /** @private [for benchmarking access] The implementation to use */ + std::unique_ptr implementation{}; + size_t _capacity{0}; + size_t _max_capacity; + size_t _max_depth{DEFAULT_MAX_DEPTH}; + std::unique_ptr string_buf{}; +#if SIMDJSON_DEVELOPMENT_CHECKS + std::unique_ptr start_positions{}; +#endif + + friend class json_iterator; + friend class document_stream; +}; + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::parser &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_PARSER_H +/* end file simdjson/generic/ondemand/parser.h for haswell */ + +// All other declarations +/* including simdjson/generic/ondemand/array.h for haswell: #include "simdjson/generic/ondemand/array.h" */ +/* begin file simdjson/generic/ondemand/array.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +/** + * A forward-only JSON array. + */ +class array { +public: + /** + * Create a new invalid array. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline array() noexcept = default; + + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result begin() noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() noexcept; + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an array is empty, it is more performant to use + * the is_empty() method. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the beginning of the array and checks whether the + * array is empty. + * The runtime complexity is constant time. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + simdjson_inline simdjson_result is_empty() & noexcept; + /** + * Reset the iterator so that we are pointing back at the + * beginning of the array. You should still consume values only once even if you + * can iterate through the array more than once. If you unescape a string + * within the array more than once, you have unsafe code. Note that rewinding + * an array means that you may need to reparse it anew: it is not a free + * operation. + * + * @returns true if the array contains some elements (not empty) + */ + inline simdjson_result reset() & noexcept; + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard, interpreting the current node + * as the root of its own JSON document. + * + * ondemand::parser parser; + * auto json = R"([ { "foo": { "a": [ 10, 20, 30 ] }} ])"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/0/foo/a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. Yet it is not the case when calling at_pointer on an array + * instance: there is no rewind and no invalidation. + * + * You may only call at_pointer on an array after it has been created, but before it has + * been first accessed. When calling at_pointer on an array, the pointer is advanced to + * the location indicated by the JSON pointer (in case of success). It is no longer possible + * to call at_pointer on the same array. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching. + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + /** + * Consumes the array and returns a string_view instance corresponding to the + * array as represented in JSON. It points inside the original document. + */ + simdjson_inline simdjson_result raw_json() noexcept; + + /** + * Get the value at the given index. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) noexcept; +protected: + /** + * Go to the end of the array, no matter where you are right now. + */ + simdjson_inline error_code consume() noexcept; + + /** + * Begin array iteration. + * + * @param iter The iterator. Must be where the initial [ is expected. Will be *moved* into the + * resulting array. + * @error INCORRECT_TYPE if the iterator is not at [. + */ + static simdjson_inline simdjson_result start(value_iterator &iter) noexcept; + /** + * Begin array iteration from the root. + * + * @param iter The iterator. Must be where the initial [ is expected. Will be *moved* into the + * resulting array. + * @error INCORRECT_TYPE if the iterator is not at [. + * @error TAPE_ERROR if there is no closing ] at the end of the document. + */ + static simdjson_inline simdjson_result start_root(value_iterator &iter) noexcept; + /** + * Begin array iteration. + * + * This version of the method should be called after the initial [ has been verified, and is + * intended for use by switch statements that check the type of a value. + * + * @param iter The iterator. Must be after the initial [. Will be *moved* into the resulting array. + */ + static simdjson_inline simdjson_result started(value_iterator &iter) noexcept; + + /** + * Create an array at the given Internal array creation. Call array::start() or array::started() instead of this. + * + * @param iter The iterator. Must either be at the start of the first element with iter.is_alive() + * == true, or past the [] with is_alive() == false if the array is empty. Will be *moved* + * into the resulting array. + */ + simdjson_inline array(const value_iterator &iter) noexcept; + + /** + * Iterator marking current position. + * + * iter.is_alive() == false indicates iteration is complete. + */ + value_iterator iter{}; + + friend class value; + friend class document; + friend struct simdjson_result; + friend struct simdjson_result; + friend class array_iterator; +}; + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::array &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + inline simdjson_result count_elements() & noexcept; + inline simdjson_result is_empty() & noexcept; + inline simdjson_result reset() & noexcept; + simdjson_inline simdjson_result at(size_t index) noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_H +/* end file simdjson/generic/ondemand/array.h for haswell */ +/* including simdjson/generic/ondemand/array_iterator.h for haswell: #include "simdjson/generic/ondemand/array_iterator.h" */ +/* begin file simdjson/generic/ondemand/array_iterator.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + + +namespace simdjson { +namespace haswell { +namespace ondemand { + +/** + * A forward-only JSON array. + * + * This is an input_iterator, meaning: + * - It is forward-only + * - * must be called exactly once per element. + * - ++ must be called exactly once in between each * (*, ++, *, ++, * ...) + */ +class array_iterator { +public: + /** Create a new, invalid array iterator. */ + simdjson_inline array_iterator() noexcept = default; + + // + // Iterator interface + // + + /** + * Get the current element. + * + * Part of the std::iterator interface. + */ + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + /** + * Check if we are at the end of the JSON. + * + * Part of the std::iterator interface. + * + * @return true if there are no more elements in the JSON array. + */ + simdjson_inline bool operator==(const array_iterator &) const noexcept; + /** + * Check if there are more elements in the JSON array. + * + * Part of the std::iterator interface. + * + * @return true if there are more elements in the JSON array. + */ + simdjson_inline bool operator!=(const array_iterator &) const noexcept; + /** + * Move to the next element. + * + * Part of the std::iterator interface. + */ + simdjson_inline array_iterator &operator++() noexcept; + +private: + value_iterator iter{}; + + simdjson_inline array_iterator(const value_iterator &iter) noexcept; + + friend class array; + friend class value; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::array_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + // + // Iterator interface + // + + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + simdjson_inline bool operator==(const simdjson_result &) const noexcept; + simdjson_inline bool operator!=(const simdjson_result &) const noexcept; + simdjson_inline simdjson_result &operator++() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H +/* end file simdjson/generic/ondemand/array_iterator.h for haswell */ +/* including simdjson/generic/ondemand/document.h for haswell: #include "simdjson/generic/ondemand/document.h" */ +/* begin file simdjson/generic/ondemand/document.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +/** + * A JSON document. It holds a json_iterator instance. + * + * Used by tokens to get text, and string buffer location. + * + * You must keep the document around during iteration. + */ +class document { +public: + /** + * Create a new invalid document. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline document() noexcept = default; + simdjson_inline document(const document &other) noexcept = delete; // pass your documents by reference, not by copy + simdjson_inline document(document &&other) noexcept = default; + simdjson_inline document &operator=(const document &other) noexcept = delete; + simdjson_inline document &operator=(document &&other) noexcept = default; + + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result get_array() & noexcept; + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @returns INCORRECT_TYPE If the JSON value is not an object. + */ + simdjson_inline simdjson_result get_object() & noexcept; + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64() noexcept; + /** + * Cast this JSON value (inside string) to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64() noexcept; + /** + * Cast this JSON value (inside string) to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64_in_string() noexcept; + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double() noexcept; + + /** + * Cast this JSON value (inside string) to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double_in_string() noexcept; + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: Calling get_string() twice on the same document is an error. + * + * @param Whether to allow a replacement character for unmatched surrogate pairs. + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + /** + * Attempts to fill the provided std::string reference with the parsed value of the current string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory. + * We recommend you avoid allocating an std::string unless you need to. + * + * @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS. + */ + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + /** + * Cast this JSON value to a string. + * + * The string is not guaranteed to be valid UTF-8. See https://simonsapin.github.io/wtf-8/ + * + * Important: Calling get_wobbly_string() twice on the same document is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_wobbly_string() noexcept; + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_raw_json_string() noexcept; + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @returns INCORRECT_TYPE if the JSON value is not true or false. + */ + simdjson_inline simdjson_result get_bool() noexcept; + /** + * Cast this JSON value to a value when the document is an object or an array. + * + * You must not have begun iterating through the object or array. When + * SIMDJSON_DEVELOPMENT_CHECKS is set to 1 (which is the case when building in Debug mode + * by default), and you have already begun iterating, + * you will get an OUT_OF_ORDER_ITERATION error. If you have begun iterating, you can use + * rewind() to reset the document to its initial state before calling this method. + * + * @returns A value if a JSON array or object cannot be found. + * @returns SCALAR_DOCUMENT_AS_VALUE error is the document is a scalar (see is_scalar() function). + */ + simdjson_inline simdjson_result get_value() noexcept; + + /** + * Checks if this JSON value is null. If and only if the value is + * null, then it is consumed (we advance). If we find a token that + * begins with 'n' but is not 'null', then an error is returned. + * + * @returns Whether the value is null. + * @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'. + */ + simdjson_inline simdjson_result is_null() noexcept; + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * You may use get_double(), get_bool(), get_uint64(), get_int64(), + * get_object(), get_array(), get_raw_json_string(), or get_string() instead. + * + * @returns A value of the given type, parsed from the JSON. + * @returns INCORRECT_TYPE If the JSON value is not the given type. + */ + template simdjson_inline simdjson_result get() & noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + /** @overload template simdjson_result get() & noexcept */ + template simdjson_inline simdjson_result get() && noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool, value + * + * Be mindful that the document instance must remain in scope while you are accessing object, array and value instances. + * + * @param out This is set to a value of the given type, parsed from the JSON. If there is an error, this may not be initialized. + * @returns INCORRECT_TYPE If the JSON value is not an object. + * @returns SUCCESS If the parse succeeded and the out parameter was set to the value. + */ + template simdjson_inline error_code get(T &out) & noexcept; + /** @overload template error_code get(T &out) & noexcept */ + template simdjson_inline error_code get(T &out) && noexcept; + +#if SIMDJSON_EXCEPTIONS + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an array. + */ + simdjson_inline operator array() & noexcept(false); + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an object. + */ + simdjson_inline operator object() & noexcept(false); + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline operator uint64_t() noexcept(false); + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer. + */ + simdjson_inline operator int64_t() noexcept(false); + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number. + */ + simdjson_inline operator double() noexcept(false); + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator std::string_view() noexcept(false); + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator raw_json_string() noexcept(false); + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false. + */ + simdjson_inline operator bool() noexcept(false); + /** + * Cast this JSON value to a value when the document is an object or an array. + * + * You must not have begun iterating through the object or array. When + * SIMDJSON_DEVELOPMENT_CHECKS is defined, and you have already begun iterating, + * you will get an OUT_OF_ORDER_ITERATION error. If you have begun iterating, you can use + * rewind() to reset the document to its initial state before calling this method. + * + * @returns A value value if a JSON array or object cannot be found. + * @exception SCALAR_DOCUMENT_AS_VALUE error is the document is a scalar (see is_scalar() function). + */ + simdjson_inline operator value() noexcept(false); +#endif + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Get the value at the given index in the array. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) & noexcept; + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result begin() & noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() & noexcept; + + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. E.g., the array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to + * a key a single time. Doing object["mykey"].to_string()and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. E.g., the array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a key + * a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + + /** + * Get the type of this JSON value. It does not validate or consume the value. + * E.g., you must still call "is_null()" to check that a value is null even if + * "type()" returns json_type::null. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + * + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() noexcept; + + /** + * Checks whether the document is a scalar (string, number, null, Boolean). + * Returns false when there it is an array or object. + * + * @returns true if the type is string, number, null, Boolean + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result is_scalar() noexcept; + + /** + * Checks whether the document is a negative number. + * + * @returns true if the number if negative. + */ + simdjson_inline bool is_negative() noexcept; + /** + * Checks whether the document is an integer number. Note that + * this requires to partially parse the number string. If + * the value is determined to be an integer, it may still + * not parse properly as an integer in subsequent steps + * (e.g., it might overflow). + * + * @returns true if the number if negative. + */ + simdjson_inline simdjson_result is_integer() noexcept; + /** + * Determine the number type (integer or floating-point number) as quickly + * as possible. This function does not fully validate the input. It is + * useful when you only need to classify the numbers, without parsing them. + * + * If you are planning to retrieve the value or you need full validation, + * consider using the get_number() method instead: it will fully parse + * and validate the input, and give you access to the type: + * get_number().get_number_type(). + * + * get_number_type() is number_type::unsigned_integer if we have + * an integer greater or equal to 9223372036854775808 + * get_number_type() is number_type::signed_integer if we have an + * integer that is less than 9223372036854775808 + * Otherwise, get_number_type() has value number_type::floating_point_number + * + * This function requires processing the number string, but it is expected + * to be faster than get_number().get_number_type() because it is does not + * parse the number value. + * + * @returns the type of the number + */ + simdjson_inline simdjson_result get_number_type() noexcept; + + /** + * Attempt to parse an ondemand::number. An ondemand::number may + * contain an integer value or a floating-point value, the simdjson + * library will autodetect the type. Thus it is a dynamically typed + * number. Before accessing the value, you must determine the detected + * type. + * + * number.get_number_type() is number_type::signed_integer if we have + * an integer in [-9223372036854775808,9223372036854775808) + * You can recover the value by calling number.get_int64() and you + * have that number.is_int64() is true. + * + * number.get_number_type() is number_type::unsigned_integer if we have + * an integer in [9223372036854775808,18446744073709551616) + * You can recover the value by calling number.get_uint64() and you + * have that number.is_uint64() is true. + * + * Otherwise, number.get_number_type() has value number_type::floating_point_number + * and we have a binary64 number. + * You can recover the value by calling number.get_double() and you + * have that number.is_double() is true. + * + * You must check the type before accessing the value: it is an error + * to call "get_int64()" when number.get_number_type() is not + * number_type::signed_integer and when number.is_int64() is false. + */ + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + /** + * Get the raw JSON for this token. + * + * The string_view will always point into the input buffer. + * + * The string_view will start at the beginning of the token, and include the entire token + * *as well as all spaces until the next token (or EOF).* This means, for example, that a + * string token always begins with a " and is always terminated by the final ", possibly + * followed by a number of spaces. + * + * The string_view is *not* null-terminated. If this is a scalar (string, number, + * boolean, or null), the character after the end of the string_view may be the padded buffer. + * + * Tokens include: + * - { + * - [ + * - "a string (possibly with UTF-8 or backslashed characters like \\\")". + * - -1.2e-100 + * - true + * - false + * - null + */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + /** + * Reset the iterator inside the document instance so we are pointing back at the + * beginning of the document, as if it had just been created. It invalidates all + * values, objects and arrays that you have created so far (including unescaped strings). + */ + inline void rewind() noexcept; + /** + * Returns debugging information. + */ + inline std::string to_debug_string() noexcept; + /** + * Some unrecoverable error conditions may render the document instance unusable. + * The is_alive() method returns true when the document is still suitable. + */ + inline bool is_alive() noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + inline simdjson_result current_location() const noexcept; + + /** + * Returns true if this document has been fully parsed. + * If you have consumed the whole document and at_end() returns + * false, then there may be trailing content. + */ + inline bool at_end() const noexcept; + + /** + * Returns the current depth in the document if in bounds. + * + * E.g., + * 0 = finished with document + * 1 = document root value (could be [ or {, not yet known) + * 2 = , or } inside root array/object + * 3 = key or value inside root array/object. + */ + simdjson_inline int32_t current_depth() const noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() automatically calls rewind between each call. Thus + * all values, objects and arrays that you have created so far (including unescaped strings) + * are invalidated. After calling at_pointer, you need to consume the result: string values + * should be stored in your own variables, arrays should be decoded and stored in your own array-like + * structures and so forth. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + * - SCALAR_DOCUMENT_AS_VALUE if the json_pointer is empty and the document is not a scalar (see is_scalar() function). + */ + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + /** + * Consumes the document and returns a string_view instance corresponding to the + * document as represented in JSON. It points inside the original byte array containing + * the JSON document. + */ + simdjson_inline simdjson_result raw_json() noexcept; +protected: + /** + * Consumes the document. + */ + simdjson_inline error_code consume() noexcept; + + simdjson_inline document(ondemand::json_iterator &&iter) noexcept; + simdjson_inline const uint8_t *text(uint32_t idx) const noexcept; + + simdjson_inline value_iterator resume_value_iterator() noexcept; + simdjson_inline value_iterator get_root_value_iterator() noexcept; + simdjson_inline simdjson_result start_or_resume_object() noexcept; + static simdjson_inline document start(ondemand::json_iterator &&iter) noexcept; + + // + // Fields + // + json_iterator iter{}; ///< Current position in the document + static constexpr depth_t DOCUMENT_DEPTH = 0; ///< document depth is always 0 + + friend class array_iterator; + friend class value; + friend class ondemand::parser; + friend class object; + friend class array; + friend class field; + friend class token; + friend class document_stream; + friend class document_reference; +}; + + +/** + * A document_reference is a thin wrapper around a document reference instance. + */ +class document_reference { +public: + simdjson_inline document_reference() noexcept; + simdjson_inline document_reference(document &d) noexcept; + simdjson_inline document_reference(const document_reference &other) noexcept = default; + simdjson_inline document_reference& operator=(const document_reference &other) noexcept = default; + simdjson_inline void rewind() noexcept; + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + + simdjson_inline simdjson_result is_null() noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + simdjson_inline operator document&() const noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator array() & noexcept(false); + simdjson_inline operator object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline int32_t current_depth() const noexcept; + simdjson_inline bool is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + simdjson_inline simdjson_result raw_json_token() noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +private: + document *doc{nullptr}; +}; +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::document &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline error_code rewind() noexcept; + + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + + template simdjson_inline simdjson_result get() & noexcept; + template simdjson_inline simdjson_result get() && noexcept; + + template simdjson_inline error_code get(T &out) & noexcept; + template simdjson_inline error_code get(T &out) && noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator haswell::ondemand::array() & noexcept(false); + simdjson_inline operator haswell::ondemand::object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator haswell::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator haswell::ondemand::value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline int32_t current_depth() const noexcept; + simdjson_inline bool at_end() const noexcept; + simdjson_inline bool is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + /** @copydoc simdjson_inline std::string_view document::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + + +} // namespace simdjson + + + +namespace simdjson { + +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::document_reference value, error_code error) noexcept; + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline error_code rewind() noexcept; + + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator haswell::ondemand::array() & noexcept(false); + simdjson_inline operator haswell::ondemand::object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator haswell::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator haswell::ondemand::value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline simdjson_result current_depth() const noexcept; + simdjson_inline simdjson_result is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + /** @copydoc simdjson_inline std::string_view document_reference::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H +/* end file simdjson/generic/ondemand/document.h for haswell */ +/* including simdjson/generic/ondemand/document_stream.h for haswell: #include "simdjson/generic/ondemand/document_stream.h" */ +/* begin file simdjson/generic/ondemand/document_stream.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#ifdef SIMDJSON_THREADS_ENABLED +#include +#include +#include +#endif + +namespace simdjson { +namespace haswell { +namespace ondemand { + +#ifdef SIMDJSON_THREADS_ENABLED +/** @private Custom worker class **/ +struct stage1_worker { + stage1_worker() noexcept = default; + stage1_worker(const stage1_worker&) = delete; + stage1_worker(stage1_worker&&) = delete; + stage1_worker operator=(const stage1_worker&) = delete; + ~stage1_worker(); + /** + * We only start the thread when it is needed, not at object construction, this may throw. + * You should only call this once. + **/ + void start_thread(); + /** + * Start a stage 1 job. You should first call 'run', then 'finish'. + * You must call start_thread once before. + */ + void run(document_stream * ds, parser * stage1, size_t next_batch_start); + /** Wait for the run to finish (blocking). You should first call 'run', then 'finish'. **/ + void finish(); + +private: + + /** + * Normally, we would never stop the thread. But we do in the destructor. + * This function is only safe assuming that you are not waiting for results. You + * should have called run, then finish, and be done. + **/ + void stop_thread(); + + std::thread thread{}; + /** These three variables define the work done by the thread. **/ + ondemand::parser * stage1_thread_parser{}; + size_t _next_batch_start{}; + document_stream * owner{}; + /** + * We have two state variables. This could be streamlined to one variable in the future but + * we use two for clarity. + */ + bool has_work{false}; + bool can_work{true}; + + /** + * We lock using a mutex. + */ + std::mutex locking_mutex{}; + std::condition_variable cond_var{}; + + friend class document_stream; +}; +#endif // SIMDJSON_THREADS_ENABLED + +/** + * A forward-only stream of documents. + * + * Produced by parser::iterate_many. + * + */ +class document_stream { +public: + /** + * Construct an uninitialized document_stream. + * + * ```c++ + * document_stream docs; + * auto error = parser.iterate_many(json).get(docs); + * ``` + */ + simdjson_inline document_stream() noexcept; + /** Move one document_stream to another. */ + simdjson_inline document_stream(document_stream &&other) noexcept = default; + /** Move one document_stream to another. */ + simdjson_inline document_stream &operator=(document_stream &&other) noexcept = default; + + simdjson_inline ~document_stream() noexcept; + + /** + * Returns the input size in bytes. + */ + inline size_t size_in_bytes() const noexcept; + + /** + * After iterating through the stream, this method + * returns the number of bytes that were not parsed at the end + * of the stream. If truncated_bytes() differs from zero, + * then the input was truncated maybe because incomplete JSON + * documents were found at the end of the stream. You + * may need to process the bytes in the interval [size_in_bytes()-truncated_bytes(), size_in_bytes()). + * + * You should only call truncated_bytes() after streaming through all + * documents, like so: + * + * document_stream stream = parser.iterate_many(json,window); + * for(auto & doc : stream) { + * // do something with doc + * } + * size_t truncated = stream.truncated_bytes(); + * + */ + inline size_t truncated_bytes() const noexcept; + + class iterator { + public: + using value_type = simdjson_result; + using reference = value_type; + + using difference_type = std::ptrdiff_t; + + using iterator_category = std::input_iterator_tag; + + /** + * Default constructor. + */ + simdjson_inline iterator() noexcept; + /** + * Get the current document (or error). + */ + simdjson_inline simdjson_result operator*() noexcept; + /** + * Advance to the next document (prefix). + */ + inline iterator& operator++() noexcept; + /** + * Check if we're at the end yet. + * @param other the end iterator to compare to. + */ + simdjson_inline bool operator!=(const iterator &other) const noexcept; + /** + * @private + * + * Gives the current index in the input document in bytes. + * + * document_stream stream = parser.parse_many(json,window); + * for(auto i = stream.begin(); i != stream.end(); ++i) { + * auto doc = *i; + * size_t index = i.current_index(); + * } + * + * This function (current_index()) is experimental and the usage + * may change in future versions of simdjson: we find the API somewhat + * awkward and we would like to offer something friendlier. + */ + simdjson_inline size_t current_index() const noexcept; + + /** + * @private + * + * Gives a view of the current document at the current position. + * + * document_stream stream = parser.iterate_many(json,window); + * for(auto i = stream.begin(); i != stream.end(); ++i) { + * std::string_view v = i.source(); + * } + * + * The returned string_view instance is simply a map to the (unparsed) + * source string: it may thus include white-space characters and all manner + * of padding. + * + * This function (source()) is experimental and the usage + * may change in future versions of simdjson: we find the API somewhat + * awkward and we would like to offer something friendlier. + * + */ + simdjson_inline std::string_view source() const noexcept; + + /** + * Returns error of the stream (if any). + */ + inline error_code error() const noexcept; + + private: + simdjson_inline iterator(document_stream *s, bool finished) noexcept; + /** The document_stream we're iterating through. */ + document_stream* stream; + /** Whether we're finished or not. */ + bool finished; + + friend class document; + friend class document_stream; + friend class json_iterator; + }; + + /** + * Start iterating the documents in the stream. + */ + simdjson_inline iterator begin() noexcept; + /** + * The end of the stream, for iterator comparison purposes. + */ + simdjson_inline iterator end() noexcept; + +private: + + document_stream &operator=(const document_stream &) = delete; // Disallow copying + document_stream(const document_stream &other) = delete; // Disallow copying + + /** + * Construct a document_stream. Does not allocate or parse anything until the iterator is + * used. + * + * @param parser is a reference to the parser instance used to generate this document_stream + * @param buf is the raw byte buffer we need to process + * @param len is the length of the raw byte buffer in bytes + * @param batch_size is the size of the windows (must be strictly greater or equal to the largest JSON document) + */ + simdjson_inline document_stream( + ondemand::parser &parser, + const uint8_t *buf, + size_t len, + size_t batch_size, + bool allow_comma_separated + ) noexcept; + + /** + * Parse the first document in the buffer. Used by begin(), to handle allocation and + * initialization. + */ + inline void start() noexcept; + + /** + * Parse the next document found in the buffer previously given to document_stream. + * + * The content should be a valid JSON document encoded as UTF-8. If there is a + * UTF-8 BOM, the parser skips it. + * + * You do NOT need to pre-allocate a parser. This function takes care of + * pre-allocating a capacity defined by the batch_size defined when creating the + * document_stream object. + * + * The function returns simdjson::EMPTY if there is no more data to be parsed. + * + * The function returns simdjson::SUCCESS (as integer = 0) in case of success + * and indicates that the buffer has successfully been parsed to the end. + * Every document it contained has been parsed without error. + * + * The function returns an error code from simdjson/simdjson.h in case of failure + * such as simdjson::CAPACITY, simdjson::MEMALLOC, simdjson::DEPTH_ERROR and so forth; + * the simdjson::error_message function converts these error codes into a string). + * + * You can also check validity by calling parser.is_valid(). The same parser can + * and should be reused for the other documents in the buffer. + */ + inline void next() noexcept; + + /** Move the json_iterator of the document to the location of the next document in the stream. */ + inline void next_document() noexcept; + + /** Get the next document index. */ + inline size_t next_batch_start() const noexcept; + + /** Pass the next batch through stage 1 with the given parser. */ + inline error_code run_stage1(ondemand::parser &p, size_t batch_start) noexcept; + + // Fields + ondemand::parser *parser; + const uint8_t *buf; + size_t len; + size_t batch_size; + bool allow_comma_separated; + /** + * We are going to use just one document instance. The document owns + * the json_iterator. It implies that we only ever pass a reference + * to the document to the users. + */ + document doc{}; + /** The error (or lack thereof) from the current document. */ + error_code error; + size_t batch_start{0}; + size_t doc_index{}; + + #ifdef SIMDJSON_THREADS_ENABLED + /** Indicates whether we use threads. Note that this needs to be a constant during the execution of the parsing. */ + bool use_thread; + + inline void load_from_stage1_thread() noexcept; + + /** Start a thread to run stage 1 on the next batch. */ + inline void start_stage1_thread() noexcept; + + /** Wait for the stage 1 thread to finish and capture the results. */ + inline void finish_stage1_thread() noexcept; + + /** The error returned from the stage 1 thread. */ + error_code stage1_thread_error{UNINITIALIZED}; + /** The thread used to run stage 1 against the next batch in the background. */ + std::unique_ptr worker{new(std::nothrow) stage1_worker()}; + /** + * The parser used to run stage 1 in the background. Will be swapped + * with the regular parser when finished. + */ + ondemand::parser stage1_thread_parser{}; + + friend struct stage1_worker; + #endif // SIMDJSON_THREADS_ENABLED + + friend class parser; + friend class document; + friend class json_iterator; + friend struct simdjson_result; + friend struct internal::simdjson_result_base; +}; // document_stream + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::document_stream &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H +/* end file simdjson/generic/ondemand/document_stream.h for haswell */ +/* including simdjson/generic/ondemand/field.h for haswell: #include "simdjson/generic/ondemand/field.h" */ +/* begin file simdjson/generic/ondemand/field.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_FIELD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_FIELD_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +/** + * A JSON field (key/value pair) in an object. + * + * Returned from object iteration. + * + * Extends from std::pair so you can use C++ algorithms that rely on pairs. + */ +class field : public std::pair { +public: + /** + * Create a new invalid field. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline field() noexcept; + + /** + * Get the key as a string_view (for higher speed, consider raw_key). + * We deliberately use a more cumbersome name (unescaped_key) to force users + * to think twice about using it. + * + * This consumes the key: once you have called unescaped_key(), you cannot + * call it again nor can you call key(). + */ + simdjson_inline simdjson_warn_unused simdjson_result unescaped_key(bool allow_replacement) noexcept; + /** + * Get the key as a raw_json_string. Can be used for direct comparison with + * an unescaped C string: e.g., key() == "test". + */ + simdjson_inline raw_json_string key() const noexcept; + /** + * Get the field value. + */ + simdjson_inline ondemand::value &value() & noexcept; + /** + * @overload ondemand::value &ondemand::value() & noexcept + */ + simdjson_inline ondemand::value value() && noexcept; + +protected: + simdjson_inline field(raw_json_string key, ondemand::value &&value) noexcept; + static simdjson_inline simdjson_result start(value_iterator &parent_iter) noexcept; + static simdjson_inline simdjson_result start(const value_iterator &parent_iter, raw_json_string key) noexcept; + friend struct simdjson_result; + friend class object_iterator; +}; + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::field &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result unescaped_key(bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result key() noexcept; + simdjson_inline simdjson_result value() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_FIELD_H +/* end file simdjson/generic/ondemand/field.h for haswell */ +/* including simdjson/generic/ondemand/object.h for haswell: #include "simdjson/generic/ondemand/object.h" */ +/* begin file simdjson/generic/ondemand/object.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +/** + * A forward-only JSON object field iterator. + */ +class object { +public: + /** + * Create a new invalid object. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline object() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. The value instance you get + * from `content["bids"]` becomes invalid when you call `content["asks"]`. The array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a + * key a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field(std::string_view key) && noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. The value instance you get + * from `content["bids"]` becomes invalid when you call `content["asks"]`. The array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a key + * a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) && noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) && noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard, interpreting the current node + * as the root of its own JSON document. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. Yet it is not the case when calling at_pointer on an object + * instance: there is no rewind and no invalidation. + * + * You may call at_pointer more than once on an object, but each time the pointer is advanced + * to be within the value matched by the key indicated by the JSON pointer query. Thus any preceding + * key (as well as the current key) can no longer be used with following JSON pointer calls. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching. + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + + /** + * Reset the iterator so that we are pointing back at the + * beginning of the object. You should still consume values only once even if you + * can iterate through the object more than once. If you unescape a string within + * the object more than once, you have unsafe code. Note that rewinding an object + * means that you may need to reparse it anew: it is not a free operation. + * + * @returns true if the object contains some elements (not empty) + */ + inline simdjson_result reset() & noexcept; + /** + * This method scans the beginning of the object and checks whether the + * object is empty. + * The runtime complexity is constant time. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + inline simdjson_result is_empty() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method. + * + * Performance hint: You should only call count_fields() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Consumes the object and returns a string_view instance corresponding to the + * object as represented in JSON. It points inside the original byte array containing + * the JSON document. + */ + simdjson_inline simdjson_result raw_json() noexcept; + +protected: + /** + * Go to the end of the object, no matter where you are right now. + */ + simdjson_inline error_code consume() noexcept; + static simdjson_inline simdjson_result start(value_iterator &iter) noexcept; + static simdjson_inline simdjson_result start_root(value_iterator &iter) noexcept; + static simdjson_inline simdjson_result started(value_iterator &iter) noexcept; + static simdjson_inline object resume(const value_iterator &iter) noexcept; + simdjson_inline object(const value_iterator &iter) noexcept; + + simdjson_warn_unused simdjson_inline error_code find_field_raw(const std::string_view key) noexcept; + + value_iterator iter{}; + + friend class value; + friend class document; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::object &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) && noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) && noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) && noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + inline simdjson_result reset() noexcept; + inline simdjson_result is_empty() noexcept; + inline simdjson_result count_fields() & noexcept; + inline simdjson_result raw_json() noexcept; + +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_H +/* end file simdjson/generic/ondemand/object.h for haswell */ +/* including simdjson/generic/ondemand/object_iterator.h for haswell: #include "simdjson/generic/ondemand/object_iterator.h" */ +/* begin file simdjson/generic/ondemand/object_iterator.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +class object_iterator { +public: + /** + * Create a new invalid object_iterator. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline object_iterator() noexcept = default; + + // + // Iterator interface + // + + // Reads key and value, yielding them to the user. + // MUST ONLY BE CALLED ONCE PER ITERATION. + simdjson_inline simdjson_result operator*() noexcept; + // Assumes it's being compared with the end. true if depth < iter->depth. + simdjson_inline bool operator==(const object_iterator &) const noexcept; + // Assumes it's being compared with the end. true if depth >= iter->depth. + simdjson_inline bool operator!=(const object_iterator &) const noexcept; + // Checks for ']' and ',' + simdjson_inline object_iterator &operator++() noexcept; + +private: + /** + * The underlying JSON iterator. + * + * PERF NOTE: expected to be elided in favor of the parent document: this is set when the object + * is first used, and never changes afterwards. + */ + value_iterator iter{}; + + simdjson_inline object_iterator(const value_iterator &iter) noexcept; + friend struct simdjson_result; + friend class object; +}; + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public haswell::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(haswell::ondemand::object_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + // + // Iterator interface + // + + // Reads key and value, yielding them to the user. + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + // Assumes it's being compared with the end. true if depth < iter->depth. + simdjson_inline bool operator==(const simdjson_result &) const noexcept; + // Assumes it's being compared with the end. true if depth >= iter->depth. + simdjson_inline bool operator!=(const simdjson_result &) const noexcept; + // Checks for ']' and ',' + simdjson_inline simdjson_result &operator++() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H +/* end file simdjson/generic/ondemand/object_iterator.h for haswell */ +/* including simdjson/generic/ondemand/serialization.h for haswell: #include "simdjson/generic/ondemand/serialization.h" */ +/* begin file simdjson/generic/ondemand/serialization.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Create a string-view instance out of a document instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(haswell::ondemand::document& x) noexcept; +/** + * Create a string-view instance out of a value instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. The value must + * not have been accessed previously. It does not + * validate the content. + */ +inline simdjson_result to_json_string(haswell::ondemand::value& x) noexcept; +/** + * Create a string-view instance out of an object instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(haswell::ondemand::object& x) noexcept; +/** + * Create a string-view instance out of an array instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(haswell::ondemand::array& x) noexcept; +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +} // namespace simdjson + +/** + * We want to support argument-dependent lookup (ADL). + * Hence we should define operator<< in the namespace + * where the argument (here value, object, etc.) resides. + * Credit: @madhur4127 + * See https://github.com/simdjson/simdjson/issues/1768 + */ +namespace simdjson { namespace haswell { namespace ondemand { + +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The element. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::haswell::ondemand::value x); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The array. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::haswell::ondemand::array value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The array. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::haswell::ondemand::document& value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x); +#endif +inline std::ostream& operator<<(std::ostream& out, simdjson::haswell::ondemand::document_reference& value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The object. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::haswell::ondemand::object value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +}}} // namespace simdjson::haswell::ondemand + +#endif // SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H +/* end file simdjson/generic/ondemand/serialization.h for haswell */ + +// Inline definitions +/* including simdjson/generic/ondemand/array-inl.h for haswell: #include "simdjson/generic/ondemand/array-inl.h" */ +/* begin file simdjson/generic/ondemand/array-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +// +// ### Live States +// +// While iterating or looking up values, depth >= iter->depth. at_start may vary. Error is +// always SUCCESS: +// +// - Start: This is the state when the array is first found and the iterator is just past the `{`. +// In this state, at_start == true. +// - Next: After we hand a scalar value to the user, or an array/object which they then fully +// iterate over, the iterator is at the `,` before the next value (or `]`). In this state, +// depth == iter->depth, at_start == false, and error == SUCCESS. +// - Unfinished Business: When we hand an array/object to the user which they do not fully +// iterate over, we need to finish that iteration by skipping child values until we reach the +// Next state. In this state, depth > iter->depth, at_start == false, and error == SUCCESS. +// +// ## Error States +// +// In error states, we will yield exactly one more value before stopping. iter->depth == depth +// and at_start is always false. We decrement after yielding the error, moving to the Finished +// state. +// +// - Chained Error: When the array iterator is part of an error chain--for example, in +// `for (auto tweet : doc["tweets"])`, where the tweet element may be missing or not be an +// array--we yield that error in the loop, exactly once. In this state, error != SUCCESS and +// iter->depth == depth, and at_start == false. We decrement depth when we yield the error. +// - Missing Comma Error: When the iterator ++ method discovers there is no comma between elements, +// we flag that as an error and treat it exactly the same as a Chained Error. In this state, +// error == TAPE_ERROR, iter->depth == depth, and at_start == false. +// +// ## Terminal State +// +// The terminal state has iter->depth < depth. at_start is always false. +// +// - Finished: When we have reached a `]` or have reported an error, we are finished. We signal this +// by decrementing depth. In this state, iter->depth < depth, at_start == false, and +// error == SUCCESS. +// + +simdjson_inline array::array(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} + +simdjson_inline simdjson_result array::start(value_iterator &iter) noexcept { + // We don't need to know if the array is empty to start iteration, but we do want to know if there + // is an error--thus `simdjson_unused`. + simdjson_unused bool has_value; + SIMDJSON_TRY( iter.start_array().get(has_value) ); + return array(iter); +} +simdjson_inline simdjson_result array::start_root(value_iterator &iter) noexcept { + simdjson_unused bool has_value; + SIMDJSON_TRY( iter.start_root_array().get(has_value) ); + return array(iter); +} +simdjson_inline simdjson_result array::started(value_iterator &iter) noexcept { + bool has_value; + SIMDJSON_TRY(iter.started_array().get(has_value)); + return array(iter); +} + +simdjson_inline simdjson_result array::begin() noexcept { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + return array_iterator(iter); +} +simdjson_inline simdjson_result array::end() noexcept { + return array_iterator(iter); +} +simdjson_inline error_code array::consume() noexcept { + auto error = iter.json_iter().skip_child(iter.depth()-1); + if(error) { iter.abandon(); } + return error; +} + +simdjson_inline simdjson_result array::raw_json() noexcept { + const uint8_t * starting_point{iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + // After 'consume()', we could be left pointing just beyond the document, but that + // is ok because we are not going to dereference the final pointer position, we just + // use it to compute the length in bytes. + const uint8_t * final_point{iter._json_iter->unsafe_pointer()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline simdjson_result array::count_elements() & noexcept { + size_t count{0}; + // Important: we do not consume any of the values. + for(simdjson_unused auto v : *this) { count++; } + // The above loop will always succeed, but we want to report errors. + if(iter.error()) { return iter.error(); } + // We need to move back at the start because we expect users to iterate through + // the array after counting the number of elements. + iter.reset_array(); + return count; +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline simdjson_result array::is_empty() & noexcept { + bool is_not_empty; + auto error = iter.reset_array().get(is_not_empty); + if(error) { return error; } + return !is_not_empty; +} + +inline simdjson_result array::reset() & noexcept { + return iter.reset_array(); +} + +inline simdjson_result array::at_pointer(std::string_view json_pointer) noexcept { + if (json_pointer[0] != '/') { return INVALID_JSON_POINTER; } + json_pointer = json_pointer.substr(1); + // - 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; } + + // Read the array index + size_t array_index = 0; + size_t i; + for (i = 0; i < json_pointer.length() && json_pointer[i] != '/'; i++) { + uint8_t digit = uint8_t(json_pointer[i] - '0'); + // Check for non-digit in array index. If it's there, we're trying to get a field in an object + if (digit > 9) { return INCORRECT_TYPE; } + array_index = array_index*10 + digit; + } + + // 0 followed by other digits is invalid + if (i > 1 && json_pointer[0] == '0') { return INVALID_JSON_POINTER; } // "JSON pointer array index has other characters after 0" + + // Empty string is invalid; so is a "/" with no digits before it + if (i == 0) { return INVALID_JSON_POINTER; } // "Empty string in JSON pointer array index" + // Get the child + auto child = at(array_index); + // If there is an error, it ends here + if(child.error()) { + return child; + } + + // If there is a /, we're not done yet, call recursively. + if (i < json_pointer.length()) { + child = child.at_pointer(json_pointer.substr(i)); + } + return child; +} + +simdjson_inline simdjson_result array::at(size_t index) noexcept { + size_t i = 0; + for (auto value : *this) { + if (i == index) { return value; } + i++; + } + return INDEX_OUT_OF_BOUNDS; +} + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + haswell::ondemand::array &&value +) noexcept + : implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept + : implementation_simdjson_result_base(error) +{ +} + +simdjson_inline simdjson_result simdjson_result::begin() noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() noexcept { + if (error()) { return error(); } + return first.end(); +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::is_empty() & noexcept { + if (error()) { return error(); } + return first.is_empty(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H +/* end file simdjson/generic/ondemand/array-inl.h for haswell */ +/* including simdjson/generic/ondemand/array_iterator-inl.h for haswell: #include "simdjson/generic/ondemand/array_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/array_iterator-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +simdjson_inline array_iterator::array_iterator(const value_iterator &_iter) noexcept + : iter{_iter} +{} + +simdjson_inline simdjson_result array_iterator::operator*() noexcept { + if (iter.error()) { iter.abandon(); return iter.error(); } + return value(iter.child()); +} +simdjson_inline bool array_iterator::operator==(const array_iterator &other) const noexcept { + return !(*this != other); +} +simdjson_inline bool array_iterator::operator!=(const array_iterator &) const noexcept { + return iter.is_open(); +} +simdjson_inline array_iterator &array_iterator::operator++() noexcept { + error_code error; + // PERF NOTE this is a safety rail ... users should exit loops as soon as they receive an error, so we'll never get here. + // However, it does not seem to make a perf difference, so we add it out of an abundance of caution. + if (( error = iter.error() )) { return *this; } + if (( error = iter.skip_child() )) { return *this; } + if (( error = iter.has_next_element().error() )) { return *this; } + return *this; +} + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + haswell::ondemand::array_iterator &&value +) noexcept + : haswell::implementation_simdjson_result_base(std::forward(value)) +{ + first.iter.assert_is_valid(); +} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : haswell::implementation_simdjson_result_base({}, error) +{ +} + +simdjson_inline simdjson_result simdjson_result::operator*() noexcept { + if (error()) { return error(); } + return *first; +} +simdjson_inline bool simdjson_result::operator==(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return !error(); } + return first == other.first; +} +simdjson_inline bool simdjson_result::operator!=(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return error(); } + return first != other.first; +} +simdjson_inline simdjson_result &simdjson_result::operator++() noexcept { + // Clear the error if there is one, so we don't yield it twice + if (error()) { second = SUCCESS; return *this; } + ++(first); + return *this; +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/array_iterator-inl.h for haswell */ +/* including simdjson/generic/ondemand/document-inl.h for haswell: #include "simdjson/generic/ondemand/document-inl.h" */ +/* begin file simdjson/generic/ondemand/document-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +simdjson_inline document::document(ondemand::json_iterator &&_iter) noexcept + : iter{std::forward(_iter)} +{ + logger::log_start_value(iter, "document"); +} + +simdjson_inline document document::start(json_iterator &&iter) noexcept { + return document(std::forward(iter)); +} + +inline void document::rewind() noexcept { + iter.rewind(); +} + +inline std::string document::to_debug_string() noexcept { + return iter.to_string(); +} + +inline simdjson_result document::current_location() const noexcept { + return iter.current_location(); +} + +inline int32_t document::current_depth() const noexcept { + return iter.depth(); +} + +inline bool document::at_end() const noexcept { + return iter.at_end(); +} + + +inline bool document::is_alive() noexcept { + return iter.is_alive(); +} +simdjson_inline value_iterator document::resume_value_iterator() noexcept { + return value_iterator(&iter, 1, iter.root_position()); +} +simdjson_inline value_iterator document::get_root_value_iterator() noexcept { + return resume_value_iterator(); +} +simdjson_inline simdjson_result document::start_or_resume_object() noexcept { + if (iter.at_root()) { + return get_object(); + } else { + return object::resume(resume_value_iterator()); + } +} +simdjson_inline simdjson_result document::get_value() noexcept { + // Make sure we start any arrays or objects before returning, so that start_root_() + // gets called. + + // It is the convention throughout the code that the macro `SIMDJSON_DEVELOPMENT_CHECKS` determines whether + // we check for OUT_OF_ORDER_ITERATION. Proper on::demand code should never trigger this error. +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.at_root()) { return OUT_OF_ORDER_ITERATION; } +#endif + // assert_at_root() serves two purposes: in Debug mode, whether or not + // SIMDJSON_DEVELOPMENT_CHECKS is set or not, it checks that we are at the root of + // the document (this will typically be redundant). In release mode, it generates + // SIMDJSON_ASSUME statements to allow the compiler to make assumptions. + iter.assert_at_root(); + switch (*iter.peek()) { + case '[': { + // The following lines check that the document ends with ]. + auto value_iterator = get_root_value_iterator(); + auto error = value_iterator.check_root_array(); + if(error) { return error; } + return value(get_root_value_iterator()); + } + case '{': { + // The following lines would check that the document ends with }. + auto value_iterator = get_root_value_iterator(); + auto error = value_iterator.check_root_object(); + if(error) { return error; } + return value(get_root_value_iterator()); + } + default: + // Unfortunately, scalar documents are a special case in simdjson and they cannot + // be safely converted to value instances. + return SCALAR_DOCUMENT_AS_VALUE; + } +} +simdjson_inline simdjson_result document::get_array() & noexcept { + auto value = get_root_value_iterator(); + return array::start_root(value); +} +simdjson_inline simdjson_result document::get_object() & noexcept { + auto value = get_root_value_iterator(); + return object::start_root(value); +} + +/** + * We decided that calling 'get_double()' on the JSON document '1.233 blabla' should + * give an error, so we check for trailing content. We want to disallow trailing + * content. + * Thus, in several implementations below, we pass a 'true' parameter value to + * a get_root_value_iterator() method: this indicates that we disallow trailing content. + */ + +simdjson_inline simdjson_result document::get_uint64() noexcept { + return get_root_value_iterator().get_root_uint64(true); +} +simdjson_inline simdjson_result document::get_uint64_in_string() noexcept { + return get_root_value_iterator().get_root_uint64_in_string(true); +} +simdjson_inline simdjson_result document::get_int64() noexcept { + return get_root_value_iterator().get_root_int64(true); +} +simdjson_inline simdjson_result document::get_int64_in_string() noexcept { + return get_root_value_iterator().get_root_int64_in_string(true); +} +simdjson_inline simdjson_result document::get_double() noexcept { + return get_root_value_iterator().get_root_double(true); +} +simdjson_inline simdjson_result document::get_double_in_string() noexcept { + return get_root_value_iterator().get_root_double_in_string(true); +} +simdjson_inline simdjson_result document::get_string(bool allow_replacement) noexcept { + return get_root_value_iterator().get_root_string(true, allow_replacement); +} +template +simdjson_inline error_code document::get_string(string_type& receiver, bool allow_replacement) noexcept { + return get_root_value_iterator().get_root_string(receiver, true, allow_replacement); +} +simdjson_inline simdjson_result document::get_wobbly_string() noexcept { + return get_root_value_iterator().get_root_wobbly_string(true); +} +simdjson_inline simdjson_result document::get_raw_json_string() noexcept { + return get_root_value_iterator().get_root_raw_json_string(true); +} +simdjson_inline simdjson_result document::get_bool() noexcept { + return get_root_value_iterator().get_root_bool(true); +} +simdjson_inline simdjson_result document::is_null() noexcept { + return get_root_value_iterator().is_root_null(true); +} + +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_array(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_object(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_double(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_uint64(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_int64(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_bool(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_value(); } + +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_double(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_uint64(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_int64(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_bool(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_value(); } + +template simdjson_inline error_code document::get(T &out) & noexcept { + return get().get(out); +} +template simdjson_inline error_code document::get(T &out) && noexcept { + return std::forward(*this).get().get(out); +} + +#if SIMDJSON_EXCEPTIONS +simdjson_inline document::operator array() & noexcept(false) { return get_array(); } +simdjson_inline document::operator object() & noexcept(false) { return get_object(); } +simdjson_inline document::operator uint64_t() noexcept(false) { return get_uint64(); } +simdjson_inline document::operator int64_t() noexcept(false) { return get_int64(); } +simdjson_inline document::operator double() noexcept(false) { return get_double(); } +simdjson_inline document::operator std::string_view() noexcept(false) { return get_string(false); } +simdjson_inline document::operator raw_json_string() noexcept(false) { return get_raw_json_string(); } +simdjson_inline document::operator bool() noexcept(false) { return get_bool(); } +simdjson_inline document::operator value() noexcept(false) { return get_value(); } + +#endif +simdjson_inline simdjson_result document::count_elements() & noexcept { + auto a = get_array(); + simdjson_result answer = a.count_elements(); + /* If there was an array, we are now left pointing at its first element. */ + if(answer.error() == SUCCESS) { rewind(); } + return answer; +} +simdjson_inline simdjson_result document::count_fields() & noexcept { + auto a = get_object(); + simdjson_result answer = a.count_fields(); + /* If there was an object, we are now left pointing at its first element. */ + if(answer.error() == SUCCESS) { rewind(); } + return answer; +} +simdjson_inline simdjson_result document::at(size_t index) & noexcept { + auto a = get_array(); + return a.at(index); +} +simdjson_inline simdjson_result document::begin() & noexcept { + return get_array().begin(); +} +simdjson_inline simdjson_result document::end() & noexcept { + return {}; +} + +simdjson_inline simdjson_result document::find_field(std::string_view key) & noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result document::find_field(const char *key) & noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result document::find_field_unordered(std::string_view key) & noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result document::find_field_unordered(const char *key) & noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result document::operator[](std::string_view key) & noexcept { + return start_or_resume_object()[key]; +} +simdjson_inline simdjson_result document::operator[](const char *key) & noexcept { + return start_or_resume_object()[key]; +} + +simdjson_inline error_code document::consume() noexcept { + auto error = iter.skip_child(0); + if(error) { iter.abandon(); } + return error; +} + +simdjson_inline simdjson_result document::raw_json() noexcept { + auto _iter = get_root_value_iterator(); + const uint8_t * starting_point{_iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + // After 'consume()', we could be left pointing just beyond the document, but that + // is ok because we are not going to dereference the final pointer position, we just + // use it to compute the length in bytes. + const uint8_t * final_point{iter.unsafe_pointer()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +simdjson_inline simdjson_result document::type() noexcept { + return get_root_value_iterator().type(); +} + +simdjson_inline simdjson_result document::is_scalar() noexcept { + json_type this_type; + auto error = type().get(this_type); + if(error) { return error; } + return ! ((this_type == json_type::array) || (this_type == json_type::object)); +} + +simdjson_inline bool document::is_negative() noexcept { + return get_root_value_iterator().is_root_negative(); +} + +simdjson_inline simdjson_result document::is_integer() noexcept { + return get_root_value_iterator().is_root_integer(true); +} + +simdjson_inline simdjson_result document::get_number_type() noexcept { + return get_root_value_iterator().get_root_number_type(true); +} + +simdjson_inline simdjson_result document::get_number() noexcept { + return get_root_value_iterator().get_root_number(true); +} + + +simdjson_inline simdjson_result document::raw_json_token() noexcept { + auto _iter = get_root_value_iterator(); + return std::string_view(reinterpret_cast(_iter.peek_start()), _iter.peek_start_length()); +} + +simdjson_inline simdjson_result document::at_pointer(std::string_view json_pointer) noexcept { + rewind(); // Rewind the document each time at_pointer is called + if (json_pointer.empty()) { + return this->get_value(); + } + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: + return (*this).get_array().at_pointer(json_pointer); + case json_type::object: + return (*this).get_object().at_pointer(json_pointer); + default: + return INVALID_JSON_POINTER; + } +} + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + haswell::ondemand::document &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base( + error + ) +{ +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) & noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline error_code simdjson_result::rewind() noexcept { + if (error()) { return error(); } + first.rewind(); + return SUCCESS; +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::get_array() & noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() & noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::get_value() noexcept { + if (error()) { return error(); } + return first.get_value(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} + +template +simdjson_inline simdjson_result simdjson_result::get() & noexcept { + if (error()) { return error(); } + return first.get(); +} +template +simdjson_inline simdjson_result simdjson_result::get() && noexcept { + if (error()) { return error(); } + return std::forward(first).get(); +} +template +simdjson_inline error_code simdjson_result::get(T &out) & noexcept { + if (error()) { return error(); } + return first.get(out); +} +template +simdjson_inline error_code simdjson_result::get(T &out) && noexcept { + if (error()) { return error(); } + return std::forward(first).get(out); +} + +template<> simdjson_inline simdjson_result simdjson_result::get() & noexcept = delete; +template<> simdjson_inline simdjson_result simdjson_result::get() && noexcept { + if (error()) { return error(); } + return std::forward(first); +} +template<> simdjson_inline error_code simdjson_result::get(haswell::ondemand::document &out) & noexcept = delete; +template<> simdjson_inline error_code simdjson_result::get(haswell::ondemand::document &out) && noexcept { + if (error()) { return error(); } + out = std::forward(first); + return SUCCESS; +} + +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} + +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} + + +simdjson_inline bool simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} + +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} + +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} + +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} + + +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator haswell::ondemand::array() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator haswell::ondemand::object() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator haswell::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator haswell::ondemand::value() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline bool simdjson_result::at_end() const noexcept { + if (error()) { return error(); } + return first.at_end(); +} + + +simdjson_inline int32_t simdjson_result::current_depth() const noexcept { + if (error()) { return error(); } + return first.current_depth(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + + +} // namespace simdjson + + +namespace simdjson { +namespace haswell { +namespace ondemand { + +simdjson_inline document_reference::document_reference() noexcept : doc{nullptr} {} +simdjson_inline document_reference::document_reference(document &d) noexcept : doc(&d) {} +simdjson_inline void document_reference::rewind() noexcept { doc->rewind(); } +simdjson_inline simdjson_result document_reference::get_array() & noexcept { return doc->get_array(); } +simdjson_inline simdjson_result document_reference::get_object() & noexcept { return doc->get_object(); } +/** + * The document_reference instances are used primarily/solely for streams of JSON + * documents. + * We decided that calling 'get_double()' on the JSON document '1.233 blabla' should + * give an error, so we check for trailing content. + * + * However, for streams of JSON documents, we want to be able to start from + * "321" "321" "321" + * and parse it successfully as a stream of JSON documents, calling get_uint64_in_string() + * successfully each time. + * + * To achieve this result, we pass a 'false' to a get_root_value_iterator() method: + * this indicates that we allow trailing content. + */ +simdjson_inline simdjson_result document_reference::get_uint64() noexcept { return doc->get_root_value_iterator().get_root_uint64(false); } +simdjson_inline simdjson_result document_reference::get_uint64_in_string() noexcept { return doc->get_root_value_iterator().get_root_uint64_in_string(false); } +simdjson_inline simdjson_result document_reference::get_int64() noexcept { return doc->get_root_value_iterator().get_root_int64(false); } +simdjson_inline simdjson_result document_reference::get_int64_in_string() noexcept { return doc->get_root_value_iterator().get_root_int64_in_string(false); } +simdjson_inline simdjson_result document_reference::get_double() noexcept { return doc->get_root_value_iterator().get_root_double(false); } +simdjson_inline simdjson_result document_reference::get_double_in_string() noexcept { return doc->get_root_value_iterator().get_root_double(false); } +simdjson_inline simdjson_result document_reference::get_string(bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(false, allow_replacement); } +template +simdjson_inline error_code document_reference::get_string(string_type& receiver, bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(receiver, false, allow_replacement); } +simdjson_inline simdjson_result document_reference::get_wobbly_string() noexcept { return doc->get_root_value_iterator().get_root_wobbly_string(false); } +simdjson_inline simdjson_result document_reference::get_raw_json_string() noexcept { return doc->get_root_value_iterator().get_root_raw_json_string(false); } +simdjson_inline simdjson_result document_reference::get_bool() noexcept { return doc->get_root_value_iterator().get_root_bool(false); } +simdjson_inline simdjson_result document_reference::get_value() noexcept { return doc->get_value(); } +simdjson_inline simdjson_result document_reference::is_null() noexcept { return doc->get_root_value_iterator().is_root_null(false); } + +#if SIMDJSON_EXCEPTIONS +simdjson_inline document_reference::operator array() & noexcept(false) { return array(*doc); } +simdjson_inline document_reference::operator object() & noexcept(false) { return object(*doc); } +simdjson_inline document_reference::operator uint64_t() noexcept(false) { return get_uint64(); } +simdjson_inline document_reference::operator int64_t() noexcept(false) { return get_int64(); } +simdjson_inline document_reference::operator double() noexcept(false) { return get_double(); } +simdjson_inline document_reference::operator std::string_view() noexcept(false) { return std::string_view(*doc); } +simdjson_inline document_reference::operator raw_json_string() noexcept(false) { return raw_json_string(*doc); } +simdjson_inline document_reference::operator bool() noexcept(false) { return get_bool(); } +simdjson_inline document_reference::operator value() noexcept(false) { return value(*doc); } +#endif +simdjson_inline simdjson_result document_reference::count_elements() & noexcept { return doc->count_elements(); } +simdjson_inline simdjson_result document_reference::count_fields() & noexcept { return doc->count_fields(); } +simdjson_inline simdjson_result document_reference::at(size_t index) & noexcept { return doc->at(index); } +simdjson_inline simdjson_result document_reference::begin() & noexcept { return doc->begin(); } +simdjson_inline simdjson_result document_reference::end() & noexcept { return doc->end(); } +simdjson_inline simdjson_result document_reference::find_field(std::string_view key) & noexcept { return doc->find_field(key); } +simdjson_inline simdjson_result document_reference::find_field(const char *key) & noexcept { return doc->find_field(key); } +simdjson_inline simdjson_result document_reference::operator[](std::string_view key) & noexcept { return (*doc)[key]; } +simdjson_inline simdjson_result document_reference::operator[](const char *key) & noexcept { return (*doc)[key]; } +simdjson_inline simdjson_result document_reference::find_field_unordered(std::string_view key) & noexcept { return doc->find_field_unordered(key); } +simdjson_inline simdjson_result document_reference::find_field_unordered(const char *key) & noexcept { return doc->find_field_unordered(key); } +simdjson_inline simdjson_result document_reference::type() noexcept { return doc->type(); } +simdjson_inline simdjson_result document_reference::is_scalar() noexcept { return doc->is_scalar(); } +simdjson_inline simdjson_result document_reference::current_location() noexcept { return doc->current_location(); } +simdjson_inline int32_t document_reference::current_depth() const noexcept { return doc->current_depth(); } +simdjson_inline bool document_reference::is_negative() noexcept { return doc->is_negative(); } +simdjson_inline simdjson_result document_reference::is_integer() noexcept { return doc->get_root_value_iterator().is_root_integer(false); } +simdjson_inline simdjson_result document_reference::get_number_type() noexcept { return doc->get_root_value_iterator().get_root_number_type(false); } +simdjson_inline simdjson_result document_reference::get_number() noexcept { return doc->get_root_value_iterator().get_root_number(false); } +simdjson_inline simdjson_result document_reference::raw_json_token() noexcept { return doc->raw_json_token(); } +simdjson_inline simdjson_result document_reference::at_pointer(std::string_view json_pointer) noexcept { return doc->at_pointer(json_pointer); } +simdjson_inline simdjson_result document_reference::raw_json() noexcept { return doc->raw_json();} +simdjson_inline document_reference::operator document&() const noexcept { return *doc; } + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + + + +namespace simdjson { +simdjson_inline simdjson_result::simdjson_result(haswell::ondemand::document_reference value, error_code error) + noexcept : implementation_simdjson_result_base(std::forward(value), error) {} + + +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) & noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline error_code simdjson_result::rewind() noexcept { + if (error()) { return error(); } + first.rewind(); + return SUCCESS; +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::get_array() & noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() & noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::get_value() noexcept { + if (error()) { return error(); } + return first.get_value(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} +simdjson_inline simdjson_result simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator haswell::ondemand::array() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator haswell::ondemand::object() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator haswell::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator haswell::ondemand::value() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H +/* end file simdjson/generic/ondemand/document-inl.h for haswell */ +/* including simdjson/generic/ondemand/document_stream-inl.h for haswell: #include "simdjson/generic/ondemand/document_stream-inl.h" */ +/* begin file simdjson/generic/ondemand/document_stream-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document_stream.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include + +namespace simdjson { +namespace haswell { +namespace ondemand { + +#ifdef SIMDJSON_THREADS_ENABLED + +inline void stage1_worker::finish() { + // After calling "run" someone would call finish() to wait + // for the end of the processing. + // This function will wait until either the thread has done + // the processing or, else, the destructor has been called. + std::unique_lock lock(locking_mutex); + cond_var.wait(lock, [this]{return has_work == false;}); +} + +inline stage1_worker::~stage1_worker() { + // The thread may never outlive the stage1_worker instance + // and will always be stopped/joined before the stage1_worker + // instance is gone. + stop_thread(); +} + +inline void stage1_worker::start_thread() { + std::unique_lock lock(locking_mutex); + if(thread.joinable()) { + return; // This should never happen but we never want to create more than one thread. + } + thread = std::thread([this]{ + while(true) { + std::unique_lock thread_lock(locking_mutex); + // We wait for either "run" or "stop_thread" to be called. + cond_var.wait(thread_lock, [this]{return has_work || !can_work;}); + // If, for some reason, the stop_thread() method was called (i.e., the + // destructor of stage1_worker is called, then we want to immediately destroy + // the thread (and not do any more processing). + if(!can_work) { + break; + } + this->owner->stage1_thread_error = this->owner->run_stage1(*this->stage1_thread_parser, + this->_next_batch_start); + this->has_work = false; + // The condition variable call should be moved after thread_lock.unlock() for performance + // reasons but thread sanitizers may report it as a data race if we do. + // See https://stackoverflow.com/questions/35775501/c-should-condition-variable-be-notified-under-lock + cond_var.notify_one(); // will notify "finish" + thread_lock.unlock(); + } + } + ); +} + + +inline void stage1_worker::stop_thread() { + std::unique_lock lock(locking_mutex); + // We have to make sure that all locks can be released. + can_work = false; + has_work = false; + cond_var.notify_all(); + lock.unlock(); + if(thread.joinable()) { + thread.join(); + } +} + +inline void stage1_worker::run(document_stream * ds, parser * stage1, size_t next_batch_start) { + std::unique_lock lock(locking_mutex); + owner = ds; + _next_batch_start = next_batch_start; + stage1_thread_parser = stage1; + has_work = true; + // The condition variable call should be moved after thread_lock.unlock() for performance + // reasons but thread sanitizers may report it as a data race if we do. + // See https://stackoverflow.com/questions/35775501/c-should-condition-variable-be-notified-under-lock + cond_var.notify_one(); // will notify the thread lock that we have work + lock.unlock(); +} + +#endif // SIMDJSON_THREADS_ENABLED + +simdjson_inline document_stream::document_stream( + ondemand::parser &_parser, + const uint8_t *_buf, + size_t _len, + size_t _batch_size, + bool _allow_comma_separated +) noexcept + : parser{&_parser}, + buf{_buf}, + len{_len}, + batch_size{_batch_size <= MINIMAL_BATCH_SIZE ? MINIMAL_BATCH_SIZE : _batch_size}, + allow_comma_separated{_allow_comma_separated}, + error{SUCCESS} + #ifdef SIMDJSON_THREADS_ENABLED + , use_thread(_parser.threaded) // we need to make a copy because _parser.threaded can change + #endif +{ +#ifdef SIMDJSON_THREADS_ENABLED + if(worker.get() == nullptr) { + error = MEMALLOC; + } +#endif +} + +simdjson_inline document_stream::document_stream() noexcept + : parser{nullptr}, + buf{nullptr}, + len{0}, + batch_size{0}, + allow_comma_separated{false}, + error{UNINITIALIZED} + #ifdef SIMDJSON_THREADS_ENABLED + , use_thread(false) + #endif +{ +} + +simdjson_inline document_stream::~document_stream() noexcept +{ + #ifdef SIMDJSON_THREADS_ENABLED + worker.reset(); + #endif +} + +inline size_t document_stream::size_in_bytes() const noexcept { + return len; +} + +inline size_t document_stream::truncated_bytes() const noexcept { + if(error == CAPACITY) { return len - batch_start; } + return parser->implementation->structural_indexes[parser->implementation->n_structural_indexes] - parser->implementation->structural_indexes[parser->implementation->n_structural_indexes + 1]; +} + +simdjson_inline document_stream::iterator::iterator() noexcept + : stream{nullptr}, finished{true} { +} + +simdjson_inline document_stream::iterator::iterator(document_stream* _stream, bool is_end) noexcept + : stream{_stream}, finished{is_end} { +} + +simdjson_inline simdjson_result document_stream::iterator::operator*() noexcept { + //if(stream->error) { return stream->error; } + return simdjson_result(stream->doc, stream->error); +} + +simdjson_inline document_stream::iterator& document_stream::iterator::operator++() noexcept { + // If there is an error, then we want the iterator + // to be finished, no matter what. (E.g., we do not + // keep generating documents with errors, or go beyond + // a document with errors.) + // + // Users do not have to call "operator*()" when they use operator++, + // so we need to end the stream in the operator++ function. + // + // Note that setting finished = true is essential otherwise + // we would enter an infinite loop. + if (stream->error) { finished = true; } + // Note that stream->error() is guarded against error conditions + // (it will immediately return if stream->error casts to false). + // In effect, this next function does nothing when (stream->error) + // is true (hence the risk of an infinite loop). + stream->next(); + // If that was the last document, we're finished. + // It is the only type of error we do not want to appear + // in operator*. + if (stream->error == EMPTY) { finished = true; } + // If we had any other kind of error (not EMPTY) then we want + // to pass it along to the operator* and we cannot mark the result + // as "finished" just yet. + return *this; +} + +simdjson_inline bool document_stream::iterator::operator!=(const document_stream::iterator &other) const noexcept { + return finished != other.finished; +} + +simdjson_inline document_stream::iterator document_stream::begin() noexcept { + start(); + // If there are no documents, we're finished. + return iterator(this, error == EMPTY); +} + +simdjson_inline document_stream::iterator document_stream::end() noexcept { + return iterator(this, true); +} + +inline void document_stream::start() noexcept { + if (error) { return; } + error = parser->allocate(batch_size); + if (error) { return; } + // Always run the first stage 1 parse immediately + batch_start = 0; + error = run_stage1(*parser, batch_start); + while(error == EMPTY) { + // In exceptional cases, we may start with an empty block + batch_start = next_batch_start(); + if (batch_start >= len) { return; } + error = run_stage1(*parser, batch_start); + } + if (error) { return; } + doc_index = batch_start; + doc = document(json_iterator(&buf[batch_start], parser)); + doc.iter._streaming = true; + + #ifdef SIMDJSON_THREADS_ENABLED + if (use_thread && next_batch_start() < len) { + // Kick off the first thread on next batch if needed + error = stage1_thread_parser.allocate(batch_size); + if (error) { return; } + worker->start_thread(); + start_stage1_thread(); + if (error) { return; } + } + #endif // SIMDJSON_THREADS_ENABLED +} + +inline void document_stream::next() noexcept { + // We always enter at once once in an error condition. + if (error) { return; } + next_document(); + if (error) { return; } + auto cur_struct_index = doc.iter._root - parser->implementation->structural_indexes.get(); + doc_index = batch_start + parser->implementation->structural_indexes[cur_struct_index]; + + // Check if at end of structural indexes (i.e. at end of batch) + if(cur_struct_index >= static_cast(parser->implementation->n_structural_indexes)) { + error = EMPTY; + // Load another batch (if available) + while (error == EMPTY) { + batch_start = next_batch_start(); + if (batch_start >= len) { break; } + #ifdef SIMDJSON_THREADS_ENABLED + if(use_thread) { + load_from_stage1_thread(); + } else { + error = run_stage1(*parser, batch_start); + } + #else + error = run_stage1(*parser, batch_start); + #endif + /** + * Whenever we move to another window, we need to update all pointers to make + * it appear as if the input buffer started at the beginning of the window. + * + * Take this input: + * + * {"z":5} {"1":1,"2":2,"4":4} [7, 10, 9] [15, 11, 12, 13] [154, 110, 112, 1311] + * + * Say you process the following window... + * + * '{"z":5} {"1":1,"2":2,"4":4} [7, 10, 9]' + * + * When you do so, the json_iterator has a pointer at the beginning of the memory region + * (pointing at the beginning of '{"z"...'. + * + * When you move to the window that starts at... + * + * '[7, 10, 9] [15, 11, 12, 13] ... + * + * then it is not sufficient to just run stage 1. You also need to re-anchor the + * json_iterator so that it believes we are starting at '[7, 10, 9]...'. + * + * Under the DOM front-end, this gets done automatically because the parser owns + * the pointer the data, and when you call stage1 and then stage2 on the same + * parser, then stage2 will run on the pointer acquired by stage1. + * + * That is, stage1 calls "this->buf = _buf" so the parser remembers the buffer that + * we used. But json_iterator has no callback when stage1 is called on the parser. + * In fact, I think that the parser is unaware of json_iterator. + * + * + * So we need to re-anchor the json_iterator after each call to stage 1 so that + * all of the pointers are in sync. + */ + doc.iter = json_iterator(&buf[batch_start], parser); + doc.iter._streaming = true; + /** + * End of resync. + */ + + if (error) { continue; } // If the error was EMPTY, we may want to load another batch. + doc_index = batch_start; + } + } +} + +inline void document_stream::next_document() noexcept { + // Go to next place where depth=0 (document depth) + error = doc.iter.skip_child(0); + if (error) { return; } + // Always set depth=1 at the start of document + doc.iter._depth = 1; + // consume comma if comma separated is allowed + if (allow_comma_separated) { doc.iter.consume_character(','); } + // Resets the string buffer at the beginning, thus invalidating the strings. + doc.iter._string_buf_loc = parser->string_buf.get(); + doc.iter._root = doc.iter.position(); +} + +inline size_t document_stream::next_batch_start() const noexcept { + return batch_start + parser->implementation->structural_indexes[parser->implementation->n_structural_indexes]; +} + +inline error_code document_stream::run_stage1(ondemand::parser &p, size_t _batch_start) noexcept { + // This code only updates the structural index in the parser, it does not update any json_iterator + // instance. + size_t remaining = len - _batch_start; + if (remaining <= batch_size) { + return p.implementation->stage1(&buf[_batch_start], remaining, stage1_mode::streaming_final); + } else { + return p.implementation->stage1(&buf[_batch_start], batch_size, stage1_mode::streaming_partial); + } +} + +simdjson_inline size_t document_stream::iterator::current_index() const noexcept { + return stream->doc_index; +} + +simdjson_inline std::string_view document_stream::iterator::source() const noexcept { + auto depth = stream->doc.iter.depth(); + auto cur_struct_index = stream->doc.iter._root - stream->parser->implementation->structural_indexes.get(); + + // If at root, process the first token to determine if scalar value + if (stream->doc.iter.at_root()) { + switch (stream->buf[stream->batch_start + stream->parser->implementation->structural_indexes[cur_struct_index]]) { + case '{': case '[': // Depth=1 already at start of document + break; + case '}': case ']': + depth--; + break; + default: // Scalar value document + // TODO: Remove any trailing whitespaces + // This returns a string spanning from start of value to the beginning of the next document (excluded) + return std::string_view(reinterpret_cast(stream->buf) + current_index(), stream->parser->implementation->structural_indexes[++cur_struct_index] - current_index() - 1); + } + cur_struct_index++; + } + + while (cur_struct_index <= static_cast(stream->parser->implementation->n_structural_indexes)) { + switch (stream->buf[stream->batch_start + stream->parser->implementation->structural_indexes[cur_struct_index]]) { + case '{': case '[': + depth++; + break; + case '}': case ']': + depth--; + break; + } + if (depth == 0) { break; } + cur_struct_index++; + } + + return std::string_view(reinterpret_cast(stream->buf) + current_index(), stream->parser->implementation->structural_indexes[cur_struct_index] - current_index() + stream->batch_start + 1);; +} + +inline error_code document_stream::iterator::error() const noexcept { + return stream->error; +} + +#ifdef SIMDJSON_THREADS_ENABLED + +inline void document_stream::load_from_stage1_thread() noexcept { + worker->finish(); + // Swap to the parser that was loaded up in the thread. Make sure the parser has + // enough memory to swap to, as well. + std::swap(stage1_thread_parser,*parser); + error = stage1_thread_error; + if (error) { return; } + + // If there's anything left, start the stage 1 thread! + if (next_batch_start() < len) { + start_stage1_thread(); + } +} + +inline void document_stream::start_stage1_thread() noexcept { + // we call the thread on a lambda that will update + // this->stage1_thread_error + // there is only one thread that may write to this value + // TODO this is NOT exception-safe. + this->stage1_thread_error = UNINITIALIZED; // In case something goes wrong, make sure it's an error + size_t _next_batch_start = this->next_batch_start(); + + worker->run(this, & this->stage1_thread_parser, _next_batch_start); +} + +#endif // SIMDJSON_THREADS_ENABLED + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} +simdjson_inline simdjson_result::simdjson_result( + haswell::ondemand::document_stream &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} + +} + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H +/* end file simdjson/generic/ondemand/document_stream-inl.h for haswell */ +/* including simdjson/generic/ondemand/field-inl.h for haswell: #include "simdjson/generic/ondemand/field-inl.h" */ +/* begin file simdjson/generic/ondemand/field-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +// clang 6 doesn't think the default constructor can be noexcept, so we make it explicit +simdjson_inline field::field() noexcept : std::pair() {} + +simdjson_inline field::field(raw_json_string key, ondemand::value &&value) noexcept + : std::pair(key, std::forward(value)) +{ +} + +simdjson_inline simdjson_result field::start(value_iterator &parent_iter) noexcept { + raw_json_string key; + SIMDJSON_TRY( parent_iter.field_key().get(key) ); + SIMDJSON_TRY( parent_iter.field_value() ); + return field::start(parent_iter, key); +} + +simdjson_inline simdjson_result field::start(const value_iterator &parent_iter, raw_json_string key) noexcept { + return field(key, parent_iter.child()); +} + +simdjson_inline simdjson_warn_unused simdjson_result field::unescaped_key(bool allow_replacement) noexcept { + SIMDJSON_ASSUME(first.buf != nullptr); // We would like to call .alive() but Visual Studio won't let us. + simdjson_result answer = first.unescape(second.iter.json_iter(), allow_replacement); + first.consume(); + return answer; +} + +simdjson_inline raw_json_string field::key() const noexcept { + SIMDJSON_ASSUME(first.buf != nullptr); // We would like to call .alive() by Visual Studio won't let us. + return first; +} + +simdjson_inline value &field::value() & noexcept { + return second; +} + +simdjson_inline value field::value() && noexcept { + return std::forward(*this).second; +} + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + haswell::ondemand::field &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} + +simdjson_inline simdjson_result simdjson_result::key() noexcept { + if (error()) { return error(); } + return first.key(); +} +simdjson_inline simdjson_result simdjson_result::unescaped_key(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.unescaped_key(allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::value() noexcept { + if (error()) { return error(); } + return std::move(first.value()); +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H +/* end file simdjson/generic/ondemand/field-inl.h for haswell */ +/* including simdjson/generic/ondemand/json_iterator-inl.h for haswell: #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/json_iterator-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +simdjson_inline json_iterator::json_iterator(json_iterator &&other) noexcept + : token(std::forward(other.token)), + parser{other.parser}, + _string_buf_loc{other._string_buf_loc}, + error{other.error}, + _depth{other._depth}, + _root{other._root}, + _streaming{other._streaming} +{ + other.parser = nullptr; +} +simdjson_inline json_iterator &json_iterator::operator=(json_iterator &&other) noexcept { + token = other.token; + parser = other.parser; + _string_buf_loc = other._string_buf_loc; + error = other.error; + _depth = other._depth; + _root = other._root; + _streaming = other._streaming; + other.parser = nullptr; + return *this; +} + +simdjson_inline json_iterator::json_iterator(const uint8_t *buf, ondemand::parser *_parser) noexcept + : token(buf, &_parser->implementation->structural_indexes[0]), + parser{_parser}, + _string_buf_loc{parser->string_buf.get()}, + _depth{1}, + _root{parser->implementation->structural_indexes.get()}, + _streaming{false} + +{ + logger::log_headers(); +#if SIMDJSON_CHECK_EOF + assert_more_tokens(); +#endif +} + +inline void json_iterator::rewind() noexcept { + token.set_position( root_position() ); + logger::log_headers(); // We start again + _string_buf_loc = parser->string_buf.get(); + _depth = 1; +} + +inline bool json_iterator::balanced() const noexcept { + token_iterator ti(token); + int32_t count{0}; + ti.set_position( root_position() ); + while(ti.peek() <= peek_last()) { + switch (*ti.return_current_and_advance()) + { + case '[': case '{': + count++; + break; + case ']': case '}': + count--; + break; + default: + break; + } + } + return count == 0; +} + + +// GCC 7 warns when the first line of this function is inlined away into oblivion due to the caller +// relating depth and parent_depth, which is a desired effect. The warning does not show up if the +// skip_child() function is not marked inline). +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_warn_unused simdjson_inline error_code json_iterator::skip_child(depth_t parent_depth) noexcept { + if (depth() <= parent_depth) { return SUCCESS; } + switch (*return_current_and_advance()) { + // TODO consider whether matching braces is a requirement: if non-matching braces indicates + // *missing* braces, then future lookups are not in the object/arrays they think they are, + // violating the rule "validate enough structure that the user can be confident they are + // looking at the right values." + // PERF TODO we can eliminate the switch here with a lookup of how much to add to depth + + // For the first open array/object in a value, we've already incremented depth, so keep it the same + // We never stop at colon, but if we did, it wouldn't affect depth + case '[': case '{': case ':': + logger::log_start_value(*this, "skip"); + break; + // If there is a comma, we have just finished a value in an array/object, and need to get back in + case ',': + logger::log_value(*this, "skip"); + break; + // ] or } means we just finished a value and need to jump out of the array/object + case ']': case '}': + logger::log_end_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } +#if SIMDJSON_CHECK_EOF + // If there are no more tokens, the parent is incomplete. + if (at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "Missing [ or { at start"); } +#endif // SIMDJSON_CHECK_EOF + break; + case '"': + if(*peek() == ':') { + // We are at a key!!! + // This might happen if you just started an object and you skip it immediately. + // Performance note: it would be nice to get rid of this check as it is somewhat + // expensive. + // https://github.com/simdjson/simdjson/issues/1742 + logger::log_value(*this, "key"); + return_current_and_advance(); // eat up the ':' + break; // important!!! + } + simdjson_fallthrough; + // Anything else must be a scalar value + default: + // For the first scalar, we will have incremented depth already, so we decrement it here. + logger::log_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } + break; + } + + // Now that we've considered the first value, we only increment/decrement for arrays/objects + while (position() < end_position()) { + switch (*return_current_and_advance()) { + case '[': case '{': + logger::log_start_value(*this, "skip"); + _depth++; + break; + // TODO consider whether matching braces is a requirement: if non-matching braces indicates + // *missing* braces, then future lookups are not in the object/arrays they think they are, + // violating the rule "validate enough structure that the user can be confident they are + // looking at the right values." + // PERF TODO we can eliminate the switch here with a lookup of how much to add to depth + case ']': case '}': + logger::log_end_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } + break; + default: + logger::log_value(*this, "skip", ""); + break; + } + } + + return report_error(TAPE_ERROR, "not enough close braces"); +} + +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline bool json_iterator::at_root() const noexcept { + return position() == root_position(); +} + +simdjson_inline bool json_iterator::is_single_token() const noexcept { + return parser->implementation->n_structural_indexes == 1; +} + +simdjson_inline bool json_iterator::streaming() const noexcept { + return _streaming; +} + +simdjson_inline token_position json_iterator::root_position() const noexcept { + return _root; +} + +simdjson_inline void json_iterator::assert_at_document_depth() const noexcept { + SIMDJSON_ASSUME( _depth == 1 ); +} + +simdjson_inline void json_iterator::assert_at_root() const noexcept { + SIMDJSON_ASSUME( _depth == 1 ); +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + // Under Visual Studio, the next SIMDJSON_ASSUME fails with: the argument + // has side effects that will be discarded. + SIMDJSON_ASSUME( token.position() == _root ); +#endif +} + +simdjson_inline void json_iterator::assert_more_tokens(uint32_t required_tokens) const noexcept { + assert_valid_position(token._position + required_tokens - 1); +} + +simdjson_inline void json_iterator::assert_valid_position(token_position position) const noexcept { +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + SIMDJSON_ASSUME( position >= &parser->implementation->structural_indexes[0] ); + SIMDJSON_ASSUME( position < &parser->implementation->structural_indexes[parser->implementation->n_structural_indexes] ); +#endif +} + +simdjson_inline bool json_iterator::at_end() const noexcept { + return position() == end_position(); +} +simdjson_inline token_position json_iterator::end_position() const noexcept { + uint32_t n_structural_indexes{parser->implementation->n_structural_indexes}; + return &parser->implementation->structural_indexes[n_structural_indexes]; +} + +inline std::string json_iterator::to_string() const noexcept { + if( !is_alive() ) { return "dead json_iterator instance"; } + const char * current_structural = reinterpret_cast(token.peek()); + return std::string("json_iterator [ depth : ") + std::to_string(_depth) + + std::string(", structural : '") + std::string(current_structural,1) + + std::string("', offset : ") + std::to_string(token.current_offset()) + + std::string("', error : ") + error_message(error) + + std::string(" ]"); +} + +inline simdjson_result json_iterator::current_location() const noexcept { + if (!is_alive()) { // Unrecoverable error + if (!at_root()) { + return reinterpret_cast(token.peek(-1)); + } else { + return reinterpret_cast(token.peek()); + } + } + if (at_end()) { + return OUT_OF_BOUNDS; + } + return reinterpret_cast(token.peek()); +} + +simdjson_inline bool json_iterator::is_alive() const noexcept { + return parser; +} + +simdjson_inline void json_iterator::abandon() noexcept { + parser = nullptr; + _depth = 0; +} + +simdjson_inline const uint8_t *json_iterator::return_current_and_advance() noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(); +#endif // SIMDJSON_CHECK_EOF + return token.return_current_and_advance(); +} + +simdjson_inline const uint8_t *json_iterator::unsafe_pointer() const noexcept { + // deliberately done without safety guard: + return token.peek(); +} + +simdjson_inline const uint8_t *json_iterator::peek(int32_t delta) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(delta+1); +#endif // SIMDJSON_CHECK_EOF + return token.peek(delta); +} + +simdjson_inline uint32_t json_iterator::peek_length(int32_t delta) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(delta+1); +#endif // #if SIMDJSON_CHECK_EOF + return token.peek_length(delta); +} + +simdjson_inline const uint8_t *json_iterator::peek(token_position position) const noexcept { + // todo: currently we require end-of-string buffering, but the following + // assert_valid_position should be turned on if/when we lift that condition. + // assert_valid_position(position); + // This is almost surely related to SIMDJSON_CHECK_EOF but given that SIMDJSON_CHECK_EOF + // is ON by default, we have no choice but to disable it for real with a comment. + return token.peek(position); +} + +simdjson_inline uint32_t json_iterator::peek_length(token_position position) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_valid_position(position); +#endif // SIMDJSON_CHECK_EOF + return token.peek_length(position); +} + +simdjson_inline token_position json_iterator::last_position() const noexcept { + // The following line fails under some compilers... + // SIMDJSON_ASSUME(parser->implementation->n_structural_indexes > 0); + // since it has side-effects. + uint32_t n_structural_indexes{parser->implementation->n_structural_indexes}; + SIMDJSON_ASSUME(n_structural_indexes > 0); + return &parser->implementation->structural_indexes[n_structural_indexes - 1]; +} +simdjson_inline const uint8_t *json_iterator::peek_last() const noexcept { + return token.peek(last_position()); +} + +simdjson_inline void json_iterator::ascend_to(depth_t parent_depth) noexcept { + SIMDJSON_ASSUME(parent_depth >= 0 && parent_depth < INT32_MAX - 1); + SIMDJSON_ASSUME(_depth == parent_depth + 1); + _depth = parent_depth; +} + +simdjson_inline void json_iterator::descend_to(depth_t child_depth) noexcept { + SIMDJSON_ASSUME(child_depth >= 1 && child_depth < INT32_MAX); + SIMDJSON_ASSUME(_depth == child_depth - 1); + _depth = child_depth; +} + +simdjson_inline depth_t json_iterator::depth() const noexcept { + return _depth; +} + +simdjson_inline uint8_t *&json_iterator::string_buf_loc() noexcept { + return _string_buf_loc; +} + +simdjson_inline error_code json_iterator::report_error(error_code _error, const char *message) noexcept { + SIMDJSON_ASSUME(_error != SUCCESS && _error != UNINITIALIZED && _error != INCORRECT_TYPE && _error != NO_SUCH_FIELD); + logger::log_error(*this, message); + error = _error; + return error; +} + +simdjson_inline token_position json_iterator::position() const noexcept { + return token.position(); +} + +simdjson_inline simdjson_result json_iterator::unescape(raw_json_string in, bool allow_replacement) noexcept { + return parser->unescape(in, _string_buf_loc, allow_replacement); +} + +simdjson_inline simdjson_result json_iterator::unescape_wobbly(raw_json_string in) noexcept { + return parser->unescape_wobbly(in, _string_buf_loc); +} + +simdjson_inline void json_iterator::reenter_child(token_position position, depth_t child_depth) noexcept { + SIMDJSON_ASSUME(child_depth >= 1 && child_depth < INT32_MAX); + SIMDJSON_ASSUME(_depth == child_depth - 1); +#if SIMDJSON_DEVELOPMENT_CHECKS +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + SIMDJSON_ASSUME(size_t(child_depth) < parser->max_depth()); + SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]); +#endif +#endif + token.set_position(position); + _depth = child_depth; +} + +simdjson_inline error_code json_iterator::consume_character(char c) noexcept { + if (*peek() == c) { + return_current_and_advance(); + return SUCCESS; + } + return TAPE_ERROR; +} + +#if SIMDJSON_DEVELOPMENT_CHECKS + +simdjson_inline token_position json_iterator::start_position(depth_t depth) const noexcept { + SIMDJSON_ASSUME(size_t(depth) < parser->max_depth()); + return size_t(depth) < parser->max_depth() ? parser->start_positions[depth] : 0; +} + +simdjson_inline void json_iterator::set_start_position(depth_t depth, token_position position) noexcept { + SIMDJSON_ASSUME(size_t(depth) < parser->max_depth()); + if(size_t(depth) < parser->max_depth()) { parser->start_positions[depth] = position; } +} + +#endif + + +simdjson_inline error_code json_iterator::optional_error(error_code _error, const char *message) noexcept { + SIMDJSON_ASSUME(_error == INCORRECT_TYPE || _error == NO_SUCH_FIELD); + logger::log_error(*this, message); + return _error; +} + + +simdjson_warn_unused simdjson_inline bool json_iterator::copy_to_buffer(const uint8_t *json, uint32_t max_len, uint8_t *tmpbuf, size_t N) noexcept { + // This function is not expected to be called in performance-sensitive settings. + // Let us guard against silly cases: + if((N < max_len) || (N == 0)) { return false; } + // Copy to the buffer. + std::memcpy(tmpbuf, json, max_len); + if(N > max_len) { // We pad whatever remains with ' '. + std::memset(tmpbuf + max_len, ' ', N - max_len); + } + return true; +} + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(haswell::ondemand::json_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/json_iterator-inl.h for haswell */ +/* including simdjson/generic/ondemand/json_type-inl.h for haswell: #include "simdjson/generic/ondemand/json_type-inl.h" */ +/* begin file simdjson/generic/ondemand/json_type-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +inline std::ostream& operator<<(std::ostream& out, json_type type) noexcept { + switch (type) { + case json_type::array: out << "array"; break; + case json_type::object: out << "object"; break; + case json_type::number: out << "number"; break; + case json_type::string: out << "string"; break; + case json_type::boolean: out << "boolean"; break; + case json_type::null: out << "null"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson_result &type) noexcept(false) { + return out << type.value(); +} +#endif + + + +simdjson_inline number_type number::get_number_type() const noexcept { + return type; +} + +simdjson_inline bool number::is_uint64() const noexcept { + return get_number_type() == number_type::unsigned_integer; +} + +simdjson_inline uint64_t number::get_uint64() const noexcept { + return payload.unsigned_integer; +} + +simdjson_inline number::operator uint64_t() const noexcept { + return get_uint64(); +} + + +simdjson_inline bool number::is_int64() const noexcept { + return get_number_type() == number_type::signed_integer; +} + +simdjson_inline int64_t number::get_int64() const noexcept { + return payload.signed_integer; +} + +simdjson_inline number::operator int64_t() const noexcept { + return get_int64(); +} + +simdjson_inline bool number::is_double() const noexcept { + return get_number_type() == number_type::floating_point_number; +} + +simdjson_inline double number::get_double() const noexcept { + return payload.floating_point_number; +} + +simdjson_inline number::operator double() const noexcept { + return get_double(); +} + +simdjson_inline double number::as_double() const noexcept { + if(is_double()) { + return payload.floating_point_number; + } + if(is_int64()) { + return double(payload.signed_integer); + } + return double(payload.unsigned_integer); +} + +simdjson_inline void number::append_s64(int64_t value) noexcept { + payload.signed_integer = value; + type = number_type::signed_integer; +} + +simdjson_inline void number::append_u64(uint64_t value) noexcept { + payload.unsigned_integer = value; + type = number_type::unsigned_integer; +} + +simdjson_inline void number::append_double(double value) noexcept { + payload.floating_point_number = value; + type = number_type::floating_point_number; +} + +simdjson_inline void number::skip_double() noexcept { + type = number_type::floating_point_number; +} + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(haswell::ondemand::json_type &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H +/* end file simdjson/generic/ondemand/json_type-inl.h for haswell */ +/* including simdjson/generic/ondemand/logger-inl.h for haswell: #include "simdjson/generic/ondemand/logger-inl.h" */ +/* begin file simdjson/generic/ondemand/logger-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include + +namespace simdjson { +namespace haswell { +namespace ondemand { +namespace logger { + +static constexpr const char * DASHES = "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"; +static constexpr const int LOG_EVENT_LEN = 20; +static constexpr const int LOG_BUFFER_LEN = 30; +static constexpr const int LOG_SMALL_BUFFER_LEN = 10; +static int log_depth = 0; // Not threadsafe. Log only. + +// Helper to turn unprintable or newline characters into spaces +static inline char printable_char(char c) { + if (c >= 0x20) { + return c; + } else { + return ' '; + } +} + +template +static inline std::string string_format(const std::string& format, const Args&... args) +{ + SIMDJSON_PUSH_DISABLE_ALL_WARNINGS + int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; + auto size = static_cast(size_s); + if (size <= 0) return std::string(); + std::unique_ptr buf(new char[size]); + std::snprintf(buf.get(), size, format.c_str(), args...); + SIMDJSON_POP_DISABLE_WARNINGS + return std::string(buf.get(), buf.get() + size - 1); +} + +static inline log_level get_log_level_from_env() +{ + SIMDJSON_PUSH_DISABLE_WARNINGS + SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe + char *lvl = getenv("SIMDJSON_LOG_LEVEL"); + SIMDJSON_POP_DISABLE_WARNINGS + if (lvl && simdjson_strcasecmp(lvl, "ERROR") == 0) { return log_level::error; } + return log_level::info; +} + +static inline log_level log_threshold() +{ + static log_level threshold = get_log_level_from_env(); + return threshold; +} + +static inline bool should_log(log_level level) +{ + return level >= log_threshold(); +} + +inline void log_event(const json_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_line(iter, "", type, detail, delta, depth_delta, log_level::info); +} + +inline void log_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail) noexcept { + log_line(iter, index, depth, "", type, detail, log_level::info); +} +inline void log_value(const json_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_line(iter, "", type, detail, delta, depth_delta, log_level::info); +} + +inline void log_start_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail) noexcept { + log_line(iter, index, depth, "+", type, detail, log_level::info); + if (LOG_ENABLED) { log_depth++; } +} +inline void log_start_value(const json_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_line(iter, "+", type, "", delta, depth_delta, log_level::info); + if (LOG_ENABLED) { log_depth++; } +} + +inline void log_end_value(const json_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + if (LOG_ENABLED) { log_depth--; } + log_line(iter, "-", type, "", delta, depth_delta, log_level::info); +} + +inline void log_error(const json_iterator &iter, const char *error, const char *detail, int delta, int depth_delta) noexcept { + log_line(iter, "ERROR: ", error, detail, delta, depth_delta, log_level::error); +} +inline void log_error(const json_iterator &iter, token_position index, depth_t depth, const char *error, const char *detail) noexcept { + log_line(iter, index, depth, "ERROR: ", error, detail, log_level::error); +} + +inline void log_event(const value_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_event(iter.json_iter(), type, detail, delta, depth_delta); +} + +inline void log_value(const value_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_value(iter.json_iter(), type, detail, delta, depth_delta); +} + +inline void log_start_value(const value_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_start_value(iter.json_iter(), type, delta, depth_delta); +} + +inline void log_end_value(const value_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_end_value(iter.json_iter(), type, delta, depth_delta); +} + +inline void log_error(const value_iterator &iter, const char *error, const char *detail, int delta, int depth_delta) noexcept { + log_error(iter.json_iter(), error, detail, delta, depth_delta); +} + +inline void log_headers() noexcept { + if (LOG_ENABLED) { + if (simdjson_unlikely(should_log(log_level::info))) { + // Technically a static variable is not thread-safe, but if you are using threads and logging... well... + static bool displayed_hint{false}; + log_depth = 0; + printf("\n"); + if (!displayed_hint) { + // We only print this helpful header once. + printf("# Logging provides the depth and position of the iterator user-visible steps:\n"); + printf("# +array says 'this is where we were when we discovered the start array'\n"); + printf( + "# -array says 'this is where we were when we ended the array'\n"); + printf("# skip says 'this is a structural or value I am skipping'\n"); + printf("# +/-skip says 'this is a start/end array or object I am skipping'\n"); + printf("#\n"); + printf("# The indentation of the terms (array, string,...) indicates the depth,\n"); + printf("# in addition to the depth being displayed.\n"); + printf("#\n"); + printf("# Every token in the document has a single depth determined by the tokens before it,\n"); + printf("# and is not affected by what the token actually is.\n"); + printf("#\n"); + printf("# Not all structural elements are presented as tokens in the logs.\n"); + printf("#\n"); + printf("# We never give control to the user within an empty array or an empty object.\n"); + printf("#\n"); + printf("# Inside an array, having a depth greater than the array's depth means that\n"); + printf("# we are pointing inside a value.\n"); + printf("# Having a depth equal to the array means that we are pointing right before a value.\n"); + printf("# Having a depth smaller than the array means that we have moved beyond the array.\n"); + displayed_hint = true; + } + printf("\n"); + printf("| %-*s ", LOG_EVENT_LEN, "Event"); + printf("| %-*s ", LOG_BUFFER_LEN, "Buffer"); + printf("| %-*s ", LOG_SMALL_BUFFER_LEN, "Next"); + // printf("| %-*s ", 5, "Next#"); + printf("| %-*s ", 5, "Depth"); + printf("| Detail "); + printf("|\n"); + + printf("|%.*s", LOG_EVENT_LEN + 2, DASHES); + printf("|%.*s", LOG_BUFFER_LEN + 2, DASHES); + printf("|%.*s", LOG_SMALL_BUFFER_LEN + 2, DASHES); + // printf("|%.*s", 5+2, DASHES); + printf("|%.*s", 5 + 2, DASHES); + printf("|--------"); + printf("|\n"); + fflush(stdout); + } + } +} + +template +inline void log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, log_level level, Args&&... args) noexcept { + log_line(iter, iter.position()+delta, depth_t(iter.depth()+depth_delta), title_prefix, title, detail, level, std::forward(args)...); +} + +template +inline void log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, log_level level, Args&&... args) noexcept { + if (LOG_ENABLED) { + if (simdjson_unlikely(should_log(level))) { + const int indent = depth * 2; + const auto buf = iter.token.buf; + auto msg = string_format(title, std::forward(args)...); + printf("| %*s%s%-*s ", indent, "", title_prefix, + LOG_EVENT_LEN - indent - int(strlen(title_prefix)), msg.c_str()); + { + // Print the current structural. + printf("| "); + // Before we begin, the index might point right before the document. + // This could be unsafe, see https://github.com/simdjson/simdjson/discussions/1938 + if (index < iter._root) { + printf("%*s", LOG_BUFFER_LEN, ""); + } else { + auto current_structural = &buf[*index]; + for (int i = 0; i < LOG_BUFFER_LEN; i++) { + printf("%c", printable_char(current_structural[i])); + } + } + printf(" "); + } + { + // Print the next structural. + printf("| "); + auto next_structural = &buf[*(index + 1)]; + for (int i = 0; i < LOG_SMALL_BUFFER_LEN; i++) { + printf("%c", printable_char(next_structural[i])); + } + printf(" "); + } + // printf("| %5u ", *(index+1)); + printf("| %5i ", depth); + printf("| %6.*s ", int(detail.size()), detail.data()); + printf("|\n"); + fflush(stdout); + } + } +} + +} // namespace logger +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H +/* end file simdjson/generic/ondemand/logger-inl.h for haswell */ +/* including simdjson/generic/ondemand/object-inl.h for haswell: #include "simdjson/generic/ondemand/object-inl.h" */ +/* begin file simdjson/generic/ondemand/object-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +simdjson_inline simdjson_result object::find_field_unordered(const std::string_view key) & noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::find_field_unordered(const std::string_view key) && noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::operator[](const std::string_view key) & noexcept { + return find_field_unordered(key); +} +simdjson_inline simdjson_result object::operator[](const std::string_view key) && noexcept { + return std::forward(*this).find_field_unordered(key); +} +simdjson_inline simdjson_result object::find_field(const std::string_view key) & noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::find_field(const std::string_view key) && noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} + +simdjson_inline simdjson_result object::start(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.start_object().error() ); + return object(iter); +} +simdjson_inline simdjson_result object::start_root(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.start_root_object().error() ); + return object(iter); +} +simdjson_inline error_code object::consume() noexcept { + if(iter.is_at_key()) { + /** + * whenever you are pointing at a key, calling skip_child() is + * unsafe because you will hit a string and you will assume that + * it is string value, and this mistake will lead you to make bad + * depth computation. + */ + /** + * We want to 'consume' the key. We could really + * just do _json_iter->return_current_and_advance(); at this + * point, but, for clarity, we will use the high-level API to + * eat the key. We assume that the compiler optimizes away + * most of the work. + */ + simdjson_unused raw_json_string actual_key; + auto error = iter.field_key().get(actual_key); + if (error) { iter.abandon(); return error; }; + // Let us move to the value while we are at it. + if ((error = iter.field_value())) { iter.abandon(); return error; } + } + auto error_skip = iter.json_iter().skip_child(iter.depth()-1); + if(error_skip) { iter.abandon(); } + return error_skip; +} + +simdjson_inline simdjson_result object::raw_json() noexcept { + const uint8_t * starting_point{iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + const uint8_t * final_point{iter._json_iter->peek()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +simdjson_inline simdjson_result object::started(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.started_object().error() ); + return object(iter); +} + +simdjson_inline object object::resume(const value_iterator &iter) noexcept { + return iter; +} + +simdjson_inline object::object(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} + +simdjson_inline simdjson_result object::begin() noexcept { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + return object_iterator(iter); +} +simdjson_inline simdjson_result object::end() noexcept { + return object_iterator(iter); +} + +inline simdjson_result object::at_pointer(std::string_view json_pointer) noexcept { + if (json_pointer[0] != '/') { return INVALID_JSON_POINTER; } + json_pointer = json_pointer.substr(1); + size_t slash = json_pointer.find('/'); + std::string_view key = json_pointer.substr(0, slash); + // Grab the child with the given key + simdjson_result child; + + // If there is an escape character in the key, unescape it and then get the child. + size_t escape = key.find('~'); + if (escape != std::string_view::npos) { + // Unescape the key + std::string unescaped(key); + do { + switch (unescaped[escape+1]) { + case '0': + unescaped.replace(escape, 2, "~"); + break; + case '1': + unescaped.replace(escape, 2, "/"); + break; + default: + return INVALID_JSON_POINTER; // "Unexpected ~ escape character in JSON pointer"); + } + escape = unescaped.find('~', escape+1); + } while (escape != std::string::npos); + child = find_field(unescaped); // Take note find_field does not unescape keys when matching + } else { + child = find_field(key); + } + if(child.error()) { + return child; // we do not continue if there was an error + } + // If there is a /, we have to recurse and look up more of the path + if (slash != std::string_view::npos) { + child = child.at_pointer(json_pointer.substr(slash)); + } + return child; +} + +simdjson_inline simdjson_result object::count_fields() & noexcept { + size_t count{0}; + // Important: we do not consume any of the values. + for(simdjson_unused auto v : *this) { count++; } + // The above loop will always succeed, but we want to report errors. + if(iter.error()) { return iter.error(); } + // We need to move back at the start because we expect users to iterate through + // the object after counting the number of elements. + iter.reset_object(); + return count; +} + +simdjson_inline simdjson_result object::is_empty() & noexcept { + bool is_not_empty; + auto error = iter.reset_object().get(is_not_empty); + if(error) { return error; } + return !is_not_empty; +} + +simdjson_inline simdjson_result object::reset() & noexcept { + return iter.reset_object(); +} + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(haswell::ondemand::object &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +simdjson_inline simdjson_result simdjson_result::begin() noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() noexcept { + if (error()) { return error(); } + return first.end(); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first).find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first)[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first).find_field(key); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + +inline simdjson_result simdjson_result::reset() noexcept { + if (error()) { return error(); } + return first.reset(); +} + +inline simdjson_result simdjson_result::is_empty() noexcept { + if (error()) { return error(); } + return first.is_empty(); +} + +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H +/* end file simdjson/generic/ondemand/object-inl.h for haswell */ +/* including simdjson/generic/ondemand/object_iterator-inl.h for haswell: #include "simdjson/generic/ondemand/object_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/object_iterator-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +// +// object_iterator +// + +simdjson_inline object_iterator::object_iterator(const value_iterator &_iter) noexcept + : iter{_iter} +{} + +simdjson_inline simdjson_result object_iterator::operator*() noexcept { + error_code error = iter.error(); + if (error) { iter.abandon(); return error; } + auto result = field::start(iter); + // TODO this is a safety rail ... users should exit loops as soon as they receive an error. + // Nonetheless, let's see if performance is OK with this if statement--the compiler may give it to us for free. + if (result.error()) { iter.abandon(); } + return result; +} +simdjson_inline bool object_iterator::operator==(const object_iterator &other) const noexcept { + return !(*this != other); +} +simdjson_inline bool object_iterator::operator!=(const object_iterator &) const noexcept { + return iter.is_open(); +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline object_iterator &object_iterator::operator++() noexcept { + // TODO this is a safety rail ... users should exit loops as soon as they receive an error. + // Nonetheless, let's see if performance is OK with this if statement--the compiler may give it to us for free. + if (!iter.is_open()) { return *this; } // Iterator will be released if there is an error + + simdjson_unused error_code error; + if ((error = iter.skip_child() )) { return *this; } + + simdjson_unused bool has_value; + if ((error = iter.has_next_field().get(has_value) )) { return *this; }; + return *this; +} +SIMDJSON_POP_DISABLE_WARNINGS + +// +// ### Live States +// +// While iterating or looking up values, depth >= iter.depth. at_start may vary. Error is +// always SUCCESS: +// +// - Start: This is the state when the object is first found and the iterator is just past the {. +// In this state, at_start == true. +// - Next: After we hand a scalar value to the user, or an array/object which they then fully +// iterate over, the iterator is at the , or } before the next value. In this state, +// depth == iter.depth, at_start == false, and error == SUCCESS. +// - Unfinished Business: When we hand an array/object to the user which they do not fully +// iterate over, we need to finish that iteration by skipping child values until we reach the +// Next state. In this state, depth > iter.depth, at_start == false, and error == SUCCESS. +// +// ## Error States +// +// In error states, we will yield exactly one more value before stopping. iter.depth == depth +// and at_start is always false. We decrement after yielding the error, moving to the Finished +// state. +// +// - Chained Error: When the object iterator is part of an error chain--for example, in +// `for (auto tweet : doc["tweets"])`, where the tweet field may be missing or not be an +// object--we yield that error in the loop, exactly once. In this state, error != SUCCESS and +// iter.depth == depth, and at_start == false. We decrement depth when we yield the error. +// - Missing Comma Error: When the iterator ++ method discovers there is no comma between fields, +// we flag that as an error and treat it exactly the same as a Chained Error. In this state, +// error == TAPE_ERROR, iter.depth == depth, and at_start == false. +// +// Errors that occur while reading a field to give to the user (such as when the key is not a +// string or the field is missing a colon) are yielded immediately. Depth is then decremented, +// moving to the Finished state without transitioning through an Error state at all. +// +// ## Terminal State +// +// The terminal state has iter.depth < depth. at_start is always false. +// +// - Finished: When we have reached a }, we are finished. We signal this by decrementing depth. +// In this state, iter.depth < depth, at_start == false, and error == SUCCESS. +// + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + haswell::ondemand::object_iterator &&value +) noexcept + : implementation_simdjson_result_base(std::forward(value)) +{ + first.iter.assert_is_valid(); +} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base({}, error) +{ +} + +simdjson_inline simdjson_result simdjson_result::operator*() noexcept { + if (error()) { return error(); } + return *first; +} +// If we're iterating and there is an error, return the error once. +simdjson_inline bool simdjson_result::operator==(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return !error(); } + return first == other.first; +} +// If we're iterating and there is an error, return the error once. +simdjson_inline bool simdjson_result::operator!=(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return error(); } + return first != other.first; +} +// Checks for ']' and ',' +simdjson_inline simdjson_result &simdjson_result::operator++() noexcept { + // Clear the error if there is one, so we don't yield it twice + if (error()) { second = SUCCESS; return *this; } + ++first; + return *this; +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/object_iterator-inl.h for haswell */ +/* including simdjson/generic/ondemand/parser-inl.h for haswell: #include "simdjson/generic/ondemand/parser-inl.h" */ +/* begin file simdjson/generic/ondemand/parser-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/padded_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/padded_string_view.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/dom/base.h" // for MINIMAL_DOCUMENT_CAPACITY */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document_stream.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +simdjson_inline parser::parser(size_t max_capacity) noexcept + : _max_capacity{max_capacity} { +} + +simdjson_warn_unused simdjson_inline error_code parser::allocate(size_t new_capacity, size_t new_max_depth) noexcept { + if (new_capacity > max_capacity()) { return CAPACITY; } + if (string_buf && new_capacity == capacity() && new_max_depth == max_depth()) { return SUCCESS; } + + // string_capacity copied from document::allocate + _capacity = 0; + size_t string_capacity = SIMDJSON_ROUNDUP_N(5 * new_capacity / 3 + SIMDJSON_PADDING, 64); + string_buf.reset(new (std::nothrow) uint8_t[string_capacity]); +#if SIMDJSON_DEVELOPMENT_CHECKS + start_positions.reset(new (std::nothrow) token_position[new_max_depth]); +#endif + if (implementation) { + SIMDJSON_TRY( implementation->set_capacity(new_capacity) ); + SIMDJSON_TRY( implementation->set_max_depth(new_max_depth) ); + } else { + SIMDJSON_TRY( simdjson::get_active_implementation()->create_dom_parser_implementation(new_capacity, new_max_depth, implementation) ); + } + _capacity = new_capacity; + _max_depth = new_max_depth; + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(padded_string_view json) & noexcept { + if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; } + + json.remove_utf8_bom(); + + // Allocate if needed + if (capacity() < json.length() || !string_buf) { + SIMDJSON_TRY( allocate(json.length(), max_depth()) ); + } + + // Run stage 1. + SIMDJSON_TRY( implementation->stage1(reinterpret_cast(json.data()), json.length(), stage1_mode::regular) ); + return document::start({ reinterpret_cast(json.data()), this }); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const char *json, size_t len, size_t allocated) & noexcept { + return iterate(padded_string_view(json, len, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const uint8_t *json, size_t len, size_t allocated) & noexcept { + return iterate(padded_string_view(json, len, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(std::string_view json, size_t allocated) & noexcept { + return iterate(padded_string_view(json, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(std::string &json) & noexcept { + if(json.capacity() - json.size() < SIMDJSON_PADDING) { + json.reserve(json.size() + SIMDJSON_PADDING); + } + return iterate(padded_string_view(json)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const std::string &json) & noexcept { + return iterate(padded_string_view(json)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const simdjson_result &result) & noexcept { + // We don't presently have a way to temporarily get a const T& from a simdjson_result without throwing an exception + SIMDJSON_TRY( result.error() ); + padded_string_view json = result.value_unsafe(); + return iterate(json); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const simdjson_result &result) & noexcept { + // We don't presently have a way to temporarily get a const T& from a simdjson_result without throwing an exception + SIMDJSON_TRY( result.error() ); + const padded_string &json = result.value_unsafe(); + return iterate(json); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate_raw(padded_string_view json) & noexcept { + if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; } + + json.remove_utf8_bom(); + + // Allocate if needed + if (capacity() < json.length()) { + SIMDJSON_TRY( allocate(json.length(), max_depth()) ); + } + + // Run stage 1. + SIMDJSON_TRY( implementation->stage1(reinterpret_cast(json.data()), json.length(), stage1_mode::regular) ); + return json_iterator(reinterpret_cast(json.data()), this); +} + +inline simdjson_result parser::iterate_many(const uint8_t *buf, size_t len, size_t batch_size, bool allow_comma_separated) noexcept { + if(batch_size < MINIMAL_BATCH_SIZE) { batch_size = MINIMAL_BATCH_SIZE; } + if((len >= 3) && (std::memcmp(buf, "\xEF\xBB\xBF", 3) == 0)) { + buf += 3; + len -= 3; + } + if(allow_comma_separated && batch_size < len) { batch_size = len; } + return document_stream(*this, buf, len, batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const char *buf, size_t len, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(reinterpret_cast(buf), len, batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const std::string &s, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(s.data(), s.length(), batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const padded_string &s, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(s.data(), s.length(), batch_size, allow_comma_separated); +} + +simdjson_inline size_t parser::capacity() const noexcept { + return _capacity; +} +simdjson_inline size_t parser::max_capacity() const noexcept { + return _max_capacity; +} +simdjson_inline size_t parser::max_depth() const noexcept { + return _max_depth; +} + +simdjson_inline void parser::set_max_capacity(size_t max_capacity) noexcept { + if(max_capacity < dom::MINIMAL_DOCUMENT_CAPACITY) { + _max_capacity = max_capacity; + } else { + _max_capacity = dom::MINIMAL_DOCUMENT_CAPACITY; + } +} + +simdjson_inline simdjson_warn_unused simdjson_result parser::unescape(raw_json_string in, uint8_t *&dst, bool allow_replacement) const noexcept { + uint8_t *end = implementation->parse_string(in.buf, dst, allow_replacement); + if (!end) { return STRING_ERROR; } + std::string_view result(reinterpret_cast(dst), end-dst); + dst = end; + return result; +} + +simdjson_inline simdjson_warn_unused simdjson_result parser::unescape_wobbly(raw_json_string in, uint8_t *&dst) const noexcept { + uint8_t *end = implementation->parse_wobbly_string(in.buf, dst); + if (!end) { return STRING_ERROR; } + std::string_view result(reinterpret_cast(dst), end-dst); + dst = end; + return result; +} + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(haswell::ondemand::parser &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H +/* end file simdjson/generic/ondemand/parser-inl.h for haswell */ +/* including simdjson/generic/ondemand/raw_json_string-inl.h for haswell: #include "simdjson/generic/ondemand/raw_json_string-inl.h" */ +/* begin file simdjson/generic/ondemand/raw_json_string-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +namespace haswell { +namespace ondemand { + +simdjson_inline raw_json_string::raw_json_string(const uint8_t * _buf) noexcept : buf{_buf} {} + +simdjson_inline const char * raw_json_string::raw() const noexcept { return reinterpret_cast(buf); } + + +simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(std::string_view target) noexcept { + size_t pos{0}; + // if the content has no escape character, just scan through it quickly! + for(;pos < target.size() && target[pos] != '\\';pos++) {} + // slow path may begin. + bool escaping{false}; + for(;pos < target.size();pos++) { + if((target[pos] == '"') && !escaping) { + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + return true; +} + +simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(const char* target) noexcept { + size_t pos{0}; + // if the content has no escape character, just scan through it quickly! + for(;target[pos] && target[pos] != '\\';pos++) {} + // slow path may begin. + bool escaping{false}; + for(;target[pos];pos++) { + if((target[pos] == '"') && !escaping) { + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + return true; +} + + +simdjson_inline bool raw_json_string::unsafe_is_equal(size_t length, std::string_view target) const noexcept { + // If we are going to call memcmp, then we must know something about the length of the raw_json_string. + return (length >= target.size()) && (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size()); +} + +simdjson_inline bool raw_json_string::unsafe_is_equal(std::string_view target) const noexcept { + // Assumptions: does not contain unescaped quote characters, and + // the raw content is quote terminated within a valid JSON string. + if(target.size() <= SIMDJSON_PADDING) { + return (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size()); + } + const char * r{raw()}; + size_t pos{0}; + for(;pos < target.size();pos++) { + if(r[pos] != target[pos]) { return false; } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_inline bool raw_json_string::is_equal(std::string_view target) const noexcept { + const char * r{raw()}; + size_t pos{0}; + bool escaping{false}; + for(;pos < target.size();pos++) { + if(r[pos] != target[pos]) { return false; } + // if target is a compile-time constant and it is free from + // quotes, then the next part could get optimized away through + // inlining. + if((target[pos] == '"') && !escaping) { + // We have reached the end of the raw_json_string but + // the target is not done. + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + if(r[pos] != '"') { return false; } + return true; +} + + +simdjson_inline bool raw_json_string::unsafe_is_equal(const char * target) const noexcept { + // Assumptions: 'target' does not contain unescaped quote characters, is null terminated and + // the raw content is quote terminated within a valid JSON string. + const char * r{raw()}; + size_t pos{0}; + for(;target[pos];pos++) { + if(r[pos] != target[pos]) { return false; } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_inline bool raw_json_string::is_equal(const char* target) const noexcept { + // Assumptions: does not contain unescaped quote characters, and + // the raw content is quote terminated within a valid JSON string. + const char * r{raw()}; + size_t pos{0}; + bool escaping{false}; + for(;target[pos];pos++) { + if(r[pos] != target[pos]) { return false; } + // if target is a compile-time constant and it is free from + // quotes, then the next part could get optimized away through + // inlining. + if((target[pos] == '"') && !escaping) { + // We have reached the end of the raw_json_string but + // the target is not done. + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept { + return a.unsafe_is_equal(c); +} + +simdjson_unused simdjson_inline bool operator==(std::string_view c, const raw_json_string &a) noexcept { + return a == c; +} + +simdjson_unused simdjson_inline bool operator!=(const raw_json_string &a, std::string_view c) noexcept { + return !(a == c); +} + +simdjson_unused simdjson_inline bool operator!=(std::string_view c, const raw_json_string &a) noexcept { + return !(a == c); +} + + +simdjson_inline simdjson_warn_unused simdjson_result raw_json_string::unescape(json_iterator &iter, bool allow_replacement) const noexcept { + return iter.unescape(*this, allow_replacement); +} + +simdjson_inline simdjson_warn_unused simdjson_result raw_json_string::unescape_wobbly(json_iterator &iter) const noexcept { + return iter.unescape_wobbly(*this); +} + +simdjson_unused simdjson_inline std::ostream &operator<<(std::ostream &out, const raw_json_string &str) noexcept { + bool in_escape = false; + const char *s = str.raw(); + while (true) { + switch (*s) { + case '\\': in_escape = !in_escape; break; + case '"': if (in_escape) { in_escape = false; } else { return out; } break; + default: if (in_escape) { in_escape = false; } + } + out << *s; + s++; + } +} + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(haswell::ondemand::raw_json_string &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +simdjson_inline simdjson_result simdjson_result::raw() const noexcept { + if (error()) { return error(); } + return first.raw(); +} +simdjson_inline simdjson_warn_unused simdjson_result simdjson_result::unescape(haswell::ondemand::json_iterator &iter, bool allow_replacement) const noexcept { + if (error()) { return error(); } + return first.unescape(iter, allow_replacement); +} +simdjson_inline simdjson_warn_unused simdjson_result simdjson_result::unescape_wobbly(haswell::ondemand::json_iterator &iter) const noexcept { + if (error()) { return error(); } + return first.unescape_wobbly(iter); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H +/* end file simdjson/generic/ondemand/raw_json_string-inl.h for haswell */ +/* including simdjson/generic/ondemand/serialization-inl.h for haswell: #include "simdjson/generic/ondemand/serialization-inl.h" */ +/* begin file simdjson/generic/ondemand/serialization-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/serialization.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +inline std::string_view trim(const std::string_view str) noexcept { + // We can almost surely do better by rolling our own find_first_not_of function. + size_t first = str.find_first_not_of(" \t\n\r"); + // If we have the empty string (just white space), then no trimming is possible, and + // we return the empty string_view. + if (std::string_view::npos == first) { return std::string_view(); } + size_t last = str.find_last_not_of(" \t\n\r"); + return str.substr(first, (last - first + 1)); +} + + +inline simdjson_result to_json_string(haswell::ondemand::document& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(haswell::ondemand::document_reference& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(haswell::ondemand::value& x) noexcept { + /** + * If we somehow receive a value that has already been consumed, + * then the following code could be in trouble. E.g., we create + * an array as needed, but if an array was already created, then + * it could be bad. + */ + using namespace haswell::ondemand; + haswell::ondemand::json_type t; + auto error = x.type().get(t); + if(error != SUCCESS) { return error; } + switch (t) + { + case json_type::array: + { + haswell::ondemand::array array; + error = x.get_array().get(array); + if(error) { return error; } + return to_json_string(array); + } + case json_type::object: + { + haswell::ondemand::object object; + error = x.get_object().get(object); + if(error) { return error; } + return to_json_string(object); + } + default: + return trim(x.raw_json_token()); + } +} + +inline simdjson_result to_json_string(haswell::ondemand::object& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(haswell::ondemand::array& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} +} // namespace simdjson + +namespace simdjson { namespace haswell { namespace ondemand { + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::haswell::ondemand::value x) { + std::string_view v; + auto error = simdjson::to_json_string(x).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::haswell::ondemand::value x) { + std::string_view v; + auto error = simdjson::to_json_string(x).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::haswell::ondemand::array value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::haswell::ondemand::array value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::haswell::ondemand::document& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::haswell::ondemand::document_reference& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::haswell::ondemand::document& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::haswell::ondemand::object value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::haswell::ondemand::object value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif +}}} // namespace simdjson::haswell::ondemand + +#endif // SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H +/* end file simdjson/generic/ondemand/serialization-inl.h for haswell */ +/* including simdjson/generic/ondemand/token_iterator-inl.h for haswell: #include "simdjson/generic/ondemand/token_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/token_iterator-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +simdjson_inline token_iterator::token_iterator( + const uint8_t *_buf, + token_position position +) noexcept : buf{_buf}, _position{position} +{ +} + +simdjson_inline uint32_t token_iterator::current_offset() const noexcept { + return *(_position); +} + + +simdjson_inline const uint8_t *token_iterator::return_current_and_advance() noexcept { + return &buf[*(_position++)]; +} + +simdjson_inline const uint8_t *token_iterator::peek(token_position position) const noexcept { + return &buf[*position]; +} +simdjson_inline uint32_t token_iterator::peek_index(token_position position) const noexcept { + return *position; +} +simdjson_inline uint32_t token_iterator::peek_length(token_position position) const noexcept { + return *(position+1) - *position; +} + +simdjson_inline const uint8_t *token_iterator::peek(int32_t delta) const noexcept { + return &buf[*(_position+delta)]; +} +simdjson_inline uint32_t token_iterator::peek_index(int32_t delta) const noexcept { + return *(_position+delta); +} +simdjson_inline uint32_t token_iterator::peek_length(int32_t delta) const noexcept { + return *(_position+delta+1) - *(_position+delta); +} + +simdjson_inline token_position token_iterator::position() const noexcept { + return _position; +} +simdjson_inline void token_iterator::set_position(token_position target_position) noexcept { + _position = target_position; +} + +simdjson_inline bool token_iterator::operator==(const token_iterator &other) const noexcept { + return _position == other._position; +} +simdjson_inline bool token_iterator::operator!=(const token_iterator &other) const noexcept { + return _position != other._position; +} +simdjson_inline bool token_iterator::operator>(const token_iterator &other) const noexcept { + return _position > other._position; +} +simdjson_inline bool token_iterator::operator>=(const token_iterator &other) const noexcept { + return _position >= other._position; +} +simdjson_inline bool token_iterator::operator<(const token_iterator &other) const noexcept { + return _position < other._position; +} +simdjson_inline bool token_iterator::operator<=(const token_iterator &other) const noexcept { + return _position <= other._position; +} + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(haswell::ondemand::token_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/token_iterator-inl.h for haswell */ +/* including simdjson/generic/ondemand/value-inl.h for haswell: #include "simdjson/generic/ondemand/value-inl.h" */ +/* begin file simdjson/generic/ondemand/value-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +simdjson_inline value::value(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} +simdjson_inline value value::start(const value_iterator &iter) noexcept { + return iter; +} +simdjson_inline value value::resume(const value_iterator &iter) noexcept { + return iter; +} + +simdjson_inline simdjson_result value::get_array() noexcept { + return array::start(iter); +} +simdjson_inline simdjson_result value::get_object() noexcept { + return object::start(iter); +} +simdjson_inline simdjson_result value::start_or_resume_object() noexcept { + if (iter.at_start()) { + return get_object(); + } else { + return object::resume(iter); + } +} + +simdjson_inline simdjson_result value::get_raw_json_string() noexcept { + return iter.get_raw_json_string(); +} +simdjson_inline simdjson_result value::get_string(bool allow_replacement) noexcept { + return iter.get_string(allow_replacement); +} +template +simdjson_inline error_code value::get_string(string_type& receiver, bool allow_replacement) noexcept { + return iter.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result value::get_wobbly_string() noexcept { + return iter.get_wobbly_string(); +} +simdjson_inline simdjson_result value::get_double() noexcept { + return iter.get_double(); +} +simdjson_inline simdjson_result value::get_double_in_string() noexcept { + return iter.get_double_in_string(); +} +simdjson_inline simdjson_result value::get_uint64() noexcept { + return iter.get_uint64(); +} +simdjson_inline simdjson_result value::get_uint64_in_string() noexcept { + return iter.get_uint64_in_string(); +} +simdjson_inline simdjson_result value::get_int64() noexcept { + return iter.get_int64(); +} +simdjson_inline simdjson_result value::get_int64_in_string() noexcept { + return iter.get_int64_in_string(); +} +simdjson_inline simdjson_result value::get_bool() noexcept { + return iter.get_bool(); +} +simdjson_inline simdjson_result value::is_null() noexcept { + return iter.is_null(); +} +template<> simdjson_inline simdjson_result value::get() noexcept { return get_array(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_object(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_number(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_double(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_uint64(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_int64(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_bool(); } + +template simdjson_inline error_code value::get(T &out) noexcept { + return get().get(out); +} + +#if SIMDJSON_EXCEPTIONS +simdjson_inline value::operator array() noexcept(false) { + return get_array(); +} +simdjson_inline value::operator object() noexcept(false) { + return get_object(); +} +simdjson_inline value::operator uint64_t() noexcept(false) { + return get_uint64(); +} +simdjson_inline value::operator int64_t() noexcept(false) { + return get_int64(); +} +simdjson_inline value::operator double() noexcept(false) { + return get_double(); +} +simdjson_inline value::operator std::string_view() noexcept(false) { + return get_string(false); +} +simdjson_inline value::operator raw_json_string() noexcept(false) { + return get_raw_json_string(); +} +simdjson_inline value::operator bool() noexcept(false) { + return get_bool(); +} +#endif + +simdjson_inline simdjson_result value::begin() & noexcept { + return get_array().begin(); +} +simdjson_inline simdjson_result value::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result value::count_elements() & noexcept { + simdjson_result answer; + auto a = get_array(); + answer = a.count_elements(); + // count_elements leaves you pointing inside the array, at the first element. + // We need to move back so that the user can create a new array (which requires that + // we point at '['). + iter.move_at_start(); + return answer; +} +simdjson_inline simdjson_result value::count_fields() & noexcept { + simdjson_result answer; + auto a = get_object(); + answer = a.count_fields(); + iter.move_at_start(); + return answer; +} +simdjson_inline simdjson_result value::at(size_t index) noexcept { + auto a = get_array(); + return a.at(index); +} + +simdjson_inline simdjson_result value::find_field(std::string_view key) noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result value::find_field(const char *key) noexcept { + return start_or_resume_object().find_field(key); +} + +simdjson_inline simdjson_result value::find_field_unordered(std::string_view key) noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result value::find_field_unordered(const char *key) noexcept { + return start_or_resume_object().find_field_unordered(key); +} + +simdjson_inline simdjson_result value::operator[](std::string_view key) noexcept { + return start_or_resume_object()[key]; +} +simdjson_inline simdjson_result value::operator[](const char *key) noexcept { + return start_or_resume_object()[key]; +} + +simdjson_inline simdjson_result value::type() noexcept { + return iter.type(); +} + +simdjson_inline simdjson_result value::is_scalar() noexcept { + json_type this_type; + auto error = type().get(this_type); + if(error) { return error; } + return ! ((this_type == json_type::array) || (this_type == json_type::object)); +} + +simdjson_inline bool value::is_negative() noexcept { + return iter.is_negative(); +} + +simdjson_inline simdjson_result value::is_integer() noexcept { + return iter.is_integer(); +} +simdjson_warn_unused simdjson_inline simdjson_result value::get_number_type() noexcept { + return iter.get_number_type(); +} +simdjson_warn_unused simdjson_inline simdjson_result value::get_number() noexcept { + return iter.get_number(); +} + +simdjson_inline std::string_view value::raw_json_token() noexcept { + return std::string_view(reinterpret_cast(iter.peek_start()), iter.peek_start_length()); +} + +simdjson_inline simdjson_result value::raw_json() noexcept { + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: { + ondemand::array array; + SIMDJSON_TRY(get_array().get(array)); + return array.raw_json(); + } + case json_type::object: { + ondemand::object object; + SIMDJSON_TRY(get_object().get(object)); + return object.raw_json(); + } + default: + return raw_json_token(); + } +} + +simdjson_inline simdjson_result value::current_location() noexcept { + return iter.json_iter().current_location(); +} + +simdjson_inline int32_t value::current_depth() const noexcept{ + return iter.json_iter().depth(); +} + +simdjson_inline simdjson_result value::at_pointer(std::string_view json_pointer) noexcept { + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: + return (*this).get_array().at_pointer(json_pointer); + case json_type::object: + return (*this).get_object().at_pointer(json_pointer); + default: + return INVALID_JSON_POINTER; + } +} + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + haswell::ondemand::value &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + if (error()) { return error(); } + return {}; +} + +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) noexcept { + if (error()) { return error(); } + return first.find_field(key); +} + +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} + +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) noexcept { + if (error()) { return error(); } + return first[key]; +} + +simdjson_inline simdjson_result simdjson_result::get_array() noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} + +template simdjson_inline simdjson_result simdjson_result::get() noexcept { + if (error()) { return error(); } + return first.get(); +} +template simdjson_inline error_code simdjson_result::get(T &out) noexcept { + if (error()) { return error(); } + return first.get(out); +} + +template<> simdjson_inline simdjson_result simdjson_result::get() noexcept { + if (error()) { return error(); } + return std::move(first); +} +template<> simdjson_inline error_code simdjson_result::get(haswell::ondemand::value &out) noexcept { + if (error()) { return error(); } + out = first; + return SUCCESS; +} + +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} +simdjson_inline simdjson_result simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator haswell::ondemand::array() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator haswell::ondemand::object() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator haswell::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline simdjson_result simdjson_result::current_depth() const noexcept { + if (error()) { return error(); } + return first.current_depth(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H +/* end file simdjson/generic/ondemand/value-inl.h for haswell */ +/* including simdjson/generic/ondemand/value_iterator-inl.h for haswell: #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/value_iterator-inl.h for haswell */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/atomparsing.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/numberparsing.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace haswell { +namespace ondemand { + +simdjson_inline value_iterator::value_iterator( + json_iterator *json_iter, + depth_t depth, + token_position start_position +) noexcept : _json_iter{json_iter}, _depth{depth}, _start_position{start_position} +{ +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_object() noexcept { + SIMDJSON_TRY( start_container('{', "Not an object", "object") ); + return started_object(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_root_object() noexcept { + SIMDJSON_TRY( start_container('{', "Not an object", "object") ); + return started_root_object(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_object() noexcept { + assert_at_container_start(); +#if SIMDJSON_DEVELOPMENT_CHECKS + _json_iter->set_start_position(_depth, start_position()); +#endif + if (*_json_iter->peek() == '}') { + logger::log_value(*_json_iter, "empty object"); + _json_iter->return_current_and_advance(); + end_container(); + return false; + } + return true; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::check_root_object() noexcept { + // When in streaming mode, we cannot expect peek_last() to be the last structural element of the + // current document. It only works in the normal mode where we have indexed a single document. + // Note that adding a check for 'streaming' is not expensive since we only have at most + // one root element. + if ( ! _json_iter->streaming() ) { + // The following lines do not fully protect against garbage content within the + // object: e.g., `{"a":2} foo }`. Users concerned with garbage content should + // call `at_end()` on the document instance at the end of the processing to + // ensure that the processing has finished at the end. + // + if (*_json_iter->peek_last() != '}') { + _json_iter->abandon(); + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing } at end"); + } + // If the last character is } *and* the first gibberish character is also '}' + // then on-demand could accidentally go over. So we need additional checks. + // https://github.com/simdjson/simdjson/issues/1834 + // Checking that the document is balanced requires a full scan which is potentially + // expensive, but it only happens in edge cases where the first padding character is + // a closing bracket. + if ((*_json_iter->peek(_json_iter->end_position()) == '}') && (!_json_iter->balanced())) { + _json_iter->abandon(); + // The exact error would require more work. It will typically be an unclosed object. + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "the document is unbalanced"); + } + } + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_root_object() noexcept { + auto error = check_root_object(); + if(error) { return error; } + return started_object(); +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::end_container() noexcept { +#if SIMDJSON_CHECK_EOF + if (depth() > 1 && at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing parent ] or }"); } + // if (depth() <= 1 && !at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing [ or { at start"); } +#endif // SIMDJSON_CHECK_EOF + _json_iter->ascend_to(depth()-1); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::has_next_field() noexcept { + assert_at_next(); + + // It's illegal to call this unless there are more tokens: anything that ends in } or ] is + // obligated to verify there are more tokens if they are not the top level. + switch (*_json_iter->return_current_and_advance()) { + case '}': + logger::log_end_value(*_json_iter, "object"); + SIMDJSON_TRY( end_container() ); + return false; + case ',': + return true; + default: + return report_error(TAPE_ERROR, "Missing comma between object fields"); + } +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::find_field_raw(const std::string_view key) noexcept { + error_code error; + bool has_value; + // + // Initially, the object can be in one of a few different places: + // + // 1. The start of the object, at the first field: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2, index 1) + // ``` + if (at_first_field()) { + has_value = true; + + // + // 2. When a previous search did not yield a value or the object is empty: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // { } + // ^ (depth 0, index 2) + // ``` + // + } else if (!is_open()) { +#if SIMDJSON_DEVELOPMENT_CHECKS + // If we're past the end of the object, we're being iterated out of order. + // Note: this isn't perfect detection. It's possible the user is inside some other object; if so, + // this object iterator will blithely scan that object for fields. + if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; } +#endif + return false; + + // 3. When a previous search found a field or an iterator yielded a value: + // + // ``` + // // When a field was not fully consumed (or not even touched at all) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2) + // // When a field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // When the last field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // ``` + // + } else { + if ((error = skip_child() )) { abandon(); return error; } + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } +#if SIMDJSON_DEVELOPMENT_CHECKS + if (_json_iter->start_position(_depth) != start_position()) { return OUT_OF_ORDER_ITERATION; } +#endif + } + while (has_value) { + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + if ((error = field_key().get(actual_key) )) { abandon(); return error; }; + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + if ((error = field_value() )) { abandon(); return error; } + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + //if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); // Skip the value entirely + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } + } + + // If the loop ended, we're out of fields to look at. + return false; +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::find_field_unordered_raw(const std::string_view key) noexcept { + /** + * When find_field_unordered_raw is called, we can either be pointing at the + * first key, pointing outside (at the closing brace) or if a key was matched + * we can be either pointing right afterthe ':' right before the value (that we need skip), + * or we may have consumed the value and we might be at a comma or at the + * final brace (ready for a call to has_next_field()). + */ + error_code error; + bool has_value; + + // First, we scan from that point to the end. + // If we don't find a match, we may loop back around, and scan from the beginning to that point. + token_position search_start = _json_iter->position(); + + // We want to know whether we need to go back to the beginning. + bool at_first = at_first_field(); + /////////////// + // Initially, the object can be in one of a few different places: + // + // 1. At the first key: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2, index 1) + // ``` + // + if (at_first) { + has_value = true; + + // 2. When a previous search did not yield a value or the object is empty: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // { } + // ^ (depth 0, index 2) + // ``` + // + } else if (!is_open()) { + +#if SIMDJSON_DEVELOPMENT_CHECKS + // If we're past the end of the object, we're being iterated out of order. + // Note: this isn't perfect detection. It's possible the user is inside some other object; if so, + // this object iterator will blithely scan that object for fields. + if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; } +#endif + SIMDJSON_TRY(reset_object().get(has_value)); + at_first = true; + // 3. When a previous search found a field or an iterator yielded a value: + // + // ``` + // // When a field was not fully consumed (or not even touched at all) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2) + // // When a field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // When the last field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // ``` + // + } else { + // If someone queried a key but they not did access the value, then we are left pointing + // at the ':' and we need to move forward through the value... If the value was + // processed then skip_child() does not move the iterator (but may adjust the depth). + if ((error = skip_child() )) { abandon(); return error; } + search_start = _json_iter->position(); + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } +#if SIMDJSON_DEVELOPMENT_CHECKS + if (_json_iter->start_position(_depth) != start_position()) { return OUT_OF_ORDER_ITERATION; } +#endif + } + + // After initial processing, we will be in one of two states: + // + // ``` + // // At the beginning of a field + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // At the end of the object + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // ``` + // + // Next, we find a match starting from the current position. + while (has_value) { + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); // We must be at the start of a field + + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + if ((error = field_key().get(actual_key) )) { abandon(); return error; }; + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + if ((error = field_value() )) { abandon(); return error; } + + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + // if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } + } + // Performance note: it maybe wasteful to rewind to the beginning when there might be + // no other query following. Indeed, it would require reskipping the whole object. + // Instead, you can just stay where you are. If there is a new query, there is always time + // to rewind. + if(at_first) { return false; } + + // If we reach the end without finding a match, search the rest of the fields starting at the + // beginning of the object. + // (We have already run through the object before, so we've already validated its structure. We + // don't check errors in this bit.) + SIMDJSON_TRY(reset_object().get(has_value)); + while (true) { + SIMDJSON_ASSUME(has_value); // we should reach search_start before ever reaching the end of the object + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); // We must be at the start of a field + + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + error = field_key().get(actual_key); SIMDJSON_ASSUME(!error); + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + error = field_value(); SIMDJSON_ASSUME(!error); + + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + // if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); + // If we reached the end of the key-value pair we started from, then we know + // that the key is not there so we return false. We are either right before + // the next comma or the final brace. + if(_json_iter->position() == search_start) { return false; } + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + error = has_next_field().get(has_value); SIMDJSON_ASSUME(!error); + // If we make the mistake of exiting here, then we could be left pointing at a key + // in the middle of an object. That's not an allowable state. + } + // If the loop ended, we're out of fields to look at. The program should + // never reach this point. + return false; +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::field_key() noexcept { + assert_at_next(); + + const uint8_t *key = _json_iter->return_current_and_advance(); + if (*(key++) != '"') { return report_error(TAPE_ERROR, "Object key is not a string"); } + return raw_json_string(key); +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::field_value() noexcept { + assert_at_next(); + + if (*_json_iter->return_current_and_advance() != ':') { return report_error(TAPE_ERROR, "Missing colon in object field"); } + _json_iter->descend_to(depth()+1); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_array() noexcept { + SIMDJSON_TRY( start_container('[', "Not an array", "array") ); + return started_array(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_root_array() noexcept { + SIMDJSON_TRY( start_container('[', "Not an array", "array") ); + return started_root_array(); +} + +inline std::string value_iterator::to_string() const noexcept { + auto answer = std::string("value_iterator [ depth : ") + std::to_string(_depth) + std::string(", "); + if(_json_iter != nullptr) { answer += _json_iter->to_string(); } + answer += std::string(" ]"); + return answer; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_array() noexcept { + assert_at_container_start(); + if (*_json_iter->peek() == ']') { + logger::log_value(*_json_iter, "empty array"); + _json_iter->return_current_and_advance(); + SIMDJSON_TRY( end_container() ); + return false; + } + _json_iter->descend_to(depth()+1); +#if SIMDJSON_DEVELOPMENT_CHECKS + _json_iter->set_start_position(_depth, start_position()); +#endif + return true; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::check_root_array() noexcept { + // When in streaming mode, we cannot expect peek_last() to be the last structural element of the + // current document. It only works in the normal mode where we have indexed a single document. + // Note that adding a check for 'streaming' is not expensive since we only have at most + // one root element. + if ( ! _json_iter->streaming() ) { + // The following lines do not fully protect against garbage content within the + // array: e.g., `[1, 2] foo]`. Users concerned with garbage content should + // also call `at_end()` on the document instance at the end of the processing to + // ensure that the processing has finished at the end. + // + if (*_json_iter->peek_last() != ']') { + _json_iter->abandon(); + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing ] at end"); + } + // If the last character is ] *and* the first gibberish character is also ']' + // then on-demand could accidentally go over. So we need additional checks. + // https://github.com/simdjson/simdjson/issues/1834 + // Checking that the document is balanced requires a full scan which is potentially + // expensive, but it only happens in edge cases where the first padding character is + // a closing bracket. + if ((*_json_iter->peek(_json_iter->end_position()) == ']') && (!_json_iter->balanced())) { + _json_iter->abandon(); + // The exact error would require more work. It will typically be an unclosed array. + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "the document is unbalanced"); + } + } + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_root_array() noexcept { + auto error = check_root_array(); + if (error) { return error; } + return started_array(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::has_next_element() noexcept { + assert_at_next(); + + logger::log_event(*this, "has_next_element"); + switch (*_json_iter->return_current_and_advance()) { + case ']': + logger::log_end_value(*_json_iter, "array"); + SIMDJSON_TRY( end_container() ); + return false; + case ',': + _json_iter->descend_to(depth()+1); + return true; + default: + return report_error(TAPE_ERROR, "Missing comma between array elements"); + } +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::parse_bool(const uint8_t *json) const noexcept { + auto not_true = atomparsing::str4ncmp(json, "true"); + auto not_false = atomparsing::str4ncmp(json, "fals") | (json[4] ^ 'e'); + bool error = (not_true && not_false) || jsoncharutils::is_not_structural_or_whitespace(json[not_true ? 5 : 4]); + if (error) { return incorrect_type_error("Not a boolean"); } + return simdjson_result(!not_true); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::parse_null(const uint8_t *json) const noexcept { + bool is_null_string = !atomparsing::str4ncmp(json, "null") && jsoncharutils::is_structural_or_whitespace(json[4]); + // if we start with 'n', we must be a null + if(!is_null_string && json[0]=='n') { return incorrect_type_error("Not a null but starts with n"); } + return is_null_string; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_string(bool allow_replacement) noexcept { + return get_raw_json_string().unescape(json_iter(), allow_replacement); +} +template +simdjson_warn_unused simdjson_inline error_code value_iterator::get_string(string_type& receiver, bool allow_replacement) noexcept { + std::string_view content; + auto err = get_string(allow_replacement).get(content); + if (err) { return err; } + receiver = content; + return SUCCESS; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_wobbly_string() noexcept { + return get_raw_json_string().unescape_wobbly(json_iter()); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_raw_json_string() noexcept { + auto json = peek_scalar("string"); + if (*json != '"') { return incorrect_type_error("Not a string"); } + advance_scalar("string"); + return raw_json_string(json+1); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_uint64() noexcept { + auto result = numberparsing::parse_unsigned(peek_non_root_scalar("uint64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("uint64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_uint64_in_string() noexcept { + auto result = numberparsing::parse_unsigned_in_string(peek_non_root_scalar("uint64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("uint64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_int64() noexcept { + auto result = numberparsing::parse_integer(peek_non_root_scalar("int64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("int64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_int64_in_string() noexcept { + auto result = numberparsing::parse_integer_in_string(peek_non_root_scalar("int64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("int64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_double() noexcept { + auto result = numberparsing::parse_double(peek_non_root_scalar("double")); + if(result.error() == SUCCESS) { advance_non_root_scalar("double"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_double_in_string() noexcept { + auto result = numberparsing::parse_double_in_string(peek_non_root_scalar("double")); + if(result.error() == SUCCESS) { advance_non_root_scalar("double"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_bool() noexcept { + auto result = parse_bool(peek_non_root_scalar("bool")); + if(result.error() == SUCCESS) { advance_non_root_scalar("bool"); } + return result; +} +simdjson_inline simdjson_result value_iterator::is_null() noexcept { + bool is_null_value; + SIMDJSON_TRY(parse_null(peek_non_root_scalar("null")).get(is_null_value)); + if(is_null_value) { advance_non_root_scalar("null"); } + return is_null_value; +} +simdjson_inline bool value_iterator::is_negative() noexcept { + return numberparsing::is_negative(peek_non_root_scalar("numbersign")); +} +simdjson_inline bool value_iterator::is_root_negative() noexcept { + return numberparsing::is_negative(peek_root_scalar("numbersign")); +} +simdjson_inline simdjson_result value_iterator::is_integer() noexcept { + return numberparsing::is_integer(peek_non_root_scalar("integer")); +} +simdjson_inline simdjson_result value_iterator::get_number_type() noexcept { + return numberparsing::get_number_type(peek_non_root_scalar("integer")); +} +simdjson_inline simdjson_result value_iterator::get_number() noexcept { + number num; + error_code error = numberparsing::parse_number(peek_non_root_scalar("number"), num); + if(error) { return error; } + return num; +} + +simdjson_inline simdjson_result value_iterator::is_root_integer(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("is_root_integer"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + return false; // if there are more than 20 characters, it cannot be represented as an integer. + } + auto answer = numberparsing::is_integer(tmpbuf); + // If the parsing was a success, we must still check that it is + // a single scalar. Note that we parse first because of cases like '[]' where + // getting TRAILING_CONTENT is wrong. + if(check_trailing && (answer.error() == SUCCESS) && (!_json_iter->is_single_token())) { return TRAILING_CONTENT; } + return answer; +} + +simdjson_inline simdjson_result value_iterator::get_root_number_type(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("number"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto answer = numberparsing::get_number_type(tmpbuf); + if (check_trailing && (answer.error() == SUCCESS) && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + return answer; +} +simdjson_inline simdjson_result value_iterator::get_root_number(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("number"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + number num; + error_code error = numberparsing::parse_number(tmpbuf, num); + if(error) { return error; } + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("number"); + return num; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_string(bool check_trailing, bool allow_replacement) noexcept { + return get_root_raw_json_string(check_trailing).unescape(json_iter(), allow_replacement); +} +template +simdjson_warn_unused simdjson_inline error_code value_iterator::get_root_string(string_type& receiver, bool check_trailing, bool allow_replacement) noexcept { + std::string_view content; + auto err = get_root_string(check_trailing, allow_replacement).get(content); + if (err) { return err; } + receiver = content; + return SUCCESS; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_wobbly_string(bool check_trailing) noexcept { + return get_root_raw_json_string(check_trailing).unescape_wobbly(json_iter()); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_raw_json_string(bool check_trailing) noexcept { + auto json = peek_scalar("string"); + if (*json != '"') { return incorrect_type_error("Not a string"); } + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_scalar("string"); + return raw_json_string(json+1); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_uint64(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("uint64"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_unsigned(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("uint64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_uint64_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("uint64"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_unsigned_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("uint64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_int64(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("int64"); + uint8_t tmpbuf[20+1+1]; // -<19 digits> is the longest possible integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + + auto result = numberparsing::parse_integer(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("int64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_int64_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("int64"); + uint8_t tmpbuf[20+1+1]; // -<19 digits> is the longest possible integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + + auto result = numberparsing::parse_integer_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("int64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_double(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("double"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; // +1 for null termination. + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_double(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("double"); + } + return result; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_double_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("double"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; // +1 for null termination. + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_double_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("double"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_bool(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("bool"); + uint8_t tmpbuf[5+1+1]; // +1 for null termination + tmpbuf[5+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 5+1)) { return incorrect_type_error("Not a boolean"); } + auto result = parse_bool(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("bool"); + } + return result; +} +simdjson_inline simdjson_result value_iterator::is_root_null(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("null"); + bool result = (max_len >= 4 && !atomparsing::str4ncmp(json, "null") && + (max_len == 4 || jsoncharutils::is_structural_or_whitespace(json[4]))); + if(result) { // we have something that looks like a null. + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("null"); + } + return result; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::skip_child() noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth >= _depth ); + + return _json_iter->skip_child(depth()); +} + +simdjson_inline value_iterator value_iterator::child() const noexcept { + assert_at_child(); + return { _json_iter, depth()+1, _json_iter->token.position() }; +} + +// GCC 7 warns when the first line of this function is inlined away into oblivion due to the caller +// relating depth and iterator depth, which is a desired effect. It does not happen if is_open is +// marked non-inline. +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline bool value_iterator::is_open() const noexcept { + return _json_iter->depth() >= depth(); +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline bool value_iterator::at_end() const noexcept { + return _json_iter->at_end(); +} + +simdjson_inline bool value_iterator::at_start() const noexcept { + return _json_iter->token.position() == start_position(); +} + +simdjson_inline bool value_iterator::at_first_field() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + return _json_iter->token.position() == start_position() + 1; +} + +simdjson_inline void value_iterator::abandon() noexcept { + _json_iter->abandon(); +} + +simdjson_warn_unused simdjson_inline depth_t value_iterator::depth() const noexcept { + return _depth; +} +simdjson_warn_unused simdjson_inline error_code value_iterator::error() const noexcept { + return _json_iter->error; +} +simdjson_warn_unused simdjson_inline uint8_t *&value_iterator::string_buf_loc() noexcept { + return _json_iter->string_buf_loc(); +} +simdjson_warn_unused simdjson_inline const json_iterator &value_iterator::json_iter() const noexcept { + return *_json_iter; +} +simdjson_warn_unused simdjson_inline json_iterator &value_iterator::json_iter() noexcept { + return *_json_iter; +} + +simdjson_inline const uint8_t *value_iterator::peek_start() const noexcept { + return _json_iter->peek(start_position()); +} +simdjson_inline uint32_t value_iterator::peek_start_length() const noexcept { + return _json_iter->peek_length(start_position()); +} + +simdjson_inline const uint8_t *value_iterator::peek_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + if (!is_at_start()) { return peek_start(); } + + // Get the JSON and advance the cursor, decreasing depth to signify that we have retrieved the value. + assert_at_start(); + return _json_iter->peek(); +} + +simdjson_inline void value_iterator::advance_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + if (!is_at_start()) { return; } + + // Get the JSON and advance the cursor, decreasing depth to signify that we have retrieved the value. + assert_at_start(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} + +simdjson_inline error_code value_iterator::start_container(uint8_t start_char, const char *incorrect_type_message, const char *type) noexcept { + logger::log_start_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + const uint8_t *json; + if (!is_at_start()) { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + json = peek_start(); + if (*json != start_char) { return incorrect_type_error(incorrect_type_message); } + } else { + assert_at_start(); + /** + * We should be prudent. Let us peek. If it is not the right type, we + * return an error. Only once we have determined that we have the right + * type are we allowed to advance! + */ + json = _json_iter->peek(); + if (*json != start_char) { return incorrect_type_error(incorrect_type_message); } + _json_iter->return_current_and_advance(); + } + + + return SUCCESS; +} + + +simdjson_inline const uint8_t *value_iterator::peek_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return peek_start(); } + + assert_at_root(); + return _json_iter->peek(); +} +simdjson_inline const uint8_t *value_iterator::peek_non_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return peek_start(); } + + assert_at_non_root_start(); + return _json_iter->peek(); +} + +simdjson_inline void value_iterator::advance_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return; } + + assert_at_root(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} +simdjson_inline void value_iterator::advance_non_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return; } + + assert_at_non_root_start(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} + +simdjson_inline error_code value_iterator::incorrect_type_error(const char *message) const noexcept { + logger::log_error(*_json_iter, start_position(), depth(), message); + return INCORRECT_TYPE; +} + +simdjson_inline bool value_iterator::is_at_start() const noexcept { + return position() == start_position(); +} + +simdjson_inline bool value_iterator::is_at_key() const noexcept { + // Keys are at the same depth as the object. + // Note here that we could be safer and check that we are within an object, + // but we do not. + return _depth == _json_iter->_depth && *_json_iter->peek() == '"'; +} + +simdjson_inline bool value_iterator::is_at_iterator_start() const noexcept { + // We can legitimately be either at the first value ([1]), or after the array if it's empty ([]). + auto delta = position() - start_position(); + return delta == 1 || delta == 2; +} + +inline void value_iterator::assert_at_start() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position == _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_container_start() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position == _start_position + 1 ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_next() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +simdjson_inline void value_iterator::move_at_start() noexcept { + _json_iter->_depth = _depth; + _json_iter->token.set_position(_start_position); +} + +simdjson_inline void value_iterator::move_at_container_start() noexcept { + _json_iter->_depth = _depth; + _json_iter->token.set_position(_start_position + 1); +} + +simdjson_inline simdjson_result value_iterator::reset_array() noexcept { + if(error()) { return error(); } + move_at_container_start(); + return started_array(); +} + +simdjson_inline simdjson_result value_iterator::reset_object() noexcept { + if(error()) { return error(); } + move_at_container_start(); + return started_object(); +} + +inline void value_iterator::assert_at_child() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth + 1 ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_root() const noexcept { + assert_at_start(); + SIMDJSON_ASSUME( _depth == 1 ); +} + +inline void value_iterator::assert_at_non_root_start() const noexcept { + assert_at_start(); + SIMDJSON_ASSUME( _depth > 1 ); +} + +inline void value_iterator::assert_is_valid() const noexcept { + SIMDJSON_ASSUME( _json_iter != nullptr ); +} + +simdjson_inline bool value_iterator::is_valid() const noexcept { + return _json_iter != nullptr; +} + +simdjson_inline simdjson_result value_iterator::type() const noexcept { + switch (*peek_start()) { + case '{': + return json_type::object; + case '[': + return json_type::array; + case '"': + return json_type::string; + case 'n': + return json_type::null; + case 't': case 'f': + return json_type::boolean; + case '-': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return json_type::number; + default: + return TAPE_ERROR; + } +} + +simdjson_inline token_position value_iterator::start_position() const noexcept { + return _start_position; +} + +simdjson_inline token_position value_iterator::position() const noexcept { + return _json_iter->position(); +} + +simdjson_inline token_position value_iterator::end_position() const noexcept { + return _json_iter->end_position(); +} + +simdjson_inline token_position value_iterator::last_position() const noexcept { + return _json_iter->last_position(); +} + +simdjson_inline error_code value_iterator::report_error(error_code error, const char *message) noexcept { + return _json_iter->report_error(error, message); +} + +} // namespace ondemand +} // namespace haswell +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(haswell::ondemand::value_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/value_iterator-inl.h for haswell */ +/* end file simdjson/generic/ondemand/amalgamated.h for haswell */ +/* including simdjson/haswell/end.h: #include "simdjson/haswell/end.h" */ +/* begin file simdjson/haswell/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/haswell/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_HASWELL +SIMDJSON_UNTARGET_REGION +#endif + +/* undefining SIMDJSON_IMPLEMENTATION from "haswell" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/haswell/end.h */ + +#endif // SIMDJSON_HASWELL_ONDEMAND_H +/* end file simdjson/haswell/ondemand.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(icelake) +/* including simdjson/icelake/ondemand.h: #include "simdjson/icelake/ondemand.h" */ +/* begin file simdjson/icelake/ondemand.h */ +#ifndef SIMDJSON_ICELAKE_ONDEMAND_H +#define SIMDJSON_ICELAKE_ONDEMAND_H + +/* including simdjson/icelake/begin.h: #include "simdjson/icelake/begin.h" */ +/* begin file simdjson/icelake/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "icelake" */ +#define SIMDJSON_IMPLEMENTATION icelake +/* including simdjson/icelake/base.h: #include "simdjson/icelake/base.h" */ +/* begin file simdjson/icelake/base.h */ +#ifndef SIMDJSON_ICELAKE_BASE_H +#define SIMDJSON_ICELAKE_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_ICELAKE +namespace simdjson { +/** + * Implementation for Icelake (Intel AVX512). + */ +namespace icelake { + +class implementation; + +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_BASE_H +/* end file simdjson/icelake/base.h */ +/* including simdjson/icelake/intrinsics.h: #include "simdjson/icelake/intrinsics.h" */ +/* begin file simdjson/icelake/intrinsics.h */ +#ifndef SIMDJSON_ICELAKE_INTRINSICS_H +#define SIMDJSON_ICELAKE_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + * e.g., if __AVX2__ is set... in turn, we normally set these + * macros by compiling against the corresponding architecture + * (e.g., arch:AVX2, -mavx2, etc.) which compiles the whole + * software with these advanced instructions. In simdjson, we + * want to compile the whole program for a generic target, + * and only target our specific kernels. As a workaround, + * we directly include the needed headers. These headers would + * normally guard against such usage, but we carefully included + * (or ) before, so the headers + * are fooled. + */ +#include // for _blsr_u64 +#include // for __lzcnt64 +#include // for most things (AVX2, AVX512, _popcnt64) +#include +#include +#include +#include +#include // for _mm_clmulepi64_si128 +// Important: we need the AVX-512 headers: +#include +#include +#include +#include +#include +#include +#include +// unfortunately, we may not get _blsr_u64, but, thankfully, clang +// has it as a macro. +#ifndef _blsr_u64 +// we roll our own +#define _blsr_u64(n) ((n - 1) & n) +#endif // _blsr_u64 +#endif // SIMDJSON_CLANG_VISUAL_STUDIO + +static_assert(sizeof(__m512i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for icelake"); + +#endif // SIMDJSON_ICELAKE_INTRINSICS_H +/* end file simdjson/icelake/intrinsics.h */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_ICELAKE +SIMDJSON_TARGET_REGION("avx512f,avx512dq,avx512cd,avx512bw,avx512vbmi,avx512vbmi2,avx512vl,avx2,bmi,pclmul,lzcnt,popcnt") +#endif + +/* including simdjson/icelake/bitmanipulation.h: #include "simdjson/icelake/bitmanipulation.h" */ +/* begin file simdjson/icelake/bitmanipulation.h */ +#ifndef SIMDJSON_ICELAKE_BITMANIPULATION_H +#define SIMDJSON_ICELAKE_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return (int)_tzcnt_u64(input_num); +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + //////// + // You might expect the next line to be equivalent to + // return (int)_tzcnt_u64(input_num); + // but the generated code differs and might be less efficient? + //////// + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return _blsr_u64(input_num); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { + return int(_lzcnt_u64(input_num)); +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_BITMANIPULATION_H +/* end file simdjson/icelake/bitmanipulation.h */ +/* including simdjson/icelake/bitmask.h: #include "simdjson/icelake/bitmask.h" */ +/* begin file simdjson/icelake/bitmask.h */ +#ifndef SIMDJSON_ICELAKE_BITMASK_H +#define SIMDJSON_ICELAKE_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(const uint64_t bitmask) { + // There should be no such thing with a processor supporting avx2 + // but not clmul. + __m128i all_ones = _mm_set1_epi8('\xFF'); + __m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0ULL, bitmask), all_ones, 0); + return _mm_cvtsi128_si64(result); +} + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_BITMASK_H +/* end file simdjson/icelake/bitmask.h */ +/* including simdjson/icelake/simd.h: #include "simdjson/icelake/simd.h" */ +/* begin file simdjson/icelake/simd.h */ +#ifndef SIMDJSON_ICELAKE_SIMD_H +#define SIMDJSON_ICELAKE_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if defined(__GNUC__) && !defined(__clang__) +#if __GNUC__ == 8 +#define SIMDJSON_GCC8 1 +#endif // __GNUC__ == 8 +#endif // defined(__GNUC__) && !defined(__clang__) + +#if SIMDJSON_GCC8 +/** + * GCC 8 fails to provide _mm512_set_epi8. We roll our own. + */ +inline __m512i _mm512_set_epi8(uint8_t a0, uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4, uint8_t a5, uint8_t a6, uint8_t a7, uint8_t a8, uint8_t a9, uint8_t a10, uint8_t a11, uint8_t a12, uint8_t a13, uint8_t a14, uint8_t a15, uint8_t a16, uint8_t a17, uint8_t a18, uint8_t a19, uint8_t a20, uint8_t a21, uint8_t a22, uint8_t a23, uint8_t a24, uint8_t a25, uint8_t a26, uint8_t a27, uint8_t a28, uint8_t a29, uint8_t a30, uint8_t a31, uint8_t a32, uint8_t a33, uint8_t a34, uint8_t a35, uint8_t a36, uint8_t a37, uint8_t a38, uint8_t a39, uint8_t a40, uint8_t a41, uint8_t a42, uint8_t a43, uint8_t a44, uint8_t a45, uint8_t a46, uint8_t a47, uint8_t a48, uint8_t a49, uint8_t a50, uint8_t a51, uint8_t a52, uint8_t a53, uint8_t a54, uint8_t a55, uint8_t a56, uint8_t a57, uint8_t a58, uint8_t a59, uint8_t a60, uint8_t a61, uint8_t a62, uint8_t a63) { + return _mm512_set_epi64(uint64_t(a7) + (uint64_t(a6) << 8) + (uint64_t(a5) << 16) + (uint64_t(a4) << 24) + (uint64_t(a3) << 32) + (uint64_t(a2) << 40) + (uint64_t(a1) << 48) + (uint64_t(a0) << 56), + uint64_t(a15) + (uint64_t(a14) << 8) + (uint64_t(a13) << 16) + (uint64_t(a12) << 24) + (uint64_t(a11) << 32) + (uint64_t(a10) << 40) + (uint64_t(a9) << 48) + (uint64_t(a8) << 56), + uint64_t(a23) + (uint64_t(a22) << 8) + (uint64_t(a21) << 16) + (uint64_t(a20) << 24) + (uint64_t(a19) << 32) + (uint64_t(a18) << 40) + (uint64_t(a17) << 48) + (uint64_t(a16) << 56), + uint64_t(a31) + (uint64_t(a30) << 8) + (uint64_t(a29) << 16) + (uint64_t(a28) << 24) + (uint64_t(a27) << 32) + (uint64_t(a26) << 40) + (uint64_t(a25) << 48) + (uint64_t(a24) << 56), + uint64_t(a39) + (uint64_t(a38) << 8) + (uint64_t(a37) << 16) + (uint64_t(a36) << 24) + (uint64_t(a35) << 32) + (uint64_t(a34) << 40) + (uint64_t(a33) << 48) + (uint64_t(a32) << 56), + uint64_t(a47) + (uint64_t(a46) << 8) + (uint64_t(a45) << 16) + (uint64_t(a44) << 24) + (uint64_t(a43) << 32) + (uint64_t(a42) << 40) + (uint64_t(a41) << 48) + (uint64_t(a40) << 56), + uint64_t(a55) + (uint64_t(a54) << 8) + (uint64_t(a53) << 16) + (uint64_t(a52) << 24) + (uint64_t(a51) << 32) + (uint64_t(a50) << 40) + (uint64_t(a49) << 48) + (uint64_t(a48) << 56), + uint64_t(a63) + (uint64_t(a62) << 8) + (uint64_t(a61) << 16) + (uint64_t(a60) << 24) + (uint64_t(a59) << 32) + (uint64_t(a58) << 40) + (uint64_t(a57) << 48) + (uint64_t(a56) << 56)); +} +#endif // SIMDJSON_GCC8 + + + +namespace simdjson { +namespace icelake { +namespace { +namespace simd { + + // Forward-declared so they can be used by splat and friends. + template + struct base { + __m512i value; + + // Zero constructor + simdjson_inline base() : value{__m512i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m512i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m512i&() const { return this->value; } + simdjson_inline operator __m512i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm512_or_si512(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm512_and_si512(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm512_xor_si512(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm512_andnot_si512(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + // Forward-declared so they can be used by splat and friends. + template + struct simd8; + + template> + struct base8: base> { + typedef uint32_t bitmask_t; + typedef uint64_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m512i _value) : base>(_value) {} + + friend simdjson_really_inline uint64_t operator==(const simd8 lhs, const simd8 rhs) { + return _mm512_cmpeq_epi8_mask(lhs, rhs); + } + + static const int SIZE = sizeof(base::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + // workaround for compilers unable to figure out that 16 - N is a constant (GCC 8) + constexpr int shift = 16 - N; + return _mm512_alignr_epi8(*this, _mm512_permutex2var_epi64(prev_chunk, _mm512_set_epi64(13, 12, 11, 10, 9, 8, 7, 6), *this), shift); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm512_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m512i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + simdjson_inline bool any() const { return !!_mm512_test_epi8_mask (*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm512_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm512_setzero_si512(); } + static simdjson_inline simd8 load(const T values[64]) { + return _mm512_loadu_si512(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m512i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[64]) const { return _mm512_storeu_si512(reinterpret_cast<__m512i *>(dst), *this); } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm512_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm512_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm512_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 32 - count_ones(mask) bytes of the result are significant but 32 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint64_t mask, L * output) const { + _mm512_mask_compressstoreu_epi8 (output,~mask,*this); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m512i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t values[64]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15, + int8_t v16, int8_t v17, int8_t v18, int8_t v19, int8_t v20, int8_t v21, int8_t v22, int8_t v23, + int8_t v24, int8_t v25, int8_t v26, int8_t v27, int8_t v28, int8_t v29, int8_t v30, int8_t v31, + int8_t v32, int8_t v33, int8_t v34, int8_t v35, int8_t v36, int8_t v37, int8_t v38, int8_t v39, + int8_t v40, int8_t v41, int8_t v42, int8_t v43, int8_t v44, int8_t v45, int8_t v46, int8_t v47, + int8_t v48, int8_t v49, int8_t v50, int8_t v51, int8_t v52, int8_t v53, int8_t v54, int8_t v55, + int8_t v56, int8_t v57, int8_t v58, int8_t v59, int8_t v60, int8_t v61, int8_t v62, int8_t v63 + ) : simd8(_mm512_set_epi8( + v63, v62, v61, v60, v59, v58, v57, v56, + v55, v54, v53, v52, v51, v50, v49, v48, + v47, v46, v45, v44, v43, v42, v41, v40, + v39, v38, v37, v36, v35, v34, v33, v32, + v31, v30, v29, v28, v27, v26, v25, v24, + v23, v22, v21, v20, v19, v18, v17, v16, + v15, v14, v13, v12, v11, v10, v9, v8, + v7, v6, v5, v4, v3, v2, v1, v0 + )) {} + + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm512_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm512_min_epi8(*this, other); } + + simdjson_inline simd8 operator>(const simd8 other) const { return _mm512_maskz_abs_epi8(_mm512_cmpgt_epi8_mask(*this, other),_mm512_set1_epi8(uint8_t(0x80))); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm512_maskz_abs_epi8(_mm512_cmpgt_epi8_mask(other, *this),_mm512_set1_epi8(uint8_t(0x80))); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m512i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t values[64]) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15, + uint8_t v16, uint8_t v17, uint8_t v18, uint8_t v19, uint8_t v20, uint8_t v21, uint8_t v22, uint8_t v23, + uint8_t v24, uint8_t v25, uint8_t v26, uint8_t v27, uint8_t v28, uint8_t v29, uint8_t v30, uint8_t v31, + uint8_t v32, uint8_t v33, uint8_t v34, uint8_t v35, uint8_t v36, uint8_t v37, uint8_t v38, uint8_t v39, + uint8_t v40, uint8_t v41, uint8_t v42, uint8_t v43, uint8_t v44, uint8_t v45, uint8_t v46, uint8_t v47, + uint8_t v48, uint8_t v49, uint8_t v50, uint8_t v51, uint8_t v52, uint8_t v53, uint8_t v54, uint8_t v55, + uint8_t v56, uint8_t v57, uint8_t v58, uint8_t v59, uint8_t v60, uint8_t v61, uint8_t v62, uint8_t v63 + ) : simd8(_mm512_set_epi8( + v63, v62, v61, v60, v59, v58, v57, v56, + v55, v54, v53, v52, v51, v50, v49, v48, + v47, v46, v45, v44, v43, v42, v41, v40, + v39, v38, v37, v36, v35, v34, v33, v32, + v31, v30, v29, v28, v27, v26, v25, v24, + v23, v22, v21, v20, v19, v18, v17, v16, + v15, v14, v13, v12, v11, v10, v9, v8, + v7, v6, v5, v4, v3, v2, v1, v0 + )) {} + + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15, + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm512_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm512_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm512_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm512_min_epu8(other, *this); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline uint64_t operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline uint64_t operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->lt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return _mm512_mask_blend_epi8(*this == uint8_t(0), _mm512_set1_epi8(0), _mm512_set1_epi8(-1)); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + + simdjson_inline bool is_ascii() const { return _mm512_movepi8_mask(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { + return !_mm512_test_epi8_mask(*this, *this); + } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return !_mm512_test_epi8_mask(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm512_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm512_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline uint64_t get_bit() const { return _mm512_movepi8_mask(_mm512_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 1, "Icelake kernel should use one register per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1) : chunks{chunk0, chunk1} {} + simdjson_inline simd8x64(const simd8 chunk0) : chunks{chunk0} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr)} {} + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + this->chunks[0].compress(mask, output); + return 64 - count_ones(mask); + } + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + } + + simdjson_inline simd8 reduce_or() const { + return this->chunks[0]; + } + + simdjson_inline simd8x64 bit_or(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] | mask + ); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return this->chunks[0] == mask; + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return this->chunks[0] == other.chunks[0]; + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return this->chunks[0] <= mask; + } + }; // struct simd8x64 + +} // namespace simd + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_SIMD_H +/* end file simdjson/icelake/simd.h */ +/* including simdjson/icelake/stringparsing_defs.h: #include "simdjson/icelake/stringparsing_defs.h" */ +/* begin file simdjson/icelake/stringparsing_defs.h */ +#ifndef SIMDJSON_ICELAKE_STRINGPARSING_DEFS_H +#define SIMDJSON_ICELAKE_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/simd.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 64; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return ((quote_bits - 1) & bs_bits) != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint64_t bs_bits; + uint64_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 15 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v(src); + // store to dest unconditionally - we can overwrite the bits we don't like later + v.store(dst); + return { + static_cast(v == '\\'), // bs_bits + static_cast(v == '"'), // quote_bits + }; +} + +} // unnamed namespace +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_ICELAKE_STRINGPARSING_DEFS_H +/* end file simdjson/icelake/stringparsing_defs.h */ +/* including simdjson/icelake/numberparsing_defs.h: #include "simdjson/icelake/numberparsing_defs.h" */ +/* begin file simdjson/icelake/numberparsing_defs.h */ +#ifndef SIMDJSON_ICELAKE_NUMBERPARSING_DEFS_H +#define SIMDJSON_ICELAKE_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace numberparsing { + +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + // this actually computes *16* values so we are being wasteful. + const __m128i ascii0 = _mm_set1_epi8('0'); + const __m128i mul_1_10 = + _mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1); + const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1); + const __m128i mul_1_10000 = + _mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1); + const __m128i input = _mm_sub_epi8( + _mm_loadu_si128(reinterpret_cast(chars)), ascii0); + const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10); + const __m128i t2 = _mm_madd_epi16(t1, mul_1_100); + const __m128i t3 = _mm_packus_epi32(t2, t2); + const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000); + return _mm_cvtsi128_si32( + t4); // only captures the sum of the first 8 digits, drop the rest +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace icelake +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_ICELAKE_NUMBERPARSING_DEFS_H +/* end file simdjson/icelake/numberparsing_defs.h */ +/* end file simdjson/icelake/begin.h */ +/* including simdjson/generic/ondemand/amalgamated.h for icelake: #include "simdjson/generic/ondemand/amalgamated.h" */ +/* begin file simdjson/generic/ondemand/amalgamated.h for icelake */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H) +#error simdjson/generic/ondemand/dependencies.h must be included before simdjson/generic/ondemand/amalgamated.h! +#endif + +// Stuff other things depend on +/* including simdjson/generic/ondemand/base.h for icelake: #include "simdjson/generic/ondemand/base.h" */ +/* begin file simdjson/generic/ondemand/base.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +/** + * A fast, simple, DOM-like interface that parses JSON as you use it. + * + * Designed for maximum speed and a lower memory profile. + */ +namespace ondemand { + +/** Represents the depth of a JSON value (number of nested arrays/objects). */ +using depth_t = int32_t; + +/** @copydoc simdjson::icelake::number_type */ +using number_type = simdjson::icelake::number_type; + +/** @private Position in the JSON buffer indexes */ +using token_position = const uint32_t *; + +class array; +class array_iterator; +class document; +class document_reference; +class document_stream; +class field; +class json_iterator; +enum class json_type; +struct number; +class object; +class object_iterator; +class parser; +class raw_json_string; +class token_iterator; +class value; +class value_iterator; + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_BASE_H +/* end file simdjson/generic/ondemand/base.h for icelake */ +/* including simdjson/generic/ondemand/value_iterator.h for icelake: #include "simdjson/generic/ondemand/value_iterator.h" */ +/* begin file simdjson/generic/ondemand/value_iterator.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +/** + * Iterates through a single JSON value at a particular depth. + * + * Does not keep track of the type of value: provides methods for objects, arrays and scalars and expects + * the caller to call the right ones. + * + * @private This is not intended for external use. + */ +class value_iterator { +protected: + /** The underlying JSON iterator */ + json_iterator *_json_iter{}; + /** The depth of this value */ + depth_t _depth{}; + /** + * The starting token index for this value + */ + token_position _start_position{}; + +public: + simdjson_inline value_iterator() noexcept = default; + + /** + * Denote that we're starting a document. + */ + simdjson_inline void start_document() noexcept; + + /** + * Skips a non-iterated or partially-iterated JSON value, whether it is a scalar, array or object. + * + * Optimized for scalars. + */ + simdjson_warn_unused simdjson_inline error_code skip_child() noexcept; + + /** + * Tell whether the iterator is at the EOF mark + */ + simdjson_inline bool at_end() const noexcept; + + /** + * Tell whether the iterator is at the start of the value + */ + simdjson_inline bool at_start() const noexcept; + + /** + * Tell whether the value is open--if the value has not been used, or the array/object is still open. + */ + simdjson_inline bool is_open() const noexcept; + + /** + * Tell whether the value is at an object's first field (just after the {). + */ + simdjson_inline bool at_first_field() const noexcept; + + /** + * Abandon all iteration. + */ + simdjson_inline void abandon() noexcept; + + /** + * Get the child value as a value_iterator. + */ + simdjson_inline value_iterator child_value() const noexcept; + + /** + * Get the depth of this value. + */ + simdjson_inline int32_t depth() const noexcept; + + /** + * Get the JSON type of this value. + * + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() const noexcept; + + /** + * @addtogroup object Object iteration + * + * Methods to iterate and find object fields. These methods generally *assume* the value is + * actually an object; the caller is responsible for keeping track of that fact. + * + * @{ + */ + + /** + * Start an object iteration. + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCORRECT_TYPE if there is no opening { + */ + simdjson_warn_unused simdjson_inline simdjson_result start_object() noexcept; + /** + * Start an object iteration from the root. + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCORRECT_TYPE if there is no opening { + * @error TAPE_ERROR if there is no matching } at end of document + */ + simdjson_warn_unused simdjson_inline simdjson_result start_root_object() noexcept; + /** + * Checks whether an object could be started from the root. May be called by start_root_object. + * + * @returns SUCCESS if it is possible to safely start an object from the root (document level). + * @error INCORRECT_TYPE if there is no opening { + * @error TAPE_ERROR if there is no matching } at end of document + */ + simdjson_warn_unused simdjson_inline error_code check_root_object() noexcept; + /** + * Start an object iteration after the user has already checked and moved past the {. + * + * Does not move the iterator unless the object is empty ({}). + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_object() noexcept; + /** + * Start an object iteration from the root, after the user has already checked and moved past the {. + * + * Does not move the iterator unless the object is empty ({}). + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_root_object() noexcept; + + /** + * Moves to the next field in an object. + * + * Looks for , and }. If } is found, the object is finished and the iterator advances past it. + * Otherwise, it advances to the next value. + * + * @return whether there is another field in the object. + * @error TAPE_ERROR If there is a comma missing between fields. + * @error TAPE_ERROR If there is a comma, but not enough tokens remaining to have a key, :, and value. + */ + simdjson_warn_unused simdjson_inline simdjson_result has_next_field() noexcept; + + /** + * Get the current field's key. + */ + simdjson_warn_unused simdjson_inline simdjson_result field_key() noexcept; + + /** + * Pass the : in the field and move to its value. + */ + simdjson_warn_unused simdjson_inline error_code field_value() noexcept; + + /** + * Find the next field with the given key. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline error_code find_field(const std::string_view key) noexcept; + + /** + * Find the next field with the given key, *without* unescaping. This assumes object order: it + * will not find the field if it was already passed when looking for some *other* field. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline simdjson_result find_field_raw(const std::string_view key) noexcept; + + /** + * Find the field with the given key without regard to order, and *without* unescaping. + * + * This is an unordered object lookup: if the field is not found initially, it will cycle around and scan from the beginning. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline simdjson_result find_field_unordered_raw(const std::string_view key) noexcept; + + /** @} */ + + /** + * @addtogroup array Array iteration + * Methods to iterate over array elements. These methods generally *assume* the value is actually + * an object; the caller is responsible for keeping track of that fact. + * @{ + */ + + /** + * Check for an opening [ and start an array iteration. + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCORRECT_TYPE If there is no [. + */ + simdjson_warn_unused simdjson_inline simdjson_result start_array() noexcept; + /** + * Check for an opening [ and start an array iteration while at the root. + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCORRECT_TYPE If there is no [. + * @error TAPE_ERROR if there is no matching ] at end of document + */ + simdjson_warn_unused simdjson_inline simdjson_result start_root_array() noexcept; + /** + * Checks whether an array could be started from the root. May be called by start_root_array. + * + * @returns SUCCESS if it is possible to safely start an array from the root (document level). + * @error INCORRECT_TYPE If there is no [. + * @error TAPE_ERROR if there is no matching ] at end of document + */ + simdjson_warn_unused simdjson_inline error_code check_root_array() noexcept; + /** + * Start an array iteration, after the user has already checked and moved past the [. + * + * Does not move the iterator unless the array is empty ([]). + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_array() noexcept; + /** + * Start an array iteration from the root, after the user has already checked and moved past the [. + * + * Does not move the iterator unless the array is empty ([]). + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_root_array() noexcept; + + /** + * Moves to the next element in an array. + * + * Looks for , and ]. If ] is found, the array is finished and the iterator advances past it. + * Otherwise, it advances to the next value. + * + * @return Whether there is another element in the array. + * @error TAPE_ERROR If there is a comma missing between elements. + */ + simdjson_warn_unused simdjson_inline simdjson_result has_next_element() noexcept; + + /** + * Get a child value iterator. + */ + simdjson_warn_unused simdjson_inline value_iterator child() const noexcept; + + /** @} */ + + /** + * @defgroup scalar Scalar values + * @addtogroup scalar + * @{ + */ + + simdjson_warn_unused simdjson_inline simdjson_result get_string(bool allow_replacement) noexcept; + template + simdjson_warn_unused simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_int64() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_double() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_bool() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_null() noexcept; + simdjson_warn_unused simdjson_inline bool is_negative() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_integer() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + simdjson_warn_unused simdjson_inline simdjson_result get_root_string(bool check_trailing, bool allow_replacement) noexcept; + template + simdjson_warn_unused simdjson_inline error_code get_root_string(string_type& receiver, bool check_trailing, bool allow_replacement) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_wobbly_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_raw_json_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_uint64(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_uint64_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_int64(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_int64_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_double(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_double_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_bool(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline bool is_root_negative() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_root_integer(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_number_type(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_number(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_root_null(bool check_trailing) noexcept; + + simdjson_inline error_code error() const noexcept; + simdjson_inline uint8_t *&string_buf_loc() noexcept; + simdjson_inline const json_iterator &json_iter() const noexcept; + simdjson_inline json_iterator &json_iter() noexcept; + + simdjson_inline void assert_is_valid() const noexcept; + simdjson_inline bool is_valid() const noexcept; + + /** @} */ +protected: + /** + * Restarts an array iteration. + * @returns Whether the array has any elements (returns false for empty). + */ + simdjson_inline simdjson_result reset_array() noexcept; + /** + * Restarts an object iteration. + * @returns Whether the object has any fields (returns false for empty). + */ + simdjson_inline simdjson_result reset_object() noexcept; + /** + * move_at_start(): moves us so that we are pointing at the beginning of + * the container. It updates the index so that at_start() is true and it + * syncs the depth. The user can then create a new container instance. + * + * Usage: used with value::count_elements(). + **/ + simdjson_inline void move_at_start() noexcept; + + /** + * move_at_container_start(): moves us so that we are pointing at the beginning of + * the container so that assert_at_container_start() passes. + * + * Usage: used with reset_array() and reset_object(). + **/ + simdjson_inline void move_at_container_start() noexcept; + /* Useful for debugging and logging purposes. */ + inline std::string to_string() const noexcept; + simdjson_inline value_iterator(json_iterator *json_iter, depth_t depth, token_position start_index) noexcept; + + simdjson_inline simdjson_result parse_null(const uint8_t *json) const noexcept; + simdjson_inline simdjson_result parse_bool(const uint8_t *json) const noexcept; + simdjson_inline const uint8_t *peek_start() const noexcept; + simdjson_inline uint32_t peek_start_length() const noexcept; + + /** + * The general idea of the advance_... methods and the peek_* methods + * is that you first peek and check that you have desired type. If you do, + * and only if you do, then you advance. + * + * We used to unconditionally advance. But this made reasoning about our + * current state difficult. + * Suppose you always advance. Look at the 'value' matching the key + * "shadowable" in the following example... + * + * ({"globals":{"a":{"shadowable":[}}}}) + * + * If the user thinks it is a Boolean and asks for it, then we check the '[', + * decide it is not a Boolean, but still move into the next character ('}'). Now + * we are left pointing at '}' right after a '['. And we have not yet reported + * an error, only that we do not have a Boolean. + * + * If, instead, you just stand your ground until it is content that you know, then + * you will only even move beyond the '[' if the user tells you that you have an + * array. So you will be at the '}' character inside the array and, hopefully, you + * will then catch the error because an array cannot start with '}', but the code + * processing Boolean values does not know this. + * + * So the contract is: first call 'peek_...' and then call 'advance_...' only + * if you have determined that it is a type you can handle. + * + * Unfortunately, it makes the code more verbose, longer and maybe more error prone. + */ + + simdjson_inline void advance_scalar(const char *type) noexcept; + simdjson_inline void advance_root_scalar(const char *type) noexcept; + simdjson_inline void advance_non_root_scalar(const char *type) noexcept; + + simdjson_inline const uint8_t *peek_scalar(const char *type) noexcept; + simdjson_inline const uint8_t *peek_root_scalar(const char *type) noexcept; + simdjson_inline const uint8_t *peek_non_root_scalar(const char *type) noexcept; + + + simdjson_inline error_code start_container(uint8_t start_char, const char *incorrect_type_message, const char *type) noexcept; + simdjson_inline error_code end_container() noexcept; + + /** + * Advance to a place expecting a value (increasing depth). + * + * @return The current token (the one left behind). + * @error TAPE_ERROR If the document ended early. + */ + simdjson_inline simdjson_result advance_to_value() noexcept; + + simdjson_inline error_code incorrect_type_error(const char *message) const noexcept; + simdjson_inline error_code error_unless_more_tokens(uint32_t tokens=1) const noexcept; + + simdjson_inline bool is_at_start() const noexcept; + /** + * is_at_iterator_start() returns true on an array or object after it has just been + * created, whether the instance is empty or not. + * + * Usage: used by array::begin() in debug mode (SIMDJSON_DEVELOPMENT_CHECKS) + */ + simdjson_inline bool is_at_iterator_start() const noexcept; + + /** + * Assuming that we are within an object, this returns true if we + * are pointing at a key. + * + * Usage: the skip_child() method should never be used while we are pointing + * at a key inside an object. + */ + simdjson_inline bool is_at_key() const noexcept; + + inline void assert_at_start() const noexcept; + inline void assert_at_container_start() const noexcept; + inline void assert_at_root() const noexcept; + inline void assert_at_child() const noexcept; + inline void assert_at_next() const noexcept; + inline void assert_at_non_root_start() const noexcept; + + /** Get the starting position of this value */ + simdjson_inline token_position start_position() const noexcept; + + /** @copydoc error_code json_iterator::position() const noexcept; */ + simdjson_inline token_position position() const noexcept; + /** @copydoc error_code json_iterator::end_position() const noexcept; */ + simdjson_inline token_position last_position() const noexcept; + /** @copydoc error_code json_iterator::end_position() const noexcept; */ + simdjson_inline token_position end_position() const noexcept; + /** @copydoc error_code json_iterator::report_error(error_code error, const char *message) noexcept; */ + simdjson_inline error_code report_error(error_code error, const char *message) noexcept; + + friend class document; + friend class object; + friend class array; + friend class value; +}; // value_iterator + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::value_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H +/* end file simdjson/generic/ondemand/value_iterator.h for icelake */ +/* including simdjson/generic/ondemand/value.h for icelake: #include "simdjson/generic/ondemand/value.h" */ +/* begin file simdjson/generic/ondemand/value.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +/** + * An ephemeral JSON value returned during iteration. It is only valid for as long as you do + * not access more data in the JSON document. + */ +class value { +public: + /** + * Create a new invalid value. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline value() noexcept = default; + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * You may use get_double(), get_bool(), get_uint64(), get_int64(), + * get_object(), get_array(), get_raw_json_string(), or get_string() instead. + * + * @returns A value of the given type, parsed from the JSON. + * @returns INCORRECT_TYPE If the JSON value is not the given type. + */ + template simdjson_inline simdjson_result get() noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * @param out This is set to a value of the given type, parsed from the JSON. If there is an error, this may not be initialized. + * @returns INCORRECT_TYPE If the JSON value is not an object. + * @returns SUCCESS If the parse succeeded and the out parameter was set to the value. + */ + template simdjson_inline error_code get(T &out) noexcept; + + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result get_array() noexcept; + + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @returns INCORRECT_TYPE If the JSON value is not an object. + */ + simdjson_inline simdjson_result get_object() noexcept; + + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A unsigned 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64() noexcept; + + /** + * Cast this JSON value (inside string) to a unsigned integer. + * + * @returns A unsigned 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64() noexcept; + + /** + * Cast this JSON value (inside string) to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64_in_string() noexcept; + + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double() noexcept; + + /** + * Cast this JSON value (inside string) to a double + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double_in_string() noexcept; + + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Equivalent to get(). + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + + /** + * Attempts to fill the provided std::string reference with the parsed value of the current string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory. + * We recommend you avoid allocating an std::string unless you need to. + * + * @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS. + */ + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + + /** + * Cast this JSON value to a "wobbly" string. + * + * The string is may not be a valid UTF-8 string. + * See https://simonsapin.github.io/wtf-8/ + * + * Important: a value should be consumed once. Calling get_wobbly_string() twice on the same value + * is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_wobbly_string() noexcept; + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_raw_json_string() noexcept; + + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @returns INCORRECT_TYPE if the JSON value is not true or false. + */ + simdjson_inline simdjson_result get_bool() noexcept; + + /** + * Checks if this JSON value is null. If and only if the value is + * null, then it is consumed (we advance). If we find a token that + * begins with 'n' but is not 'null', then an error is returned. + * + * @returns Whether the value is null. + * @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'. + */ + simdjson_inline simdjson_result is_null() noexcept; + +#if SIMDJSON_EXCEPTIONS + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an array. + */ + simdjson_inline operator array() noexcept(false); + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an object. + */ + simdjson_inline operator object() noexcept(false); + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline operator uint64_t() noexcept(false); + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer. + */ + simdjson_inline operator int64_t() noexcept(false); + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number. + */ + simdjson_inline operator double() noexcept(false); + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Equivalent to get(). + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator std::string_view() noexcept(false); + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator raw_json_string() noexcept(false); + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false. + */ + simdjson_inline operator bool() noexcept(false); +#endif + + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + * + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result begin() & noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() & noexcept; + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * Performance hint: You should only call count_elements() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method on the object instance. + * + * Performance hint: You should only call count_fields() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Get the value at the given index in the array. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) noexcept; + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) noexcept; + + /** + * Get the type of this JSON value. It does not validate or consume the value. + * E.g., you must still call "is_null()" to check that a value is null even if + * "type()" returns json_type::null. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + * + * @return The type of JSON value (json_type::array, json_type::object, json_type::string, + * json_type::number, json_type::boolean, or json_type::null). + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() noexcept; + + /** + * Checks whether the value is a scalar (string, number, null, Boolean). + * Returns false when there it is an array or object. + * + * @returns true if the type is string, number, null, Boolean + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result is_scalar() noexcept; + + /** + * Checks whether the value is a negative number. + * + * @returns true if the number if negative. + */ + simdjson_inline bool is_negative() noexcept; + /** + * Checks whether the value is an integer number. Note that + * this requires to partially parse the number string. If + * the value is determined to be an integer, it may still + * not parse properly as an integer in subsequent steps + * (e.g., it might overflow). + * + * Performance note: if you call this function systematically + * before parsing a number, you may have fallen for a performance + * anti-pattern. + * + * @returns true if the number if negative. + */ + simdjson_inline simdjson_result is_integer() noexcept; + /** + * Determine the number type (integer or floating-point number) as quickly + * as possible. This function does not fully validate the input. It is + * useful when you only need to classify the numbers, without parsing them. + * + * If you are planning to retrieve the value or you need full validation, + * consider using the get_number() method instead: it will fully parse + * and validate the input, and give you access to the type: + * get_number().get_number_type(). + * + * get_number_type() is number_type::unsigned_integer if we have + * an integer greater or equal to 9223372036854775808 + * get_number_type() is number_type::signed_integer if we have an + * integer that is less than 9223372036854775808 + * Otherwise, get_number_type() has value number_type::floating_point_number + * + * This function requires processing the number string, but it is expected + * to be faster than get_number().get_number_type() because it is does not + * parse the number value. + * + * @returns the type of the number + */ + simdjson_inline simdjson_result get_number_type() noexcept; + + /** + * Attempt to parse an ondemand::number. An ondemand::number may + * contain an integer value or a floating-point value, the simdjson + * library will autodetect the type. Thus it is a dynamically typed + * number. Before accessing the value, you must determine the detected + * type. + * + * number.get_number_type() is number_type::signed_integer if we have + * an integer in [-9223372036854775808,9223372036854775808) + * You can recover the value by calling number.get_int64() and you + * have that number.is_int64() is true. + * + * number.get_number_type() is number_type::unsigned_integer if we have + * an integer in [9223372036854775808,18446744073709551616) + * You can recover the value by calling number.get_uint64() and you + * have that number.is_uint64() is true. + * + * Otherwise, number.get_number_type() has value number_type::floating_point_number + * and we have a binary64 number. + * You can recover the value by calling number.get_double() and you + * have that number.is_double() is true. + * + * You must check the type before accessing the value: it is an error + * to call "get_int64()" when number.get_number_type() is not + * number_type::signed_integer and when number.is_int64() is false. + * + * Performance note: this is designed with performance in mind. When + * calling 'get_number()', you scan the number string only once, determining + * efficiently the type and storing it in an efficient manner. + */ + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + + /** + * Get the raw JSON for this token. + * + * The string_view will always point into the input buffer. + * + * The string_view will start at the beginning of the token, and include the entire token + * *as well as all spaces until the next token (or EOF).* This means, for example, that a + * string token always begins with a " and is always terminated by the final ", possibly + * followed by a number of spaces. + * + * The string_view is *not* null-terminated. However, if this is a scalar (string, number, + * boolean, or null), the character after the end of the string_view is guaranteed to be + * a non-space token. + * + * Tokens include: + * - { + * - [ + * - "a string (possibly with UTF-8 or backslashed characters like \\\")". + * - -1.2e-100 + * - true + * - false + * - null + * + * See also value::raw_json(). + */ + simdjson_inline std::string_view raw_json_token() noexcept; + + /** + * Get a string_view pointing at this value in the JSON document. + * If this element is an array or an object, it consumes the array or the object + * and returns a string_view instance corresponding to the + * array as represented in JSON. It points inside the original document. + * If this element is a scalar (string, number, Boolean, null), it returns what + * raw_json_token() would return. + */ + simdjson_inline simdjson_result raw_json() noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + simdjson_inline simdjson_result current_location() noexcept; + + /** + * Returns the current depth in the document if in bounds. + * + * E.g., + * 0 = finished with document + * 1 = document root value (could be [ or {, not yet known) + * 2 = , or } inside root array/object + * 3 = key or value inside root array/object. + */ + simdjson_inline int32_t current_depth() const noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. + * + * Calling at_pointer() on non-document instances (e.g., arrays and objects) is not + * standardized (by RFC 6901). We provide some experimental support for JSON pointers + * on non-document instances. Yet it is not the case when calling at_pointer on an array + * or an object instance: there is no rewind and no invalidation. + * + * You may only call at_pointer on an array after it has been created, but before it has + * been first accessed. When calling at_pointer on an array, the pointer is advanced to + * the location indicated by the JSON pointer (in case of success). It is no longer possible + * to call at_pointer on the same array. + * + * You may call at_pointer more than once on an object, but each time the pointer is advanced + * to be within the value matched by the key indicated by the JSON pointer query. Thus any preceding + * key (as well as the current key) can no longer be used with following JSON pointer calls. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + +protected: + /** + * Create a value. + */ + simdjson_inline value(const value_iterator &iter) noexcept; + + /** + * Skip this value, allowing iteration to continue. + */ + simdjson_inline void skip() noexcept; + + /** + * Start a value at the current position. + * + * (It should already be started; this is just a self-documentation method.) + */ + static simdjson_inline value start(const value_iterator &iter) noexcept; + + /** + * Resume a value. + */ + static simdjson_inline value resume(const value_iterator &iter) noexcept; + + /** + * Get the object, starting or resuming it as necessary + */ + simdjson_inline simdjson_result start_or_resume_object() noexcept; + + // simdjson_inline void log_value(const char *type) const noexcept; + // simdjson_inline void log_error(const char *message) const noexcept; + + value_iterator iter{}; + + friend class document; + friend class array_iterator; + friend class field; + friend class object; + friend struct simdjson_result; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::value &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result get_array() noexcept; + simdjson_inline simdjson_result get_object() noexcept; + + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + + template simdjson_inline simdjson_result get() noexcept; + + template simdjson_inline error_code get(T &out) noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator icelake::ondemand::array() noexcept(false); + simdjson_inline operator icelake::ondemand::object() noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator icelake::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) noexcept; + + /** + * Get the type of this JSON value. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + */ + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + + /** @copydoc simdjson_inline std::string_view value::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + + /** @copydoc simdjson_inline simdjson_result current_location() noexcept */ + simdjson_inline simdjson_result current_location() noexcept; + /** @copydoc simdjson_inline int32_t current_depth() const noexcept */ + simdjson_inline simdjson_result current_depth() const noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_H +/* end file simdjson/generic/ondemand/value.h for icelake */ +/* including simdjson/generic/ondemand/logger.h for icelake: #include "simdjson/generic/ondemand/logger.h" */ +/* begin file simdjson/generic/ondemand/logger.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_LOGGER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_LOGGER_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +// Logging should be free unless SIMDJSON_VERBOSE_LOGGING is set. Importantly, it is critical +// that the call to the log functions be side-effect free. Thus, for example, you should not +// create temporary std::string instances. +namespace logger { + +enum class log_level : int32_t { + info = 0, + error = 1 +}; + +#if SIMDJSON_VERBOSE_LOGGING + static constexpr const bool LOG_ENABLED = true; +#else + static constexpr const bool LOG_ENABLED = false; +#endif + +// We do not want these functions to be 'really inlined' since real inlining is +// for performance purposes and if you are using the loggers, you do not care about +// performance (or should not). +static inline void log_headers() noexcept; +// If args are provided, title will be treated as format string +template +static inline void log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +template +static inline void log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; +static inline void log_event(const json_iterator &iter, const char *type, std::string_view detail="", int delta=0, int depth_delta=0) noexcept; +static inline void log_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail="") noexcept; +static inline void log_value(const json_iterator &iter, const char *type, std::string_view detail="", int delta=-1, int depth_delta=0) noexcept; +static inline void log_start_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail="") noexcept; +static inline void log_start_value(const json_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_end_value(const json_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; + +static inline void log_error(const json_iterator &iter, token_position index, depth_t depth, const char *error, const char *detail="") noexcept; +static inline void log_error(const json_iterator &iter, const char *error, const char *detail="", int delta=-1, int depth_delta=0) noexcept; + +static inline void log_event(const value_iterator &iter, const char *type, std::string_view detail="", int delta=0, int depth_delta=0) noexcept; +static inline void log_value(const value_iterator &iter, const char *type, std::string_view detail="", int delta=-1, int depth_delta=0) noexcept; +static inline void log_start_value(const value_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_end_value(const value_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_error(const value_iterator &iter, const char *error, const char *detail="", int delta=-1, int depth_delta=0) noexcept; + +} // namespace logger +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_LOGGER_H +/* end file simdjson/generic/ondemand/logger.h for icelake */ +/* including simdjson/generic/ondemand/token_iterator.h for icelake: #include "simdjson/generic/ondemand/token_iterator.h" */ +/* begin file simdjson/generic/ondemand/token_iterator.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +/** + * Iterates through JSON tokens (`{` `}` `[` `]` `,` `:` `""` `123` `true` `false` `null`) + * detected by stage 1. + * + * @private This is not intended for external use. + */ +class token_iterator { +public: + /** + * Create a new invalid token_iterator. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline token_iterator() noexcept = default; + simdjson_inline token_iterator(token_iterator &&other) noexcept = default; + simdjson_inline token_iterator &operator=(token_iterator &&other) noexcept = default; + simdjson_inline token_iterator(const token_iterator &other) noexcept = default; + simdjson_inline token_iterator &operator=(const token_iterator &other) noexcept = default; + + /** + * Advance to the next token (returning the current one). + */ + simdjson_inline const uint8_t *return_current_and_advance() noexcept; + /** + * Reports the current offset in bytes from the start of the underlying buffer. + */ + simdjson_inline uint32_t current_offset() const noexcept; + /** + * Get the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(int32_t delta=0) const noexcept; + /** + * Get the maximum length of the JSON text for a given token. + * + * The length will include any whitespace at the end of the token. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_length(int32_t delta=0) const noexcept; + + /** + * Get the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token. + * + */ + simdjson_inline const uint8_t *peek(token_position position) const noexcept; + /** + * Get the maximum length of the JSON text for a given token. + * + * The length will include any whitespace at the end of the token. + * + * @param position The position of the token. + */ + simdjson_inline uint32_t peek_length(token_position position) const noexcept; + + /** + * Return the current index. + */ + simdjson_inline token_position position() const noexcept; + /** + * Reset to a previously saved index. + */ + simdjson_inline void set_position(token_position target_position) noexcept; + + // NOTE: we don't support a full C++ iterator interface, because we expect people to make + // different calls to advance the iterator based on *their own* state. + + simdjson_inline bool operator==(const token_iterator &other) const noexcept; + simdjson_inline bool operator!=(const token_iterator &other) const noexcept; + simdjson_inline bool operator>(const token_iterator &other) const noexcept; + simdjson_inline bool operator>=(const token_iterator &other) const noexcept; + simdjson_inline bool operator<(const token_iterator &other) const noexcept; + simdjson_inline bool operator<=(const token_iterator &other) const noexcept; + +protected: + simdjson_inline token_iterator(const uint8_t *buf, token_position position) noexcept; + + /** + * Get the index of the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_index(int32_t delta=0) const noexcept; + /** + * Get the index of the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token. + * + */ + simdjson_inline uint32_t peek_index(token_position position) const noexcept; + + const uint8_t *buf{}; + token_position _position{}; + + friend class json_iterator; + friend class value_iterator; + friend class object; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +}; + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::token_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H +/* end file simdjson/generic/ondemand/token_iterator.h for icelake */ +/* including simdjson/generic/ondemand/json_iterator.h for icelake: #include "simdjson/generic/ondemand/json_iterator.h" */ +/* begin file simdjson/generic/ondemand/json_iterator.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +/** + * Iterates through JSON tokens, keeping track of depth and string buffer. + * + * @private This is not intended for external use. + */ +class json_iterator { +protected: + token_iterator token{}; + ondemand::parser *parser{}; + /** + * Next free location in the string buffer. + * + * Used by raw_json_string::unescape() to have a place to unescape strings to. + */ + uint8_t *_string_buf_loc{}; + /** + * JSON error, if there is one. + * + * INCORRECT_TYPE and NO_SUCH_FIELD are *not* stored here, ever. + * + * PERF NOTE: we *hope* this will be elided into control flow, as it is only used (a) in the first + * iteration of the loop, or (b) for the final iteration after a missing comma is found in ++. If + * this is not elided, we should make sure it's at least not using up a register. Failing that, + * we should store it in document so there's only one of them. + */ + error_code error{SUCCESS}; + /** + * Depth of the current token in the JSON. + * + * - 0 = finished with document + * - 1 = document root value (could be [ or {, not yet known) + * - 2 = , or } inside root array/object + * - 3 = key or value inside root array/object. + */ + depth_t _depth{}; + /** + * Beginning of the document indexes. + * Normally we have root == parser->implementation->structural_indexes.get() + * but this may differ, especially in streaming mode (where we have several + * documents); + */ + token_position _root{}; + /** + * Normally, a json_iterator operates over a single document, but in + * some cases, we may have a stream of documents. This attribute is meant + * as meta-data: the json_iterator works the same irrespective of the + * value of this attribute. + */ + bool _streaming{false}; + +public: + simdjson_inline json_iterator() noexcept = default; + simdjson_inline json_iterator(json_iterator &&other) noexcept; + simdjson_inline json_iterator &operator=(json_iterator &&other) noexcept; + simdjson_inline explicit json_iterator(const json_iterator &other) noexcept = default; + simdjson_inline json_iterator &operator=(const json_iterator &other) noexcept = default; + /** + * Skips a JSON value, whether it is a scalar, array or object. + */ + simdjson_warn_unused simdjson_inline error_code skip_child(depth_t parent_depth) noexcept; + + /** + * Tell whether the iterator is still at the start + */ + simdjson_inline bool at_root() const noexcept; + + /** + * Tell whether we should be expected to run in streaming + * mode (iterating over many documents). It is pure metadata + * that does not affect how the iterator works. It is used by + * start_root_array() and start_root_object(). + */ + simdjson_inline bool streaming() const noexcept; + + /** + * Get the root value iterator + */ + simdjson_inline token_position root_position() const noexcept; + /** + * Assert that we are at the document depth (== 1) + */ + simdjson_inline void assert_at_document_depth() const noexcept; + /** + * Assert that we are at the root of the document + */ + simdjson_inline void assert_at_root() const noexcept; + + /** + * Tell whether the iterator is at the EOF mark + */ + simdjson_inline bool at_end() const noexcept; + + /** + * Tell whether the iterator is live (has not been moved). + */ + simdjson_inline bool is_alive() const noexcept; + + /** + * Abandon this iterator, setting depth to 0 (as if the document is finished). + */ + simdjson_inline void abandon() noexcept; + + /** + * Advance the current token without modifying depth. + */ + simdjson_inline const uint8_t *return_current_and_advance() noexcept; + + /** + * Returns true if there is a single token in the index (i.e., it is + * a JSON with a scalar value such as a single number). + * + * @return whether there is a single token + */ + simdjson_inline bool is_single_token() const noexcept; + + /** + * Assert that there are at least the given number of tokens left. + * + * Has no effect in release builds. + */ + simdjson_inline void assert_more_tokens(uint32_t required_tokens=1) const noexcept; + /** + * Assert that the given position addresses an actual token (is within bounds). + * + * Has no effect in release builds. + */ + simdjson_inline void assert_valid_position(token_position position) const noexcept; + /** + * Get the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = next token, -1 = prev token. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(int32_t delta=0) const noexcept; + /** + * Get the maximum length of the JSON text for the current token (or relative). + * + * The length will include any whitespace at the end of the token. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_length(int32_t delta=0) const noexcept; + /** + * Get a pointer to the current location in the input buffer. + * + * This is not null-terminated; it is a view into the JSON. + * + * You may be pointing outside of the input buffer: it is not generally + * safe to dereference this pointer. + */ + simdjson_inline const uint8_t *unsafe_pointer() const noexcept; + /** + * Get the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token to retrieve. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(token_position position) const noexcept; + /** + * Get the maximum length of the JSON text for the current token (or relative). + * + * The length will include any whitespace at the end of the token. + * + * @param position The position of the token to retrieve. + */ + simdjson_inline uint32_t peek_length(token_position position) const noexcept; + /** + * Get the JSON text for the last token in the document. + * + * This is not null-terminated; it is a view into the JSON. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek_last() const noexcept; + + /** + * Ascend one level. + * + * Validates that the depth - 1 == parent_depth. + * + * @param parent_depth the expected parent depth. + */ + simdjson_inline void ascend_to(depth_t parent_depth) noexcept; + + /** + * Descend one level. + * + * Validates that the new depth == child_depth. + * + * @param child_depth the expected child depth. + */ + simdjson_inline void descend_to(depth_t child_depth) noexcept; + simdjson_inline void descend_to(depth_t child_depth, int32_t delta) noexcept; + + /** + * Get current depth. + */ + simdjson_inline depth_t depth() const noexcept; + + /** + * Get current (writeable) location in the string buffer. + */ + simdjson_inline uint8_t *&string_buf_loc() noexcept; + + /** + * Report an unrecoverable error, preventing further iteration. + * + * @param error The error to report. Must not be SUCCESS, UNINITIALIZED, INCORRECT_TYPE, or NO_SUCH_FIELD. + * @param message An error message to report with the error. + */ + simdjson_inline error_code report_error(error_code error, const char *message) noexcept; + + /** + * Log error, but don't stop iteration. + * @param error The error to report. Must be INCORRECT_TYPE, or NO_SUCH_FIELD. + * @param message An error message to report with the error. + */ + simdjson_inline error_code optional_error(error_code error, const char *message) noexcept; + + /** + * Take an input in json containing max_len characters and attempt to copy it over to tmpbuf, a buffer with + * N bytes of capacity. It will return false if N is too small (smaller than max_len) of if it is zero. + * The buffer (tmpbuf) is padded with space characters. + */ + simdjson_warn_unused simdjson_inline bool copy_to_buffer(const uint8_t *json, uint32_t max_len, uint8_t *tmpbuf, size_t N) noexcept; + + simdjson_inline token_position position() const noexcept; + /** + * Write the raw_json_string to the string buffer and return a string_view. + * Each raw_json_string should be unescaped once, or else the string buffer might + * overflow. + */ + simdjson_inline simdjson_result unescape(raw_json_string in, bool allow_replacement) noexcept; + simdjson_inline simdjson_result unescape_wobbly(raw_json_string in) noexcept; + + simdjson_inline void reenter_child(token_position position, depth_t child_depth) noexcept; + + simdjson_inline error_code consume_character(char c) noexcept; +#if SIMDJSON_DEVELOPMENT_CHECKS + simdjson_inline token_position start_position(depth_t depth) const noexcept; + simdjson_inline void set_start_position(depth_t depth, token_position position) noexcept; +#endif + + /* Useful for debugging and logging purposes. */ + inline std::string to_string() const noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + inline simdjson_result current_location() const noexcept; + + /** + * Updates this json iterator so that it is back at the beginning of the document, + * as if it had just been created. + */ + inline void rewind() noexcept; + /** + * This checks whether the {,},[,] are balanced so that the document + * ends with proper zero depth. This requires scanning the whole document + * and it may be expensive. It is expected that it will be rarely called. + * It does not attempt to match { with } and [ with ]. + */ + inline bool balanced() const noexcept; +protected: + simdjson_inline json_iterator(const uint8_t *buf, ondemand::parser *parser) noexcept; + /// The last token before the end + simdjson_inline token_position last_position() const noexcept; + /// The token *at* the end. This points at gibberish and should only be used for comparison. + simdjson_inline token_position end_position() const noexcept; + /// The end of the buffer. + simdjson_inline token_position end() const noexcept; + + friend class document; + friend class document_stream; + friend class object; + friend class array; + friend class value; + friend class raw_json_string; + friend class parser; + friend class value_iterator; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +}; // json_iterator + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::json_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H +/* end file simdjson/generic/ondemand/json_iterator.h for icelake */ +/* including simdjson/generic/ondemand/json_type.h for icelake: #include "simdjson/generic/ondemand/json_type.h" */ +/* begin file simdjson/generic/ondemand/json_type.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/numberparsing.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +/** + * The type of a JSON value. + */ +enum class json_type { + // Start at 1 to catch uninitialized / default values more easily + array=1, ///< A JSON array ( [ 1, 2, 3 ... ] ) + object, ///< A JSON object ( { "a": 1, "b" 2, ... } ) + number, ///< A JSON number ( 1 or -2.3 or 4.5e6 ...) + string, ///< A JSON string ( "a" or "hello world\n" ...) + boolean, ///< A JSON boolean (true or false) + null ///< A JSON null (null) +}; + +/** + * A type representing a JSON number. + * The design of the struct is deliberately straight-forward. All + * functions return standard values with no error check. + */ +struct number { + + /** + * return the automatically determined type of + * the number: number_type::floating_point_number, + * number_type::signed_integer or number_type::unsigned_integer. + * + * enum class number_type { + * floating_point_number=1, /// a binary64 number + * signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + * unsigned_integer /// a positive integer larger or equal to 1<<63 + * }; + */ + simdjson_inline ondemand::number_type get_number_type() const noexcept; + /** + * return true if the automatically determined type of + * the number is number_type::unsigned_integer. + */ + simdjson_inline bool is_uint64() const noexcept; + /** + * return the value as a uint64_t, only valid if is_uint64() is true. + */ + simdjson_inline uint64_t get_uint64() const noexcept; + simdjson_inline operator uint64_t() const noexcept; + + /** + * return true if the automatically determined type of + * the number is number_type::signed_integer. + */ + simdjson_inline bool is_int64() const noexcept; + /** + * return the value as a int64_t, only valid if is_int64() is true. + */ + simdjson_inline int64_t get_int64() const noexcept; + simdjson_inline operator int64_t() const noexcept; + + + /** + * return true if the automatically determined type of + * the number is number_type::floating_point_number. + */ + simdjson_inline bool is_double() const noexcept; + /** + * return the value as a double, only valid if is_double() is true. + */ + simdjson_inline double get_double() const noexcept; + simdjson_inline operator double() const noexcept; + + /** + * Convert the number to a double. Though it always succeed, the conversion + * may be lossy if the number cannot be represented exactly. + */ + simdjson_inline double as_double() const noexcept; + + +protected: + /** + * The next block of declaration is designed so that we can call the number parsing + * functions on a number type. They are protected and should never be used outside + * of the core simdjson library. + */ + friend class value_iterator; + template + friend error_code numberparsing::write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer); + template + friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer); + /** Store a signed 64-bit value to the number. */ + simdjson_inline void append_s64(int64_t value) noexcept; + /** Store an unsigned 64-bit value to the number. */ + simdjson_inline void append_u64(uint64_t value) noexcept; + /** Store a double value to the number. */ + simdjson_inline void append_double(double value) noexcept; + /** Specifies that the value is a double, but leave it undefined. */ + simdjson_inline void skip_double() noexcept; + /** + * End of friend declarations. + */ + + /** + * Our attributes are a union type (size = 64 bits) + * followed by a type indicator. + */ + union { + double floating_point_number; + int64_t signed_integer; + uint64_t unsigned_integer; + } payload{0}; + number_type type{number_type::signed_integer}; +}; + +/** + * Write the JSON type to the output stream + * + * @param out The output stream. + * @param type The json_type. + */ +inline std::ostream& operator<<(std::ostream& out, json_type type) noexcept; + +#if SIMDJSON_EXCEPTIONS +/** + * Send JSON type to an output stream. + * + * @param out The output stream. + * @param type The json_type. + * @throw simdjson_error if the result being printed has an error. If there is an error with the + * underlying output stream, that error will be propagated (simdjson_error will not be + * thrown). + */ +inline std::ostream& operator<<(std::ostream& out, simdjson_result &type) noexcept(false); +#endif + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::json_type &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H +/* end file simdjson/generic/ondemand/json_type.h for icelake */ +/* including simdjson/generic/ondemand/raw_json_string.h for icelake: #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* begin file simdjson/generic/ondemand/raw_json_string.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +/** + * A string escaped per JSON rules, terminated with quote ("). They are used to represent + * unescaped keys inside JSON documents. + * + * (In other words, a pointer to the beginning of a string, just after the start quote, inside a + * JSON file.) + * + * This class is deliberately simplistic and has little functionality. You can + * compare a raw_json_string instance with an unescaped C string, but + * that is nearly all you can do. + * + * The raw_json_string is unescaped. If you wish to write an unescaped version of it to your own + * buffer, you may do so using the parser.unescape(string, buff) method, using an ondemand::parser + * instance. Doing so requires you to have a sufficiently large buffer. + * + * The raw_json_string instances originate typically from field instance which in turn represent + * key-value pairs from object instances. From a field instance, you get the raw_json_string + * instance by calling key(). You can, if you want a more usable string_view instance, call + * the unescaped_key() method on the field instance. You may also create a raw_json_string from + * any other string value, with the value.get_raw_json_string() method. Again, you can get + * a more usable string_view instance by calling get_string(). + * + */ +class raw_json_string { +public: + /** + * Create a new invalid raw_json_string. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline raw_json_string() noexcept = default; + + /** + * Create a new invalid raw_json_string pointed at the given location in the JSON. + * + * The given location must be just *after* the beginning quote (") in the JSON file. + * + * It *must* be terminated by a ", and be a valid JSON string. + */ + simdjson_inline raw_json_string(const uint8_t * _buf) noexcept; + /** + * Get the raw pointer to the beginning of the string in the JSON (just after the "). + * + * It is possible for this function to return a null pointer if the instance + * has outlived its existence. + */ + simdjson_inline const char * raw() const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done) on target.size() characters, + * and if the raw_json_string instance has a quote character at byte index target.size(). + * We never read more than length + 1 bytes in the raw_json_string instance. + * If length is smaller than target.size(), this will return false. + * + * The std::string_view instance may contain any characters. However, the caller + * is responsible for setting length so that length bytes may be read in the + * raw_json_string. + * + * Performance: the comparison may be done using memcmp which may be efficient + * for long strings. + */ + simdjson_inline bool unsafe_is_equal(size_t length, std::string_view target) const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done). + * The std::string_view instance should not contain unescaped quote characters: + * the caller is responsible for this check. See is_free_from_unescaped_quote. + * + * Performance: the comparison is done byte-by-byte which might be inefficient for + * long strings. + * + * If target is a compile-time constant, and your compiler likes you, + * you should be able to do the following without performance penalty... + * + * static_assert(raw_json_string::is_free_from_unescaped_quote(target), ""); + * s.unsafe_is_equal(target); + */ + simdjson_inline bool unsafe_is_equal(std::string_view target) const noexcept; + + /** + * This compares the current instance to the C string target: returns true if + * they are byte-by-byte equal (no escaping is done). + * The provided C string should not contain an unescaped quote character: + * the caller is responsible for this check. See is_free_from_unescaped_quote. + * + * If target is a compile-time constant, and your compiler likes you, + * you should be able to do the following without performance penalty... + * + * static_assert(raw_json_string::is_free_from_unescaped_quote(target), ""); + * s.unsafe_is_equal(target); + */ + simdjson_inline bool unsafe_is_equal(const char* target) const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done). + */ + simdjson_inline bool is_equal(std::string_view target) const noexcept; + + /** + * This compares the current instance to the C string target: returns true if + * they are byte-by-byte equal (no escaping is done). + */ + simdjson_inline bool is_equal(const char* target) const noexcept; + + /** + * Returns true if target is free from unescaped quote. If target is known at + * compile-time, we might expect the computation to happen at compile time with + * many compilers (not all!). + */ + static simdjson_inline bool is_free_from_unescaped_quote(std::string_view target) noexcept; + static simdjson_inline bool is_free_from_unescaped_quote(const char* target) noexcept; + +private: + + + /** + * This will set the inner pointer to zero, effectively making + * this instance unusable. + */ + simdjson_inline void consume() noexcept { buf = nullptr; } + + /** + * Checks whether the inner pointer is non-null and thus usable. + */ + simdjson_inline simdjson_warn_unused bool alive() const noexcept { return buf != nullptr; } + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. + * The result will be a valid UTF-8. + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid until the next parse() call on the parser. + * + * @param iter A json_iterator, which contains a buffer where the string will be written. + * @param allow_replacement Whether we allow replacement of invalid surrogate pairs. + */ + simdjson_inline simdjson_warn_unused simdjson_result unescape(json_iterator &iter, bool allow_replacement) const noexcept; + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. + * The result may not be a valid UTF-8. https://simonsapin.github.io/wtf-8/ + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid until the next parse() call on the parser. + * + * @param iter A json_iterator, which contains a buffer where the string will be written. + */ + simdjson_inline simdjson_warn_unused simdjson_result unescape_wobbly(json_iterator &iter) const noexcept; + const uint8_t * buf{}; + friend class object; + friend class field; + friend class parser; + friend struct simdjson_result; +}; + +simdjson_unused simdjson_inline std::ostream &operator<<(std::ostream &, const raw_json_string &) noexcept; + +/** + * Comparisons between raw_json_string and std::string_view instances are potentially unsafe: the user is responsible + * for providing a string with no unescaped quote. Note that unescaped quotes cannot be present in valid JSON strings. + */ +simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept; +simdjson_unused simdjson_inline bool operator==(std::string_view c, const raw_json_string &a) noexcept; +simdjson_unused simdjson_inline bool operator!=(const raw_json_string &a, std::string_view c) noexcept; +simdjson_unused simdjson_inline bool operator!=(std::string_view c, const raw_json_string &a) noexcept; + + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::raw_json_string &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private + + simdjson_inline simdjson_result raw() const noexcept; + simdjson_inline simdjson_warn_unused simdjson_result unescape(icelake::ondemand::json_iterator &iter, bool allow_replacement) const noexcept; + simdjson_inline simdjson_warn_unused simdjson_result unescape_wobbly(icelake::ondemand::json_iterator &iter) const noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H +/* end file simdjson/generic/ondemand/raw_json_string.h for icelake */ +/* including simdjson/generic/ondemand/parser.h for icelake: #include "simdjson/generic/ondemand/parser.h" */ +/* begin file simdjson/generic/ondemand/parser.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_PARSER_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace icelake { +namespace ondemand { + +/** + * The default batch size for document_stream instances for this On Demand kernel. + * Note that different On Demand kernel may use a different DEFAULT_BATCH_SIZE value + * in the future. + */ +static constexpr size_t DEFAULT_BATCH_SIZE = 1000000; +/** + * Some adversary might try to set the batch size to 0 or 1, which might cause problems. + * We set a minimum of 32B since anything else is highly likely to be an error. In practice, + * most users will want a much larger batch size. + * + * All non-negative MINIMAL_BATCH_SIZE values should be 'safe' except that, obviously, no JSON + * document can ever span 0 or 1 byte and that very large values would create memory allocation issues. + */ +static constexpr size_t MINIMAL_BATCH_SIZE = 32; + +/** + * A JSON fragment iterator. + * + * This holds the actual iterator as well as the buffer for writing strings. + */ +class parser { +public: + /** + * Create a JSON parser. + * + * The new parser will have zero capacity. + */ + inline explicit parser(size_t max_capacity = SIMDJSON_MAXSIZE_BYTES) noexcept; + + inline parser(parser &&other) noexcept = default; + simdjson_inline parser(const parser &other) = delete; + simdjson_inline parser &operator=(const parser &other) = delete; + simdjson_inline parser &operator=(parser &&other) noexcept = default; + + /** Deallocate the JSON parser. */ + inline ~parser() noexcept = default; + + /** + * Start iterating an on-demand JSON document. + * + * ondemand::parser parser; + * document doc = parser.iterate(json); + * + * It is expected that the content is a valid UTF-8 file, containing a valid JSON document. + * Otherwise the iterate method may return an error. In particular, the whole input should be + * valid: we do not attempt to tolerate incorrect content either before or after a JSON + * document. If there is a UTF-8 BOM, the parser skips it. + * + * ### IMPORTANT: Validate what you use + * + * Calling iterate on an invalid JSON document may not immediately trigger an error. The call to + * iterate does not parse and validate the whole document. + * + * ### IMPORTANT: Buffer Lifetime + * + * Because parsing is done while you iterate, you *must* keep the JSON buffer around at least as + * long as the document iteration. + * + * ### IMPORTANT: Document Lifetime + * + * Only one iteration at a time can happen per parser, and the parser *must* be kept alive during + * iteration to ensure intermediate buffers can be accessed. Any document must be destroyed before + * you call parse() again or destroy the parser. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * @param json The JSON to parse. + * @param len The length of the JSON. + * @param capacity The number of bytes allocated in the JSON (must be at least len+SIMDJSON_PADDING). + * + * @return The document, or an error: + * - INSUFFICIENT_PADDING if the input has less than SIMDJSON_PADDING extra bytes. + * - MEMALLOC if realloc_if_needed the parser does not have enough capacity, and memory + * allocation fails. + * - EMPTY if the document is all whitespace. + * - UTF8_ERROR if the document is not valid UTF-8. + * - UNESCAPED_CHARS if a string contains control characters that must be escaped + * - UNCLOSED_STRING if there is an unclosed string in the document. + */ + simdjson_warn_unused simdjson_result iterate(padded_string_view json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const char *json, size_t len, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const uint8_t *json, size_t len, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(std::string_view json, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const std::string &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(std::string &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const simdjson_result &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const simdjson_result &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(padded_string &&json) & noexcept = delete; + + /** + * @private + * + * Start iterating an on-demand JSON document. + * + * ondemand::parser parser; + * json_iterator doc = parser.iterate(json); + * + * ### IMPORTANT: Buffer Lifetime + * + * Because parsing is done while you iterate, you *must* keep the JSON buffer around at least as + * long as the document iteration. + * + * ### IMPORTANT: Document Lifetime + * + * Only one iteration at a time can happen per parser, and the parser *must* be kept alive during + * iteration to ensure intermediate buffers can be accessed. Any document must be destroyed before + * you call parse() again or destroy the parser. + * + * The ondemand::document instance holds the iterator. The document must remain in scope + * while you are accessing instances of ondemand::value, ondemand::object, ondemand::array. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * @param json The JSON to parse. + * + * @return The iterator, or an error: + * - INSUFFICIENT_PADDING if the input has less than SIMDJSON_PADDING extra bytes. + * - MEMALLOC if realloc_if_needed the parser does not have enough capacity, and memory + * allocation fails. + * - EMPTY if the document is all whitespace. + * - UTF8_ERROR if the document is not valid UTF-8. + * - UNESCAPED_CHARS if a string contains control characters that must be escaped + * - UNCLOSED_STRING if there is an unclosed string in the document. + */ + simdjson_warn_unused simdjson_result iterate_raw(padded_string_view json) & noexcept; + + + /** + * Parse a buffer containing many JSON documents. + * + * auto json = R"({ "foo": 1 } { "foo": 2 } { "foo": 3 } )"_padded; + * ondemand::parser parser; + * ondemand::document_stream docs = parser.iterate_many(json); + * for (auto & doc : docs) { + * std::cout << doc["foo"] << std::endl; + * } + * // Prints 1 2 3 + * + * No copy of the input buffer is made. + * + * The function is lazy: it may be that no more than one JSON document at a time is parsed. + * + * The caller is responsabile to ensure that the input string data remains unchanged and is + * not deleted during the loop. + * + * ### Format + * + * The buffer must contain a series of one or more JSON documents, concatenated into a single + * buffer, separated by ASCII whitespace. It effectively parses until it has a fully valid document, + * then starts parsing the next document at that point. (It does this with more parallelism and + * lookahead than you might think, though.) + * + * documents that consist of an object or array may omit the whitespace between them, concatenating + * with no separator. Documents that consist of a single primitive (i.e. documents that are not + * arrays or objects) MUST be separated with ASCII whitespace. + * + * The characters inside a JSON document, and between JSON documents, must be valid Unicode (UTF-8). + * If there is a UTF-8 BOM, the parser skips it. + * + * The documents must not exceed batch_size bytes (by default 1MB) or they will fail to parse. + * Setting batch_size to excessively large or excessively small values may impact negatively the + * performance. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * ### Threads + * + * When compiled with SIMDJSON_THREADS_ENABLED, this method will use a single thread under the + * hood to do some lookahead. + * + * ### Parser Capacity + * + * If the parser's current capacity is less than batch_size, it will allocate enough capacity + * to handle it (up to max_capacity). + * + * @param buf The concatenated JSON to parse. + * @param len The length of the concatenated JSON. + * @param batch_size The batch size to use. MUST be larger than the largest document. The sweet + * spot is cache-related: small enough to fit in cache, yet big enough to + * parse as many documents as possible in one tight loop. + * Defaults to 10MB, which has been a reasonable sweet spot in our tests. + * @param allow_comma_separated (defaults on false) This allows a mode where the documents are + * separated by commas instead of whitespace. It comes with a performance + * penalty because the entire document is indexed at once (and the document must be + * less than 4 GB), and there is no multithreading. In this mode, the batch_size parameter + * is effectively ignored, as it is set to at least the document size. + * @return The stream, or an error. An empty input will yield 0 documents rather than an EMPTY error. Errors: + * - MEMALLOC if the parser does not have enough capacity and memory allocation fails + * - CAPACITY if the parser does not have enough capacity and batch_size > max_capacity. + * - other json errors if parsing fails. You should not rely on these errors to always the same for the + * same document: they may vary under runtime dispatch (so they may vary depending on your system and hardware). + */ + inline simdjson_result iterate_many(const uint8_t *buf, size_t len, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const char *buf, size_t len, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const std::string &s, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + inline simdjson_result iterate_many(const std::string &&s, size_t batch_size, bool allow_comma_separated = false) = delete;// unsafe + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const padded_string &s, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + inline simdjson_result iterate_many(const padded_string &&s, size_t batch_size, bool allow_comma_separated = false) = delete;// unsafe + + /** @private We do not want to allow implicit conversion from C string to std::string. */ + simdjson_result iterate_many(const char *buf, size_t batch_size = DEFAULT_BATCH_SIZE) noexcept = delete; + + /** The capacity of this parser (the largest document it can process). */ + simdjson_inline size_t capacity() const noexcept; + /** The maximum capacity of this parser (the largest document it is allowed to process). */ + simdjson_inline size_t max_capacity() const noexcept; + simdjson_inline void set_max_capacity(size_t max_capacity) noexcept; + /** + * The maximum depth of this parser (the most deeply nested objects and arrays it can process). + * This parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true. + * The document's instance current_depth() method should be used to monitor the parsing + * depth and limit it if desired. + */ + simdjson_inline size_t max_depth() const noexcept; + + /** + * Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length + * and `max_depth` depth. + * + * The max_depth parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true. + * The document's instance current_depth() method should be used to monitor the parsing + * depth and limit it if desired. + * + * @param capacity The new capacity. + * @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH. + * @return The error, if there is one. + */ + simdjson_warn_unused error_code allocate(size_t capacity, size_t max_depth=DEFAULT_MAX_DEPTH) noexcept; + + #ifdef SIMDJSON_THREADS_ENABLED + /** + * The parser instance can use threads when they are available to speed up some + * operations. It is enabled by default. Changing this attribute will change the + * behavior of the parser for future operations. + */ + bool threaded{true}; + #endif + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. to a user-provided buffer. + * The result must be valid UTF-8. + * The provided pointer is advanced to the end of the string by reference, and a string_view instance + * is returned. You can ensure that your buffer is large enough by allocating a block of memory at least + * as large as the input JSON plus SIMDJSON_PADDING and then unescape all strings to this one buffer. + * + * This unescape function is a low-level function. If you want a more user-friendly approach, you should + * avoid raw_json_string instances (e.g., by calling unescaped_key() instead of key() or get_string() + * instead of get_raw_json_string()). + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid as long as the bytes in dst. + * + * @param raw_json_string input + * @param dst A pointer to a buffer at least large enough to write this string as well as + * an additional SIMDJSON_PADDING bytes. + * @param allow_replacement Whether we allow a replacement if the input string contains unmatched surrogate pairs. + * @return A string_view pointing at the unescaped string in dst + * @error STRING_ERROR if escapes are incorrect. + */ + simdjson_inline simdjson_result unescape(raw_json_string in, uint8_t *&dst, bool allow_replacement = false) const noexcept; + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. to a user-provided buffer. + * The result may not be valid UTF-8. See https://simonsapin.github.io/wtf-8/ + * The provided pointer is advanced to the end of the string by reference, and a string_view instance + * is returned. You can ensure that your buffer is large enough by allocating a block of memory at least + * as large as the input JSON plus SIMDJSON_PADDING and then unescape all strings to this one buffer. + * + * This unescape function is a low-level function. If you want a more user-friendly approach, you should + * avoid raw_json_string instances (e.g., by calling unescaped_key() instead of key() or get_string() + * instead of get_raw_json_string()). + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid as long as the bytes in dst. + * + * @param raw_json_string input + * @param dst A pointer to a buffer at least large enough to write this string as well as + * an additional SIMDJSON_PADDING bytes. + * @return A string_view pointing at the unescaped string in dst + * @error STRING_ERROR if escapes are incorrect. + */ + simdjson_inline simdjson_result unescape_wobbly(raw_json_string in, uint8_t *&dst) const noexcept; + +private: + /** @private [for benchmarking access] The implementation to use */ + std::unique_ptr implementation{}; + size_t _capacity{0}; + size_t _max_capacity; + size_t _max_depth{DEFAULT_MAX_DEPTH}; + std::unique_ptr string_buf{}; +#if SIMDJSON_DEVELOPMENT_CHECKS + std::unique_ptr start_positions{}; +#endif + + friend class json_iterator; + friend class document_stream; +}; + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::parser &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_PARSER_H +/* end file simdjson/generic/ondemand/parser.h for icelake */ + +// All other declarations +/* including simdjson/generic/ondemand/array.h for icelake: #include "simdjson/generic/ondemand/array.h" */ +/* begin file simdjson/generic/ondemand/array.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +/** + * A forward-only JSON array. + */ +class array { +public: + /** + * Create a new invalid array. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline array() noexcept = default; + + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result begin() noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() noexcept; + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an array is empty, it is more performant to use + * the is_empty() method. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the beginning of the array and checks whether the + * array is empty. + * The runtime complexity is constant time. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + simdjson_inline simdjson_result is_empty() & noexcept; + /** + * Reset the iterator so that we are pointing back at the + * beginning of the array. You should still consume values only once even if you + * can iterate through the array more than once. If you unescape a string + * within the array more than once, you have unsafe code. Note that rewinding + * an array means that you may need to reparse it anew: it is not a free + * operation. + * + * @returns true if the array contains some elements (not empty) + */ + inline simdjson_result reset() & noexcept; + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard, interpreting the current node + * as the root of its own JSON document. + * + * ondemand::parser parser; + * auto json = R"([ { "foo": { "a": [ 10, 20, 30 ] }} ])"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/0/foo/a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. Yet it is not the case when calling at_pointer on an array + * instance: there is no rewind and no invalidation. + * + * You may only call at_pointer on an array after it has been created, but before it has + * been first accessed. When calling at_pointer on an array, the pointer is advanced to + * the location indicated by the JSON pointer (in case of success). It is no longer possible + * to call at_pointer on the same array. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching. + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + /** + * Consumes the array and returns a string_view instance corresponding to the + * array as represented in JSON. It points inside the original document. + */ + simdjson_inline simdjson_result raw_json() noexcept; + + /** + * Get the value at the given index. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) noexcept; +protected: + /** + * Go to the end of the array, no matter where you are right now. + */ + simdjson_inline error_code consume() noexcept; + + /** + * Begin array iteration. + * + * @param iter The iterator. Must be where the initial [ is expected. Will be *moved* into the + * resulting array. + * @error INCORRECT_TYPE if the iterator is not at [. + */ + static simdjson_inline simdjson_result start(value_iterator &iter) noexcept; + /** + * Begin array iteration from the root. + * + * @param iter The iterator. Must be where the initial [ is expected. Will be *moved* into the + * resulting array. + * @error INCORRECT_TYPE if the iterator is not at [. + * @error TAPE_ERROR if there is no closing ] at the end of the document. + */ + static simdjson_inline simdjson_result start_root(value_iterator &iter) noexcept; + /** + * Begin array iteration. + * + * This version of the method should be called after the initial [ has been verified, and is + * intended for use by switch statements that check the type of a value. + * + * @param iter The iterator. Must be after the initial [. Will be *moved* into the resulting array. + */ + static simdjson_inline simdjson_result started(value_iterator &iter) noexcept; + + /** + * Create an array at the given Internal array creation. Call array::start() or array::started() instead of this. + * + * @param iter The iterator. Must either be at the start of the first element with iter.is_alive() + * == true, or past the [] with is_alive() == false if the array is empty. Will be *moved* + * into the resulting array. + */ + simdjson_inline array(const value_iterator &iter) noexcept; + + /** + * Iterator marking current position. + * + * iter.is_alive() == false indicates iteration is complete. + */ + value_iterator iter{}; + + friend class value; + friend class document; + friend struct simdjson_result; + friend struct simdjson_result; + friend class array_iterator; +}; + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::array &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + inline simdjson_result count_elements() & noexcept; + inline simdjson_result is_empty() & noexcept; + inline simdjson_result reset() & noexcept; + simdjson_inline simdjson_result at(size_t index) noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_H +/* end file simdjson/generic/ondemand/array.h for icelake */ +/* including simdjson/generic/ondemand/array_iterator.h for icelake: #include "simdjson/generic/ondemand/array_iterator.h" */ +/* begin file simdjson/generic/ondemand/array_iterator.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + + +namespace simdjson { +namespace icelake { +namespace ondemand { + +/** + * A forward-only JSON array. + * + * This is an input_iterator, meaning: + * - It is forward-only + * - * must be called exactly once per element. + * - ++ must be called exactly once in between each * (*, ++, *, ++, * ...) + */ +class array_iterator { +public: + /** Create a new, invalid array iterator. */ + simdjson_inline array_iterator() noexcept = default; + + // + // Iterator interface + // + + /** + * Get the current element. + * + * Part of the std::iterator interface. + */ + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + /** + * Check if we are at the end of the JSON. + * + * Part of the std::iterator interface. + * + * @return true if there are no more elements in the JSON array. + */ + simdjson_inline bool operator==(const array_iterator &) const noexcept; + /** + * Check if there are more elements in the JSON array. + * + * Part of the std::iterator interface. + * + * @return true if there are more elements in the JSON array. + */ + simdjson_inline bool operator!=(const array_iterator &) const noexcept; + /** + * Move to the next element. + * + * Part of the std::iterator interface. + */ + simdjson_inline array_iterator &operator++() noexcept; + +private: + value_iterator iter{}; + + simdjson_inline array_iterator(const value_iterator &iter) noexcept; + + friend class array; + friend class value; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::array_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + // + // Iterator interface + // + + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + simdjson_inline bool operator==(const simdjson_result &) const noexcept; + simdjson_inline bool operator!=(const simdjson_result &) const noexcept; + simdjson_inline simdjson_result &operator++() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H +/* end file simdjson/generic/ondemand/array_iterator.h for icelake */ +/* including simdjson/generic/ondemand/document.h for icelake: #include "simdjson/generic/ondemand/document.h" */ +/* begin file simdjson/generic/ondemand/document.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +/** + * A JSON document. It holds a json_iterator instance. + * + * Used by tokens to get text, and string buffer location. + * + * You must keep the document around during iteration. + */ +class document { +public: + /** + * Create a new invalid document. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline document() noexcept = default; + simdjson_inline document(const document &other) noexcept = delete; // pass your documents by reference, not by copy + simdjson_inline document(document &&other) noexcept = default; + simdjson_inline document &operator=(const document &other) noexcept = delete; + simdjson_inline document &operator=(document &&other) noexcept = default; + + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result get_array() & noexcept; + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @returns INCORRECT_TYPE If the JSON value is not an object. + */ + simdjson_inline simdjson_result get_object() & noexcept; + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64() noexcept; + /** + * Cast this JSON value (inside string) to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64() noexcept; + /** + * Cast this JSON value (inside string) to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64_in_string() noexcept; + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double() noexcept; + + /** + * Cast this JSON value (inside string) to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double_in_string() noexcept; + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: Calling get_string() twice on the same document is an error. + * + * @param Whether to allow a replacement character for unmatched surrogate pairs. + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + /** + * Attempts to fill the provided std::string reference with the parsed value of the current string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory. + * We recommend you avoid allocating an std::string unless you need to. + * + * @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS. + */ + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + /** + * Cast this JSON value to a string. + * + * The string is not guaranteed to be valid UTF-8. See https://simonsapin.github.io/wtf-8/ + * + * Important: Calling get_wobbly_string() twice on the same document is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_wobbly_string() noexcept; + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_raw_json_string() noexcept; + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @returns INCORRECT_TYPE if the JSON value is not true or false. + */ + simdjson_inline simdjson_result get_bool() noexcept; + /** + * Cast this JSON value to a value when the document is an object or an array. + * + * You must not have begun iterating through the object or array. When + * SIMDJSON_DEVELOPMENT_CHECKS is set to 1 (which is the case when building in Debug mode + * by default), and you have already begun iterating, + * you will get an OUT_OF_ORDER_ITERATION error. If you have begun iterating, you can use + * rewind() to reset the document to its initial state before calling this method. + * + * @returns A value if a JSON array or object cannot be found. + * @returns SCALAR_DOCUMENT_AS_VALUE error is the document is a scalar (see is_scalar() function). + */ + simdjson_inline simdjson_result get_value() noexcept; + + /** + * Checks if this JSON value is null. If and only if the value is + * null, then it is consumed (we advance). If we find a token that + * begins with 'n' but is not 'null', then an error is returned. + * + * @returns Whether the value is null. + * @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'. + */ + simdjson_inline simdjson_result is_null() noexcept; + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * You may use get_double(), get_bool(), get_uint64(), get_int64(), + * get_object(), get_array(), get_raw_json_string(), or get_string() instead. + * + * @returns A value of the given type, parsed from the JSON. + * @returns INCORRECT_TYPE If the JSON value is not the given type. + */ + template simdjson_inline simdjson_result get() & noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + /** @overload template simdjson_result get() & noexcept */ + template simdjson_inline simdjson_result get() && noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool, value + * + * Be mindful that the document instance must remain in scope while you are accessing object, array and value instances. + * + * @param out This is set to a value of the given type, parsed from the JSON. If there is an error, this may not be initialized. + * @returns INCORRECT_TYPE If the JSON value is not an object. + * @returns SUCCESS If the parse succeeded and the out parameter was set to the value. + */ + template simdjson_inline error_code get(T &out) & noexcept; + /** @overload template error_code get(T &out) & noexcept */ + template simdjson_inline error_code get(T &out) && noexcept; + +#if SIMDJSON_EXCEPTIONS + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an array. + */ + simdjson_inline operator array() & noexcept(false); + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an object. + */ + simdjson_inline operator object() & noexcept(false); + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline operator uint64_t() noexcept(false); + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer. + */ + simdjson_inline operator int64_t() noexcept(false); + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number. + */ + simdjson_inline operator double() noexcept(false); + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator std::string_view() noexcept(false); + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator raw_json_string() noexcept(false); + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false. + */ + simdjson_inline operator bool() noexcept(false); + /** + * Cast this JSON value to a value when the document is an object or an array. + * + * You must not have begun iterating through the object or array. When + * SIMDJSON_DEVELOPMENT_CHECKS is defined, and you have already begun iterating, + * you will get an OUT_OF_ORDER_ITERATION error. If you have begun iterating, you can use + * rewind() to reset the document to its initial state before calling this method. + * + * @returns A value value if a JSON array or object cannot be found. + * @exception SCALAR_DOCUMENT_AS_VALUE error is the document is a scalar (see is_scalar() function). + */ + simdjson_inline operator value() noexcept(false); +#endif + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Get the value at the given index in the array. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) & noexcept; + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result begin() & noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() & noexcept; + + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. E.g., the array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to + * a key a single time. Doing object["mykey"].to_string()and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. E.g., the array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a key + * a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + + /** + * Get the type of this JSON value. It does not validate or consume the value. + * E.g., you must still call "is_null()" to check that a value is null even if + * "type()" returns json_type::null. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + * + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() noexcept; + + /** + * Checks whether the document is a scalar (string, number, null, Boolean). + * Returns false when there it is an array or object. + * + * @returns true if the type is string, number, null, Boolean + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result is_scalar() noexcept; + + /** + * Checks whether the document is a negative number. + * + * @returns true if the number if negative. + */ + simdjson_inline bool is_negative() noexcept; + /** + * Checks whether the document is an integer number. Note that + * this requires to partially parse the number string. If + * the value is determined to be an integer, it may still + * not parse properly as an integer in subsequent steps + * (e.g., it might overflow). + * + * @returns true if the number if negative. + */ + simdjson_inline simdjson_result is_integer() noexcept; + /** + * Determine the number type (integer or floating-point number) as quickly + * as possible. This function does not fully validate the input. It is + * useful when you only need to classify the numbers, without parsing them. + * + * If you are planning to retrieve the value or you need full validation, + * consider using the get_number() method instead: it will fully parse + * and validate the input, and give you access to the type: + * get_number().get_number_type(). + * + * get_number_type() is number_type::unsigned_integer if we have + * an integer greater or equal to 9223372036854775808 + * get_number_type() is number_type::signed_integer if we have an + * integer that is less than 9223372036854775808 + * Otherwise, get_number_type() has value number_type::floating_point_number + * + * This function requires processing the number string, but it is expected + * to be faster than get_number().get_number_type() because it is does not + * parse the number value. + * + * @returns the type of the number + */ + simdjson_inline simdjson_result get_number_type() noexcept; + + /** + * Attempt to parse an ondemand::number. An ondemand::number may + * contain an integer value or a floating-point value, the simdjson + * library will autodetect the type. Thus it is a dynamically typed + * number. Before accessing the value, you must determine the detected + * type. + * + * number.get_number_type() is number_type::signed_integer if we have + * an integer in [-9223372036854775808,9223372036854775808) + * You can recover the value by calling number.get_int64() and you + * have that number.is_int64() is true. + * + * number.get_number_type() is number_type::unsigned_integer if we have + * an integer in [9223372036854775808,18446744073709551616) + * You can recover the value by calling number.get_uint64() and you + * have that number.is_uint64() is true. + * + * Otherwise, number.get_number_type() has value number_type::floating_point_number + * and we have a binary64 number. + * You can recover the value by calling number.get_double() and you + * have that number.is_double() is true. + * + * You must check the type before accessing the value: it is an error + * to call "get_int64()" when number.get_number_type() is not + * number_type::signed_integer and when number.is_int64() is false. + */ + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + /** + * Get the raw JSON for this token. + * + * The string_view will always point into the input buffer. + * + * The string_view will start at the beginning of the token, and include the entire token + * *as well as all spaces until the next token (or EOF).* This means, for example, that a + * string token always begins with a " and is always terminated by the final ", possibly + * followed by a number of spaces. + * + * The string_view is *not* null-terminated. If this is a scalar (string, number, + * boolean, or null), the character after the end of the string_view may be the padded buffer. + * + * Tokens include: + * - { + * - [ + * - "a string (possibly with UTF-8 or backslashed characters like \\\")". + * - -1.2e-100 + * - true + * - false + * - null + */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + /** + * Reset the iterator inside the document instance so we are pointing back at the + * beginning of the document, as if it had just been created. It invalidates all + * values, objects and arrays that you have created so far (including unescaped strings). + */ + inline void rewind() noexcept; + /** + * Returns debugging information. + */ + inline std::string to_debug_string() noexcept; + /** + * Some unrecoverable error conditions may render the document instance unusable. + * The is_alive() method returns true when the document is still suitable. + */ + inline bool is_alive() noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + inline simdjson_result current_location() const noexcept; + + /** + * Returns true if this document has been fully parsed. + * If you have consumed the whole document and at_end() returns + * false, then there may be trailing content. + */ + inline bool at_end() const noexcept; + + /** + * Returns the current depth in the document if in bounds. + * + * E.g., + * 0 = finished with document + * 1 = document root value (could be [ or {, not yet known) + * 2 = , or } inside root array/object + * 3 = key or value inside root array/object. + */ + simdjson_inline int32_t current_depth() const noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() automatically calls rewind between each call. Thus + * all values, objects and arrays that you have created so far (including unescaped strings) + * are invalidated. After calling at_pointer, you need to consume the result: string values + * should be stored in your own variables, arrays should be decoded and stored in your own array-like + * structures and so forth. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + * - SCALAR_DOCUMENT_AS_VALUE if the json_pointer is empty and the document is not a scalar (see is_scalar() function). + */ + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + /** + * Consumes the document and returns a string_view instance corresponding to the + * document as represented in JSON. It points inside the original byte array containing + * the JSON document. + */ + simdjson_inline simdjson_result raw_json() noexcept; +protected: + /** + * Consumes the document. + */ + simdjson_inline error_code consume() noexcept; + + simdjson_inline document(ondemand::json_iterator &&iter) noexcept; + simdjson_inline const uint8_t *text(uint32_t idx) const noexcept; + + simdjson_inline value_iterator resume_value_iterator() noexcept; + simdjson_inline value_iterator get_root_value_iterator() noexcept; + simdjson_inline simdjson_result start_or_resume_object() noexcept; + static simdjson_inline document start(ondemand::json_iterator &&iter) noexcept; + + // + // Fields + // + json_iterator iter{}; ///< Current position in the document + static constexpr depth_t DOCUMENT_DEPTH = 0; ///< document depth is always 0 + + friend class array_iterator; + friend class value; + friend class ondemand::parser; + friend class object; + friend class array; + friend class field; + friend class token; + friend class document_stream; + friend class document_reference; +}; + + +/** + * A document_reference is a thin wrapper around a document reference instance. + */ +class document_reference { +public: + simdjson_inline document_reference() noexcept; + simdjson_inline document_reference(document &d) noexcept; + simdjson_inline document_reference(const document_reference &other) noexcept = default; + simdjson_inline document_reference& operator=(const document_reference &other) noexcept = default; + simdjson_inline void rewind() noexcept; + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + + simdjson_inline simdjson_result is_null() noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + simdjson_inline operator document&() const noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator array() & noexcept(false); + simdjson_inline operator object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline int32_t current_depth() const noexcept; + simdjson_inline bool is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + simdjson_inline simdjson_result raw_json_token() noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +private: + document *doc{nullptr}; +}; +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::document &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline error_code rewind() noexcept; + + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + + template simdjson_inline simdjson_result get() & noexcept; + template simdjson_inline simdjson_result get() && noexcept; + + template simdjson_inline error_code get(T &out) & noexcept; + template simdjson_inline error_code get(T &out) && noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator icelake::ondemand::array() & noexcept(false); + simdjson_inline operator icelake::ondemand::object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator icelake::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator icelake::ondemand::value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline int32_t current_depth() const noexcept; + simdjson_inline bool at_end() const noexcept; + simdjson_inline bool is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + /** @copydoc simdjson_inline std::string_view document::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + + +} // namespace simdjson + + + +namespace simdjson { + +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::document_reference value, error_code error) noexcept; + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline error_code rewind() noexcept; + + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator icelake::ondemand::array() & noexcept(false); + simdjson_inline operator icelake::ondemand::object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator icelake::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator icelake::ondemand::value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline simdjson_result current_depth() const noexcept; + simdjson_inline simdjson_result is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + /** @copydoc simdjson_inline std::string_view document_reference::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H +/* end file simdjson/generic/ondemand/document.h for icelake */ +/* including simdjson/generic/ondemand/document_stream.h for icelake: #include "simdjson/generic/ondemand/document_stream.h" */ +/* begin file simdjson/generic/ondemand/document_stream.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#ifdef SIMDJSON_THREADS_ENABLED +#include +#include +#include +#endif + +namespace simdjson { +namespace icelake { +namespace ondemand { + +#ifdef SIMDJSON_THREADS_ENABLED +/** @private Custom worker class **/ +struct stage1_worker { + stage1_worker() noexcept = default; + stage1_worker(const stage1_worker&) = delete; + stage1_worker(stage1_worker&&) = delete; + stage1_worker operator=(const stage1_worker&) = delete; + ~stage1_worker(); + /** + * We only start the thread when it is needed, not at object construction, this may throw. + * You should only call this once. + **/ + void start_thread(); + /** + * Start a stage 1 job. You should first call 'run', then 'finish'. + * You must call start_thread once before. + */ + void run(document_stream * ds, parser * stage1, size_t next_batch_start); + /** Wait for the run to finish (blocking). You should first call 'run', then 'finish'. **/ + void finish(); + +private: + + /** + * Normally, we would never stop the thread. But we do in the destructor. + * This function is only safe assuming that you are not waiting for results. You + * should have called run, then finish, and be done. + **/ + void stop_thread(); + + std::thread thread{}; + /** These three variables define the work done by the thread. **/ + ondemand::parser * stage1_thread_parser{}; + size_t _next_batch_start{}; + document_stream * owner{}; + /** + * We have two state variables. This could be streamlined to one variable in the future but + * we use two for clarity. + */ + bool has_work{false}; + bool can_work{true}; + + /** + * We lock using a mutex. + */ + std::mutex locking_mutex{}; + std::condition_variable cond_var{}; + + friend class document_stream; +}; +#endif // SIMDJSON_THREADS_ENABLED + +/** + * A forward-only stream of documents. + * + * Produced by parser::iterate_many. + * + */ +class document_stream { +public: + /** + * Construct an uninitialized document_stream. + * + * ```c++ + * document_stream docs; + * auto error = parser.iterate_many(json).get(docs); + * ``` + */ + simdjson_inline document_stream() noexcept; + /** Move one document_stream to another. */ + simdjson_inline document_stream(document_stream &&other) noexcept = default; + /** Move one document_stream to another. */ + simdjson_inline document_stream &operator=(document_stream &&other) noexcept = default; + + simdjson_inline ~document_stream() noexcept; + + /** + * Returns the input size in bytes. + */ + inline size_t size_in_bytes() const noexcept; + + /** + * After iterating through the stream, this method + * returns the number of bytes that were not parsed at the end + * of the stream. If truncated_bytes() differs from zero, + * then the input was truncated maybe because incomplete JSON + * documents were found at the end of the stream. You + * may need to process the bytes in the interval [size_in_bytes()-truncated_bytes(), size_in_bytes()). + * + * You should only call truncated_bytes() after streaming through all + * documents, like so: + * + * document_stream stream = parser.iterate_many(json,window); + * for(auto & doc : stream) { + * // do something with doc + * } + * size_t truncated = stream.truncated_bytes(); + * + */ + inline size_t truncated_bytes() const noexcept; + + class iterator { + public: + using value_type = simdjson_result; + using reference = value_type; + + using difference_type = std::ptrdiff_t; + + using iterator_category = std::input_iterator_tag; + + /** + * Default constructor. + */ + simdjson_inline iterator() noexcept; + /** + * Get the current document (or error). + */ + simdjson_inline simdjson_result operator*() noexcept; + /** + * Advance to the next document (prefix). + */ + inline iterator& operator++() noexcept; + /** + * Check if we're at the end yet. + * @param other the end iterator to compare to. + */ + simdjson_inline bool operator!=(const iterator &other) const noexcept; + /** + * @private + * + * Gives the current index in the input document in bytes. + * + * document_stream stream = parser.parse_many(json,window); + * for(auto i = stream.begin(); i != stream.end(); ++i) { + * auto doc = *i; + * size_t index = i.current_index(); + * } + * + * This function (current_index()) is experimental and the usage + * may change in future versions of simdjson: we find the API somewhat + * awkward and we would like to offer something friendlier. + */ + simdjson_inline size_t current_index() const noexcept; + + /** + * @private + * + * Gives a view of the current document at the current position. + * + * document_stream stream = parser.iterate_many(json,window); + * for(auto i = stream.begin(); i != stream.end(); ++i) { + * std::string_view v = i.source(); + * } + * + * The returned string_view instance is simply a map to the (unparsed) + * source string: it may thus include white-space characters and all manner + * of padding. + * + * This function (source()) is experimental and the usage + * may change in future versions of simdjson: we find the API somewhat + * awkward and we would like to offer something friendlier. + * + */ + simdjson_inline std::string_view source() const noexcept; + + /** + * Returns error of the stream (if any). + */ + inline error_code error() const noexcept; + + private: + simdjson_inline iterator(document_stream *s, bool finished) noexcept; + /** The document_stream we're iterating through. */ + document_stream* stream; + /** Whether we're finished or not. */ + bool finished; + + friend class document; + friend class document_stream; + friend class json_iterator; + }; + + /** + * Start iterating the documents in the stream. + */ + simdjson_inline iterator begin() noexcept; + /** + * The end of the stream, for iterator comparison purposes. + */ + simdjson_inline iterator end() noexcept; + +private: + + document_stream &operator=(const document_stream &) = delete; // Disallow copying + document_stream(const document_stream &other) = delete; // Disallow copying + + /** + * Construct a document_stream. Does not allocate or parse anything until the iterator is + * used. + * + * @param parser is a reference to the parser instance used to generate this document_stream + * @param buf is the raw byte buffer we need to process + * @param len is the length of the raw byte buffer in bytes + * @param batch_size is the size of the windows (must be strictly greater or equal to the largest JSON document) + */ + simdjson_inline document_stream( + ondemand::parser &parser, + const uint8_t *buf, + size_t len, + size_t batch_size, + bool allow_comma_separated + ) noexcept; + + /** + * Parse the first document in the buffer. Used by begin(), to handle allocation and + * initialization. + */ + inline void start() noexcept; + + /** + * Parse the next document found in the buffer previously given to document_stream. + * + * The content should be a valid JSON document encoded as UTF-8. If there is a + * UTF-8 BOM, the parser skips it. + * + * You do NOT need to pre-allocate a parser. This function takes care of + * pre-allocating a capacity defined by the batch_size defined when creating the + * document_stream object. + * + * The function returns simdjson::EMPTY if there is no more data to be parsed. + * + * The function returns simdjson::SUCCESS (as integer = 0) in case of success + * and indicates that the buffer has successfully been parsed to the end. + * Every document it contained has been parsed without error. + * + * The function returns an error code from simdjson/simdjson.h in case of failure + * such as simdjson::CAPACITY, simdjson::MEMALLOC, simdjson::DEPTH_ERROR and so forth; + * the simdjson::error_message function converts these error codes into a string). + * + * You can also check validity by calling parser.is_valid(). The same parser can + * and should be reused for the other documents in the buffer. + */ + inline void next() noexcept; + + /** Move the json_iterator of the document to the location of the next document in the stream. */ + inline void next_document() noexcept; + + /** Get the next document index. */ + inline size_t next_batch_start() const noexcept; + + /** Pass the next batch through stage 1 with the given parser. */ + inline error_code run_stage1(ondemand::parser &p, size_t batch_start) noexcept; + + // Fields + ondemand::parser *parser; + const uint8_t *buf; + size_t len; + size_t batch_size; + bool allow_comma_separated; + /** + * We are going to use just one document instance. The document owns + * the json_iterator. It implies that we only ever pass a reference + * to the document to the users. + */ + document doc{}; + /** The error (or lack thereof) from the current document. */ + error_code error; + size_t batch_start{0}; + size_t doc_index{}; + + #ifdef SIMDJSON_THREADS_ENABLED + /** Indicates whether we use threads. Note that this needs to be a constant during the execution of the parsing. */ + bool use_thread; + + inline void load_from_stage1_thread() noexcept; + + /** Start a thread to run stage 1 on the next batch. */ + inline void start_stage1_thread() noexcept; + + /** Wait for the stage 1 thread to finish and capture the results. */ + inline void finish_stage1_thread() noexcept; + + /** The error returned from the stage 1 thread. */ + error_code stage1_thread_error{UNINITIALIZED}; + /** The thread used to run stage 1 against the next batch in the background. */ + std::unique_ptr worker{new(std::nothrow) stage1_worker()}; + /** + * The parser used to run stage 1 in the background. Will be swapped + * with the regular parser when finished. + */ + ondemand::parser stage1_thread_parser{}; + + friend struct stage1_worker; + #endif // SIMDJSON_THREADS_ENABLED + + friend class parser; + friend class document; + friend class json_iterator; + friend struct simdjson_result; + friend struct internal::simdjson_result_base; +}; // document_stream + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::document_stream &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H +/* end file simdjson/generic/ondemand/document_stream.h for icelake */ +/* including simdjson/generic/ondemand/field.h for icelake: #include "simdjson/generic/ondemand/field.h" */ +/* begin file simdjson/generic/ondemand/field.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_FIELD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_FIELD_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +/** + * A JSON field (key/value pair) in an object. + * + * Returned from object iteration. + * + * Extends from std::pair so you can use C++ algorithms that rely on pairs. + */ +class field : public std::pair { +public: + /** + * Create a new invalid field. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline field() noexcept; + + /** + * Get the key as a string_view (for higher speed, consider raw_key). + * We deliberately use a more cumbersome name (unescaped_key) to force users + * to think twice about using it. + * + * This consumes the key: once you have called unescaped_key(), you cannot + * call it again nor can you call key(). + */ + simdjson_inline simdjson_warn_unused simdjson_result unescaped_key(bool allow_replacement) noexcept; + /** + * Get the key as a raw_json_string. Can be used for direct comparison with + * an unescaped C string: e.g., key() == "test". + */ + simdjson_inline raw_json_string key() const noexcept; + /** + * Get the field value. + */ + simdjson_inline ondemand::value &value() & noexcept; + /** + * @overload ondemand::value &ondemand::value() & noexcept + */ + simdjson_inline ondemand::value value() && noexcept; + +protected: + simdjson_inline field(raw_json_string key, ondemand::value &&value) noexcept; + static simdjson_inline simdjson_result start(value_iterator &parent_iter) noexcept; + static simdjson_inline simdjson_result start(const value_iterator &parent_iter, raw_json_string key) noexcept; + friend struct simdjson_result; + friend class object_iterator; +}; + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::field &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result unescaped_key(bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result key() noexcept; + simdjson_inline simdjson_result value() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_FIELD_H +/* end file simdjson/generic/ondemand/field.h for icelake */ +/* including simdjson/generic/ondemand/object.h for icelake: #include "simdjson/generic/ondemand/object.h" */ +/* begin file simdjson/generic/ondemand/object.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +/** + * A forward-only JSON object field iterator. + */ +class object { +public: + /** + * Create a new invalid object. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline object() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. The value instance you get + * from `content["bids"]` becomes invalid when you call `content["asks"]`. The array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a + * key a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field(std::string_view key) && noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. The value instance you get + * from `content["bids"]` becomes invalid when you call `content["asks"]`. The array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a key + * a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) && noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) && noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard, interpreting the current node + * as the root of its own JSON document. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. Yet it is not the case when calling at_pointer on an object + * instance: there is no rewind and no invalidation. + * + * You may call at_pointer more than once on an object, but each time the pointer is advanced + * to be within the value matched by the key indicated by the JSON pointer query. Thus any preceding + * key (as well as the current key) can no longer be used with following JSON pointer calls. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching. + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + + /** + * Reset the iterator so that we are pointing back at the + * beginning of the object. You should still consume values only once even if you + * can iterate through the object more than once. If you unescape a string within + * the object more than once, you have unsafe code. Note that rewinding an object + * means that you may need to reparse it anew: it is not a free operation. + * + * @returns true if the object contains some elements (not empty) + */ + inline simdjson_result reset() & noexcept; + /** + * This method scans the beginning of the object and checks whether the + * object is empty. + * The runtime complexity is constant time. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + inline simdjson_result is_empty() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method. + * + * Performance hint: You should only call count_fields() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Consumes the object and returns a string_view instance corresponding to the + * object as represented in JSON. It points inside the original byte array containing + * the JSON document. + */ + simdjson_inline simdjson_result raw_json() noexcept; + +protected: + /** + * Go to the end of the object, no matter where you are right now. + */ + simdjson_inline error_code consume() noexcept; + static simdjson_inline simdjson_result start(value_iterator &iter) noexcept; + static simdjson_inline simdjson_result start_root(value_iterator &iter) noexcept; + static simdjson_inline simdjson_result started(value_iterator &iter) noexcept; + static simdjson_inline object resume(const value_iterator &iter) noexcept; + simdjson_inline object(const value_iterator &iter) noexcept; + + simdjson_warn_unused simdjson_inline error_code find_field_raw(const std::string_view key) noexcept; + + value_iterator iter{}; + + friend class value; + friend class document; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::object &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) && noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) && noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) && noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + inline simdjson_result reset() noexcept; + inline simdjson_result is_empty() noexcept; + inline simdjson_result count_fields() & noexcept; + inline simdjson_result raw_json() noexcept; + +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_H +/* end file simdjson/generic/ondemand/object.h for icelake */ +/* including simdjson/generic/ondemand/object_iterator.h for icelake: #include "simdjson/generic/ondemand/object_iterator.h" */ +/* begin file simdjson/generic/ondemand/object_iterator.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +class object_iterator { +public: + /** + * Create a new invalid object_iterator. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline object_iterator() noexcept = default; + + // + // Iterator interface + // + + // Reads key and value, yielding them to the user. + // MUST ONLY BE CALLED ONCE PER ITERATION. + simdjson_inline simdjson_result operator*() noexcept; + // Assumes it's being compared with the end. true if depth < iter->depth. + simdjson_inline bool operator==(const object_iterator &) const noexcept; + // Assumes it's being compared with the end. true if depth >= iter->depth. + simdjson_inline bool operator!=(const object_iterator &) const noexcept; + // Checks for ']' and ',' + simdjson_inline object_iterator &operator++() noexcept; + +private: + /** + * The underlying JSON iterator. + * + * PERF NOTE: expected to be elided in favor of the parent document: this is set when the object + * is first used, and never changes afterwards. + */ + value_iterator iter{}; + + simdjson_inline object_iterator(const value_iterator &iter) noexcept; + friend struct simdjson_result; + friend class object; +}; + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public icelake::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(icelake::ondemand::object_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + // + // Iterator interface + // + + // Reads key and value, yielding them to the user. + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + // Assumes it's being compared with the end. true if depth < iter->depth. + simdjson_inline bool operator==(const simdjson_result &) const noexcept; + // Assumes it's being compared with the end. true if depth >= iter->depth. + simdjson_inline bool operator!=(const simdjson_result &) const noexcept; + // Checks for ']' and ',' + simdjson_inline simdjson_result &operator++() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H +/* end file simdjson/generic/ondemand/object_iterator.h for icelake */ +/* including simdjson/generic/ondemand/serialization.h for icelake: #include "simdjson/generic/ondemand/serialization.h" */ +/* begin file simdjson/generic/ondemand/serialization.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Create a string-view instance out of a document instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(icelake::ondemand::document& x) noexcept; +/** + * Create a string-view instance out of a value instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. The value must + * not have been accessed previously. It does not + * validate the content. + */ +inline simdjson_result to_json_string(icelake::ondemand::value& x) noexcept; +/** + * Create a string-view instance out of an object instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(icelake::ondemand::object& x) noexcept; +/** + * Create a string-view instance out of an array instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(icelake::ondemand::array& x) noexcept; +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +} // namespace simdjson + +/** + * We want to support argument-dependent lookup (ADL). + * Hence we should define operator<< in the namespace + * where the argument (here value, object, etc.) resides. + * Credit: @madhur4127 + * See https://github.com/simdjson/simdjson/issues/1768 + */ +namespace simdjson { namespace icelake { namespace ondemand { + +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The element. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::icelake::ondemand::value x); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The array. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::icelake::ondemand::array value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The array. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::icelake::ondemand::document& value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x); +#endif +inline std::ostream& operator<<(std::ostream& out, simdjson::icelake::ondemand::document_reference& value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The object. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::icelake::ondemand::object value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +}}} // namespace simdjson::icelake::ondemand + +#endif // SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H +/* end file simdjson/generic/ondemand/serialization.h for icelake */ + +// Inline definitions +/* including simdjson/generic/ondemand/array-inl.h for icelake: #include "simdjson/generic/ondemand/array-inl.h" */ +/* begin file simdjson/generic/ondemand/array-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +// +// ### Live States +// +// While iterating or looking up values, depth >= iter->depth. at_start may vary. Error is +// always SUCCESS: +// +// - Start: This is the state when the array is first found and the iterator is just past the `{`. +// In this state, at_start == true. +// - Next: After we hand a scalar value to the user, or an array/object which they then fully +// iterate over, the iterator is at the `,` before the next value (or `]`). In this state, +// depth == iter->depth, at_start == false, and error == SUCCESS. +// - Unfinished Business: When we hand an array/object to the user which they do not fully +// iterate over, we need to finish that iteration by skipping child values until we reach the +// Next state. In this state, depth > iter->depth, at_start == false, and error == SUCCESS. +// +// ## Error States +// +// In error states, we will yield exactly one more value before stopping. iter->depth == depth +// and at_start is always false. We decrement after yielding the error, moving to the Finished +// state. +// +// - Chained Error: When the array iterator is part of an error chain--for example, in +// `for (auto tweet : doc["tweets"])`, where the tweet element may be missing or not be an +// array--we yield that error in the loop, exactly once. In this state, error != SUCCESS and +// iter->depth == depth, and at_start == false. We decrement depth when we yield the error. +// - Missing Comma Error: When the iterator ++ method discovers there is no comma between elements, +// we flag that as an error and treat it exactly the same as a Chained Error. In this state, +// error == TAPE_ERROR, iter->depth == depth, and at_start == false. +// +// ## Terminal State +// +// The terminal state has iter->depth < depth. at_start is always false. +// +// - Finished: When we have reached a `]` or have reported an error, we are finished. We signal this +// by decrementing depth. In this state, iter->depth < depth, at_start == false, and +// error == SUCCESS. +// + +simdjson_inline array::array(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} + +simdjson_inline simdjson_result array::start(value_iterator &iter) noexcept { + // We don't need to know if the array is empty to start iteration, but we do want to know if there + // is an error--thus `simdjson_unused`. + simdjson_unused bool has_value; + SIMDJSON_TRY( iter.start_array().get(has_value) ); + return array(iter); +} +simdjson_inline simdjson_result array::start_root(value_iterator &iter) noexcept { + simdjson_unused bool has_value; + SIMDJSON_TRY( iter.start_root_array().get(has_value) ); + return array(iter); +} +simdjson_inline simdjson_result array::started(value_iterator &iter) noexcept { + bool has_value; + SIMDJSON_TRY(iter.started_array().get(has_value)); + return array(iter); +} + +simdjson_inline simdjson_result array::begin() noexcept { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + return array_iterator(iter); +} +simdjson_inline simdjson_result array::end() noexcept { + return array_iterator(iter); +} +simdjson_inline error_code array::consume() noexcept { + auto error = iter.json_iter().skip_child(iter.depth()-1); + if(error) { iter.abandon(); } + return error; +} + +simdjson_inline simdjson_result array::raw_json() noexcept { + const uint8_t * starting_point{iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + // After 'consume()', we could be left pointing just beyond the document, but that + // is ok because we are not going to dereference the final pointer position, we just + // use it to compute the length in bytes. + const uint8_t * final_point{iter._json_iter->unsafe_pointer()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline simdjson_result array::count_elements() & noexcept { + size_t count{0}; + // Important: we do not consume any of the values. + for(simdjson_unused auto v : *this) { count++; } + // The above loop will always succeed, but we want to report errors. + if(iter.error()) { return iter.error(); } + // We need to move back at the start because we expect users to iterate through + // the array after counting the number of elements. + iter.reset_array(); + return count; +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline simdjson_result array::is_empty() & noexcept { + bool is_not_empty; + auto error = iter.reset_array().get(is_not_empty); + if(error) { return error; } + return !is_not_empty; +} + +inline simdjson_result array::reset() & noexcept { + return iter.reset_array(); +} + +inline simdjson_result array::at_pointer(std::string_view json_pointer) noexcept { + if (json_pointer[0] != '/') { return INVALID_JSON_POINTER; } + json_pointer = json_pointer.substr(1); + // - 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; } + + // Read the array index + size_t array_index = 0; + size_t i; + for (i = 0; i < json_pointer.length() && json_pointer[i] != '/'; i++) { + uint8_t digit = uint8_t(json_pointer[i] - '0'); + // Check for non-digit in array index. If it's there, we're trying to get a field in an object + if (digit > 9) { return INCORRECT_TYPE; } + array_index = array_index*10 + digit; + } + + // 0 followed by other digits is invalid + if (i > 1 && json_pointer[0] == '0') { return INVALID_JSON_POINTER; } // "JSON pointer array index has other characters after 0" + + // Empty string is invalid; so is a "/" with no digits before it + if (i == 0) { return INVALID_JSON_POINTER; } // "Empty string in JSON pointer array index" + // Get the child + auto child = at(array_index); + // If there is an error, it ends here + if(child.error()) { + return child; + } + + // If there is a /, we're not done yet, call recursively. + if (i < json_pointer.length()) { + child = child.at_pointer(json_pointer.substr(i)); + } + return child; +} + +simdjson_inline simdjson_result array::at(size_t index) noexcept { + size_t i = 0; + for (auto value : *this) { + if (i == index) { return value; } + i++; + } + return INDEX_OUT_OF_BOUNDS; +} + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + icelake::ondemand::array &&value +) noexcept + : implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept + : implementation_simdjson_result_base(error) +{ +} + +simdjson_inline simdjson_result simdjson_result::begin() noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() noexcept { + if (error()) { return error(); } + return first.end(); +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::is_empty() & noexcept { + if (error()) { return error(); } + return first.is_empty(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H +/* end file simdjson/generic/ondemand/array-inl.h for icelake */ +/* including simdjson/generic/ondemand/array_iterator-inl.h for icelake: #include "simdjson/generic/ondemand/array_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/array_iterator-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +simdjson_inline array_iterator::array_iterator(const value_iterator &_iter) noexcept + : iter{_iter} +{} + +simdjson_inline simdjson_result array_iterator::operator*() noexcept { + if (iter.error()) { iter.abandon(); return iter.error(); } + return value(iter.child()); +} +simdjson_inline bool array_iterator::operator==(const array_iterator &other) const noexcept { + return !(*this != other); +} +simdjson_inline bool array_iterator::operator!=(const array_iterator &) const noexcept { + return iter.is_open(); +} +simdjson_inline array_iterator &array_iterator::operator++() noexcept { + error_code error; + // PERF NOTE this is a safety rail ... users should exit loops as soon as they receive an error, so we'll never get here. + // However, it does not seem to make a perf difference, so we add it out of an abundance of caution. + if (( error = iter.error() )) { return *this; } + if (( error = iter.skip_child() )) { return *this; } + if (( error = iter.has_next_element().error() )) { return *this; } + return *this; +} + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + icelake::ondemand::array_iterator &&value +) noexcept + : icelake::implementation_simdjson_result_base(std::forward(value)) +{ + first.iter.assert_is_valid(); +} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : icelake::implementation_simdjson_result_base({}, error) +{ +} + +simdjson_inline simdjson_result simdjson_result::operator*() noexcept { + if (error()) { return error(); } + return *first; +} +simdjson_inline bool simdjson_result::operator==(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return !error(); } + return first == other.first; +} +simdjson_inline bool simdjson_result::operator!=(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return error(); } + return first != other.first; +} +simdjson_inline simdjson_result &simdjson_result::operator++() noexcept { + // Clear the error if there is one, so we don't yield it twice + if (error()) { second = SUCCESS; return *this; } + ++(first); + return *this; +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/array_iterator-inl.h for icelake */ +/* including simdjson/generic/ondemand/document-inl.h for icelake: #include "simdjson/generic/ondemand/document-inl.h" */ +/* begin file simdjson/generic/ondemand/document-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +simdjson_inline document::document(ondemand::json_iterator &&_iter) noexcept + : iter{std::forward(_iter)} +{ + logger::log_start_value(iter, "document"); +} + +simdjson_inline document document::start(json_iterator &&iter) noexcept { + return document(std::forward(iter)); +} + +inline void document::rewind() noexcept { + iter.rewind(); +} + +inline std::string document::to_debug_string() noexcept { + return iter.to_string(); +} + +inline simdjson_result document::current_location() const noexcept { + return iter.current_location(); +} + +inline int32_t document::current_depth() const noexcept { + return iter.depth(); +} + +inline bool document::at_end() const noexcept { + return iter.at_end(); +} + + +inline bool document::is_alive() noexcept { + return iter.is_alive(); +} +simdjson_inline value_iterator document::resume_value_iterator() noexcept { + return value_iterator(&iter, 1, iter.root_position()); +} +simdjson_inline value_iterator document::get_root_value_iterator() noexcept { + return resume_value_iterator(); +} +simdjson_inline simdjson_result document::start_or_resume_object() noexcept { + if (iter.at_root()) { + return get_object(); + } else { + return object::resume(resume_value_iterator()); + } +} +simdjson_inline simdjson_result document::get_value() noexcept { + // Make sure we start any arrays or objects before returning, so that start_root_() + // gets called. + + // It is the convention throughout the code that the macro `SIMDJSON_DEVELOPMENT_CHECKS` determines whether + // we check for OUT_OF_ORDER_ITERATION. Proper on::demand code should never trigger this error. +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.at_root()) { return OUT_OF_ORDER_ITERATION; } +#endif + // assert_at_root() serves two purposes: in Debug mode, whether or not + // SIMDJSON_DEVELOPMENT_CHECKS is set or not, it checks that we are at the root of + // the document (this will typically be redundant). In release mode, it generates + // SIMDJSON_ASSUME statements to allow the compiler to make assumptions. + iter.assert_at_root(); + switch (*iter.peek()) { + case '[': { + // The following lines check that the document ends with ]. + auto value_iterator = get_root_value_iterator(); + auto error = value_iterator.check_root_array(); + if(error) { return error; } + return value(get_root_value_iterator()); + } + case '{': { + // The following lines would check that the document ends with }. + auto value_iterator = get_root_value_iterator(); + auto error = value_iterator.check_root_object(); + if(error) { return error; } + return value(get_root_value_iterator()); + } + default: + // Unfortunately, scalar documents are a special case in simdjson and they cannot + // be safely converted to value instances. + return SCALAR_DOCUMENT_AS_VALUE; + } +} +simdjson_inline simdjson_result document::get_array() & noexcept { + auto value = get_root_value_iterator(); + return array::start_root(value); +} +simdjson_inline simdjson_result document::get_object() & noexcept { + auto value = get_root_value_iterator(); + return object::start_root(value); +} + +/** + * We decided that calling 'get_double()' on the JSON document '1.233 blabla' should + * give an error, so we check for trailing content. We want to disallow trailing + * content. + * Thus, in several implementations below, we pass a 'true' parameter value to + * a get_root_value_iterator() method: this indicates that we disallow trailing content. + */ + +simdjson_inline simdjson_result document::get_uint64() noexcept { + return get_root_value_iterator().get_root_uint64(true); +} +simdjson_inline simdjson_result document::get_uint64_in_string() noexcept { + return get_root_value_iterator().get_root_uint64_in_string(true); +} +simdjson_inline simdjson_result document::get_int64() noexcept { + return get_root_value_iterator().get_root_int64(true); +} +simdjson_inline simdjson_result document::get_int64_in_string() noexcept { + return get_root_value_iterator().get_root_int64_in_string(true); +} +simdjson_inline simdjson_result document::get_double() noexcept { + return get_root_value_iterator().get_root_double(true); +} +simdjson_inline simdjson_result document::get_double_in_string() noexcept { + return get_root_value_iterator().get_root_double_in_string(true); +} +simdjson_inline simdjson_result document::get_string(bool allow_replacement) noexcept { + return get_root_value_iterator().get_root_string(true, allow_replacement); +} +template +simdjson_inline error_code document::get_string(string_type& receiver, bool allow_replacement) noexcept { + return get_root_value_iterator().get_root_string(receiver, true, allow_replacement); +} +simdjson_inline simdjson_result document::get_wobbly_string() noexcept { + return get_root_value_iterator().get_root_wobbly_string(true); +} +simdjson_inline simdjson_result document::get_raw_json_string() noexcept { + return get_root_value_iterator().get_root_raw_json_string(true); +} +simdjson_inline simdjson_result document::get_bool() noexcept { + return get_root_value_iterator().get_root_bool(true); +} +simdjson_inline simdjson_result document::is_null() noexcept { + return get_root_value_iterator().is_root_null(true); +} + +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_array(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_object(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_double(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_uint64(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_int64(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_bool(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_value(); } + +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_double(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_uint64(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_int64(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_bool(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_value(); } + +template simdjson_inline error_code document::get(T &out) & noexcept { + return get().get(out); +} +template simdjson_inline error_code document::get(T &out) && noexcept { + return std::forward(*this).get().get(out); +} + +#if SIMDJSON_EXCEPTIONS +simdjson_inline document::operator array() & noexcept(false) { return get_array(); } +simdjson_inline document::operator object() & noexcept(false) { return get_object(); } +simdjson_inline document::operator uint64_t() noexcept(false) { return get_uint64(); } +simdjson_inline document::operator int64_t() noexcept(false) { return get_int64(); } +simdjson_inline document::operator double() noexcept(false) { return get_double(); } +simdjson_inline document::operator std::string_view() noexcept(false) { return get_string(false); } +simdjson_inline document::operator raw_json_string() noexcept(false) { return get_raw_json_string(); } +simdjson_inline document::operator bool() noexcept(false) { return get_bool(); } +simdjson_inline document::operator value() noexcept(false) { return get_value(); } + +#endif +simdjson_inline simdjson_result document::count_elements() & noexcept { + auto a = get_array(); + simdjson_result answer = a.count_elements(); + /* If there was an array, we are now left pointing at its first element. */ + if(answer.error() == SUCCESS) { rewind(); } + return answer; +} +simdjson_inline simdjson_result document::count_fields() & noexcept { + auto a = get_object(); + simdjson_result answer = a.count_fields(); + /* If there was an object, we are now left pointing at its first element. */ + if(answer.error() == SUCCESS) { rewind(); } + return answer; +} +simdjson_inline simdjson_result document::at(size_t index) & noexcept { + auto a = get_array(); + return a.at(index); +} +simdjson_inline simdjson_result document::begin() & noexcept { + return get_array().begin(); +} +simdjson_inline simdjson_result document::end() & noexcept { + return {}; +} + +simdjson_inline simdjson_result document::find_field(std::string_view key) & noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result document::find_field(const char *key) & noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result document::find_field_unordered(std::string_view key) & noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result document::find_field_unordered(const char *key) & noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result document::operator[](std::string_view key) & noexcept { + return start_or_resume_object()[key]; +} +simdjson_inline simdjson_result document::operator[](const char *key) & noexcept { + return start_or_resume_object()[key]; +} + +simdjson_inline error_code document::consume() noexcept { + auto error = iter.skip_child(0); + if(error) { iter.abandon(); } + return error; +} + +simdjson_inline simdjson_result document::raw_json() noexcept { + auto _iter = get_root_value_iterator(); + const uint8_t * starting_point{_iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + // After 'consume()', we could be left pointing just beyond the document, but that + // is ok because we are not going to dereference the final pointer position, we just + // use it to compute the length in bytes. + const uint8_t * final_point{iter.unsafe_pointer()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +simdjson_inline simdjson_result document::type() noexcept { + return get_root_value_iterator().type(); +} + +simdjson_inline simdjson_result document::is_scalar() noexcept { + json_type this_type; + auto error = type().get(this_type); + if(error) { return error; } + return ! ((this_type == json_type::array) || (this_type == json_type::object)); +} + +simdjson_inline bool document::is_negative() noexcept { + return get_root_value_iterator().is_root_negative(); +} + +simdjson_inline simdjson_result document::is_integer() noexcept { + return get_root_value_iterator().is_root_integer(true); +} + +simdjson_inline simdjson_result document::get_number_type() noexcept { + return get_root_value_iterator().get_root_number_type(true); +} + +simdjson_inline simdjson_result document::get_number() noexcept { + return get_root_value_iterator().get_root_number(true); +} + + +simdjson_inline simdjson_result document::raw_json_token() noexcept { + auto _iter = get_root_value_iterator(); + return std::string_view(reinterpret_cast(_iter.peek_start()), _iter.peek_start_length()); +} + +simdjson_inline simdjson_result document::at_pointer(std::string_view json_pointer) noexcept { + rewind(); // Rewind the document each time at_pointer is called + if (json_pointer.empty()) { + return this->get_value(); + } + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: + return (*this).get_array().at_pointer(json_pointer); + case json_type::object: + return (*this).get_object().at_pointer(json_pointer); + default: + return INVALID_JSON_POINTER; + } +} + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + icelake::ondemand::document &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base( + error + ) +{ +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) & noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline error_code simdjson_result::rewind() noexcept { + if (error()) { return error(); } + first.rewind(); + return SUCCESS; +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::get_array() & noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() & noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::get_value() noexcept { + if (error()) { return error(); } + return first.get_value(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} + +template +simdjson_inline simdjson_result simdjson_result::get() & noexcept { + if (error()) { return error(); } + return first.get(); +} +template +simdjson_inline simdjson_result simdjson_result::get() && noexcept { + if (error()) { return error(); } + return std::forward(first).get(); +} +template +simdjson_inline error_code simdjson_result::get(T &out) & noexcept { + if (error()) { return error(); } + return first.get(out); +} +template +simdjson_inline error_code simdjson_result::get(T &out) && noexcept { + if (error()) { return error(); } + return std::forward(first).get(out); +} + +template<> simdjson_inline simdjson_result simdjson_result::get() & noexcept = delete; +template<> simdjson_inline simdjson_result simdjson_result::get() && noexcept { + if (error()) { return error(); } + return std::forward(first); +} +template<> simdjson_inline error_code simdjson_result::get(icelake::ondemand::document &out) & noexcept = delete; +template<> simdjson_inline error_code simdjson_result::get(icelake::ondemand::document &out) && noexcept { + if (error()) { return error(); } + out = std::forward(first); + return SUCCESS; +} + +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} + +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} + + +simdjson_inline bool simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} + +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} + +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} + +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} + + +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator icelake::ondemand::array() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator icelake::ondemand::object() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator icelake::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator icelake::ondemand::value() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline bool simdjson_result::at_end() const noexcept { + if (error()) { return error(); } + return first.at_end(); +} + + +simdjson_inline int32_t simdjson_result::current_depth() const noexcept { + if (error()) { return error(); } + return first.current_depth(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + + +} // namespace simdjson + + +namespace simdjson { +namespace icelake { +namespace ondemand { + +simdjson_inline document_reference::document_reference() noexcept : doc{nullptr} {} +simdjson_inline document_reference::document_reference(document &d) noexcept : doc(&d) {} +simdjson_inline void document_reference::rewind() noexcept { doc->rewind(); } +simdjson_inline simdjson_result document_reference::get_array() & noexcept { return doc->get_array(); } +simdjson_inline simdjson_result document_reference::get_object() & noexcept { return doc->get_object(); } +/** + * The document_reference instances are used primarily/solely for streams of JSON + * documents. + * We decided that calling 'get_double()' on the JSON document '1.233 blabla' should + * give an error, so we check for trailing content. + * + * However, for streams of JSON documents, we want to be able to start from + * "321" "321" "321" + * and parse it successfully as a stream of JSON documents, calling get_uint64_in_string() + * successfully each time. + * + * To achieve this result, we pass a 'false' to a get_root_value_iterator() method: + * this indicates that we allow trailing content. + */ +simdjson_inline simdjson_result document_reference::get_uint64() noexcept { return doc->get_root_value_iterator().get_root_uint64(false); } +simdjson_inline simdjson_result document_reference::get_uint64_in_string() noexcept { return doc->get_root_value_iterator().get_root_uint64_in_string(false); } +simdjson_inline simdjson_result document_reference::get_int64() noexcept { return doc->get_root_value_iterator().get_root_int64(false); } +simdjson_inline simdjson_result document_reference::get_int64_in_string() noexcept { return doc->get_root_value_iterator().get_root_int64_in_string(false); } +simdjson_inline simdjson_result document_reference::get_double() noexcept { return doc->get_root_value_iterator().get_root_double(false); } +simdjson_inline simdjson_result document_reference::get_double_in_string() noexcept { return doc->get_root_value_iterator().get_root_double(false); } +simdjson_inline simdjson_result document_reference::get_string(bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(false, allow_replacement); } +template +simdjson_inline error_code document_reference::get_string(string_type& receiver, bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(receiver, false, allow_replacement); } +simdjson_inline simdjson_result document_reference::get_wobbly_string() noexcept { return doc->get_root_value_iterator().get_root_wobbly_string(false); } +simdjson_inline simdjson_result document_reference::get_raw_json_string() noexcept { return doc->get_root_value_iterator().get_root_raw_json_string(false); } +simdjson_inline simdjson_result document_reference::get_bool() noexcept { return doc->get_root_value_iterator().get_root_bool(false); } +simdjson_inline simdjson_result document_reference::get_value() noexcept { return doc->get_value(); } +simdjson_inline simdjson_result document_reference::is_null() noexcept { return doc->get_root_value_iterator().is_root_null(false); } + +#if SIMDJSON_EXCEPTIONS +simdjson_inline document_reference::operator array() & noexcept(false) { return array(*doc); } +simdjson_inline document_reference::operator object() & noexcept(false) { return object(*doc); } +simdjson_inline document_reference::operator uint64_t() noexcept(false) { return get_uint64(); } +simdjson_inline document_reference::operator int64_t() noexcept(false) { return get_int64(); } +simdjson_inline document_reference::operator double() noexcept(false) { return get_double(); } +simdjson_inline document_reference::operator std::string_view() noexcept(false) { return std::string_view(*doc); } +simdjson_inline document_reference::operator raw_json_string() noexcept(false) { return raw_json_string(*doc); } +simdjson_inline document_reference::operator bool() noexcept(false) { return get_bool(); } +simdjson_inline document_reference::operator value() noexcept(false) { return value(*doc); } +#endif +simdjson_inline simdjson_result document_reference::count_elements() & noexcept { return doc->count_elements(); } +simdjson_inline simdjson_result document_reference::count_fields() & noexcept { return doc->count_fields(); } +simdjson_inline simdjson_result document_reference::at(size_t index) & noexcept { return doc->at(index); } +simdjson_inline simdjson_result document_reference::begin() & noexcept { return doc->begin(); } +simdjson_inline simdjson_result document_reference::end() & noexcept { return doc->end(); } +simdjson_inline simdjson_result document_reference::find_field(std::string_view key) & noexcept { return doc->find_field(key); } +simdjson_inline simdjson_result document_reference::find_field(const char *key) & noexcept { return doc->find_field(key); } +simdjson_inline simdjson_result document_reference::operator[](std::string_view key) & noexcept { return (*doc)[key]; } +simdjson_inline simdjson_result document_reference::operator[](const char *key) & noexcept { return (*doc)[key]; } +simdjson_inline simdjson_result document_reference::find_field_unordered(std::string_view key) & noexcept { return doc->find_field_unordered(key); } +simdjson_inline simdjson_result document_reference::find_field_unordered(const char *key) & noexcept { return doc->find_field_unordered(key); } +simdjson_inline simdjson_result document_reference::type() noexcept { return doc->type(); } +simdjson_inline simdjson_result document_reference::is_scalar() noexcept { return doc->is_scalar(); } +simdjson_inline simdjson_result document_reference::current_location() noexcept { return doc->current_location(); } +simdjson_inline int32_t document_reference::current_depth() const noexcept { return doc->current_depth(); } +simdjson_inline bool document_reference::is_negative() noexcept { return doc->is_negative(); } +simdjson_inline simdjson_result document_reference::is_integer() noexcept { return doc->get_root_value_iterator().is_root_integer(false); } +simdjson_inline simdjson_result document_reference::get_number_type() noexcept { return doc->get_root_value_iterator().get_root_number_type(false); } +simdjson_inline simdjson_result document_reference::get_number() noexcept { return doc->get_root_value_iterator().get_root_number(false); } +simdjson_inline simdjson_result document_reference::raw_json_token() noexcept { return doc->raw_json_token(); } +simdjson_inline simdjson_result document_reference::at_pointer(std::string_view json_pointer) noexcept { return doc->at_pointer(json_pointer); } +simdjson_inline simdjson_result document_reference::raw_json() noexcept { return doc->raw_json();} +simdjson_inline document_reference::operator document&() const noexcept { return *doc; } + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + + + +namespace simdjson { +simdjson_inline simdjson_result::simdjson_result(icelake::ondemand::document_reference value, error_code error) + noexcept : implementation_simdjson_result_base(std::forward(value), error) {} + + +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) & noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline error_code simdjson_result::rewind() noexcept { + if (error()) { return error(); } + first.rewind(); + return SUCCESS; +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::get_array() & noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() & noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::get_value() noexcept { + if (error()) { return error(); } + return first.get_value(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} +simdjson_inline simdjson_result simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator icelake::ondemand::array() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator icelake::ondemand::object() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator icelake::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator icelake::ondemand::value() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H +/* end file simdjson/generic/ondemand/document-inl.h for icelake */ +/* including simdjson/generic/ondemand/document_stream-inl.h for icelake: #include "simdjson/generic/ondemand/document_stream-inl.h" */ +/* begin file simdjson/generic/ondemand/document_stream-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document_stream.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include + +namespace simdjson { +namespace icelake { +namespace ondemand { + +#ifdef SIMDJSON_THREADS_ENABLED + +inline void stage1_worker::finish() { + // After calling "run" someone would call finish() to wait + // for the end of the processing. + // This function will wait until either the thread has done + // the processing or, else, the destructor has been called. + std::unique_lock lock(locking_mutex); + cond_var.wait(lock, [this]{return has_work == false;}); +} + +inline stage1_worker::~stage1_worker() { + // The thread may never outlive the stage1_worker instance + // and will always be stopped/joined before the stage1_worker + // instance is gone. + stop_thread(); +} + +inline void stage1_worker::start_thread() { + std::unique_lock lock(locking_mutex); + if(thread.joinable()) { + return; // This should never happen but we never want to create more than one thread. + } + thread = std::thread([this]{ + while(true) { + std::unique_lock thread_lock(locking_mutex); + // We wait for either "run" or "stop_thread" to be called. + cond_var.wait(thread_lock, [this]{return has_work || !can_work;}); + // If, for some reason, the stop_thread() method was called (i.e., the + // destructor of stage1_worker is called, then we want to immediately destroy + // the thread (and not do any more processing). + if(!can_work) { + break; + } + this->owner->stage1_thread_error = this->owner->run_stage1(*this->stage1_thread_parser, + this->_next_batch_start); + this->has_work = false; + // The condition variable call should be moved after thread_lock.unlock() for performance + // reasons but thread sanitizers may report it as a data race if we do. + // See https://stackoverflow.com/questions/35775501/c-should-condition-variable-be-notified-under-lock + cond_var.notify_one(); // will notify "finish" + thread_lock.unlock(); + } + } + ); +} + + +inline void stage1_worker::stop_thread() { + std::unique_lock lock(locking_mutex); + // We have to make sure that all locks can be released. + can_work = false; + has_work = false; + cond_var.notify_all(); + lock.unlock(); + if(thread.joinable()) { + thread.join(); + } +} + +inline void stage1_worker::run(document_stream * ds, parser * stage1, size_t next_batch_start) { + std::unique_lock lock(locking_mutex); + owner = ds; + _next_batch_start = next_batch_start; + stage1_thread_parser = stage1; + has_work = true; + // The condition variable call should be moved after thread_lock.unlock() for performance + // reasons but thread sanitizers may report it as a data race if we do. + // See https://stackoverflow.com/questions/35775501/c-should-condition-variable-be-notified-under-lock + cond_var.notify_one(); // will notify the thread lock that we have work + lock.unlock(); +} + +#endif // SIMDJSON_THREADS_ENABLED + +simdjson_inline document_stream::document_stream( + ondemand::parser &_parser, + const uint8_t *_buf, + size_t _len, + size_t _batch_size, + bool _allow_comma_separated +) noexcept + : parser{&_parser}, + buf{_buf}, + len{_len}, + batch_size{_batch_size <= MINIMAL_BATCH_SIZE ? MINIMAL_BATCH_SIZE : _batch_size}, + allow_comma_separated{_allow_comma_separated}, + error{SUCCESS} + #ifdef SIMDJSON_THREADS_ENABLED + , use_thread(_parser.threaded) // we need to make a copy because _parser.threaded can change + #endif +{ +#ifdef SIMDJSON_THREADS_ENABLED + if(worker.get() == nullptr) { + error = MEMALLOC; + } +#endif +} + +simdjson_inline document_stream::document_stream() noexcept + : parser{nullptr}, + buf{nullptr}, + len{0}, + batch_size{0}, + allow_comma_separated{false}, + error{UNINITIALIZED} + #ifdef SIMDJSON_THREADS_ENABLED + , use_thread(false) + #endif +{ +} + +simdjson_inline document_stream::~document_stream() noexcept +{ + #ifdef SIMDJSON_THREADS_ENABLED + worker.reset(); + #endif +} + +inline size_t document_stream::size_in_bytes() const noexcept { + return len; +} + +inline size_t document_stream::truncated_bytes() const noexcept { + if(error == CAPACITY) { return len - batch_start; } + return parser->implementation->structural_indexes[parser->implementation->n_structural_indexes] - parser->implementation->structural_indexes[parser->implementation->n_structural_indexes + 1]; +} + +simdjson_inline document_stream::iterator::iterator() noexcept + : stream{nullptr}, finished{true} { +} + +simdjson_inline document_stream::iterator::iterator(document_stream* _stream, bool is_end) noexcept + : stream{_stream}, finished{is_end} { +} + +simdjson_inline simdjson_result document_stream::iterator::operator*() noexcept { + //if(stream->error) { return stream->error; } + return simdjson_result(stream->doc, stream->error); +} + +simdjson_inline document_stream::iterator& document_stream::iterator::operator++() noexcept { + // If there is an error, then we want the iterator + // to be finished, no matter what. (E.g., we do not + // keep generating documents with errors, or go beyond + // a document with errors.) + // + // Users do not have to call "operator*()" when they use operator++, + // so we need to end the stream in the operator++ function. + // + // Note that setting finished = true is essential otherwise + // we would enter an infinite loop. + if (stream->error) { finished = true; } + // Note that stream->error() is guarded against error conditions + // (it will immediately return if stream->error casts to false). + // In effect, this next function does nothing when (stream->error) + // is true (hence the risk of an infinite loop). + stream->next(); + // If that was the last document, we're finished. + // It is the only type of error we do not want to appear + // in operator*. + if (stream->error == EMPTY) { finished = true; } + // If we had any other kind of error (not EMPTY) then we want + // to pass it along to the operator* and we cannot mark the result + // as "finished" just yet. + return *this; +} + +simdjson_inline bool document_stream::iterator::operator!=(const document_stream::iterator &other) const noexcept { + return finished != other.finished; +} + +simdjson_inline document_stream::iterator document_stream::begin() noexcept { + start(); + // If there are no documents, we're finished. + return iterator(this, error == EMPTY); +} + +simdjson_inline document_stream::iterator document_stream::end() noexcept { + return iterator(this, true); +} + +inline void document_stream::start() noexcept { + if (error) { return; } + error = parser->allocate(batch_size); + if (error) { return; } + // Always run the first stage 1 parse immediately + batch_start = 0; + error = run_stage1(*parser, batch_start); + while(error == EMPTY) { + // In exceptional cases, we may start with an empty block + batch_start = next_batch_start(); + if (batch_start >= len) { return; } + error = run_stage1(*parser, batch_start); + } + if (error) { return; } + doc_index = batch_start; + doc = document(json_iterator(&buf[batch_start], parser)); + doc.iter._streaming = true; + + #ifdef SIMDJSON_THREADS_ENABLED + if (use_thread && next_batch_start() < len) { + // Kick off the first thread on next batch if needed + error = stage1_thread_parser.allocate(batch_size); + if (error) { return; } + worker->start_thread(); + start_stage1_thread(); + if (error) { return; } + } + #endif // SIMDJSON_THREADS_ENABLED +} + +inline void document_stream::next() noexcept { + // We always enter at once once in an error condition. + if (error) { return; } + next_document(); + if (error) { return; } + auto cur_struct_index = doc.iter._root - parser->implementation->structural_indexes.get(); + doc_index = batch_start + parser->implementation->structural_indexes[cur_struct_index]; + + // Check if at end of structural indexes (i.e. at end of batch) + if(cur_struct_index >= static_cast(parser->implementation->n_structural_indexes)) { + error = EMPTY; + // Load another batch (if available) + while (error == EMPTY) { + batch_start = next_batch_start(); + if (batch_start >= len) { break; } + #ifdef SIMDJSON_THREADS_ENABLED + if(use_thread) { + load_from_stage1_thread(); + } else { + error = run_stage1(*parser, batch_start); + } + #else + error = run_stage1(*parser, batch_start); + #endif + /** + * Whenever we move to another window, we need to update all pointers to make + * it appear as if the input buffer started at the beginning of the window. + * + * Take this input: + * + * {"z":5} {"1":1,"2":2,"4":4} [7, 10, 9] [15, 11, 12, 13] [154, 110, 112, 1311] + * + * Say you process the following window... + * + * '{"z":5} {"1":1,"2":2,"4":4} [7, 10, 9]' + * + * When you do so, the json_iterator has a pointer at the beginning of the memory region + * (pointing at the beginning of '{"z"...'. + * + * When you move to the window that starts at... + * + * '[7, 10, 9] [15, 11, 12, 13] ... + * + * then it is not sufficient to just run stage 1. You also need to re-anchor the + * json_iterator so that it believes we are starting at '[7, 10, 9]...'. + * + * Under the DOM front-end, this gets done automatically because the parser owns + * the pointer the data, and when you call stage1 and then stage2 on the same + * parser, then stage2 will run on the pointer acquired by stage1. + * + * That is, stage1 calls "this->buf = _buf" so the parser remembers the buffer that + * we used. But json_iterator has no callback when stage1 is called on the parser. + * In fact, I think that the parser is unaware of json_iterator. + * + * + * So we need to re-anchor the json_iterator after each call to stage 1 so that + * all of the pointers are in sync. + */ + doc.iter = json_iterator(&buf[batch_start], parser); + doc.iter._streaming = true; + /** + * End of resync. + */ + + if (error) { continue; } // If the error was EMPTY, we may want to load another batch. + doc_index = batch_start; + } + } +} + +inline void document_stream::next_document() noexcept { + // Go to next place where depth=0 (document depth) + error = doc.iter.skip_child(0); + if (error) { return; } + // Always set depth=1 at the start of document + doc.iter._depth = 1; + // consume comma if comma separated is allowed + if (allow_comma_separated) { doc.iter.consume_character(','); } + // Resets the string buffer at the beginning, thus invalidating the strings. + doc.iter._string_buf_loc = parser->string_buf.get(); + doc.iter._root = doc.iter.position(); +} + +inline size_t document_stream::next_batch_start() const noexcept { + return batch_start + parser->implementation->structural_indexes[parser->implementation->n_structural_indexes]; +} + +inline error_code document_stream::run_stage1(ondemand::parser &p, size_t _batch_start) noexcept { + // This code only updates the structural index in the parser, it does not update any json_iterator + // instance. + size_t remaining = len - _batch_start; + if (remaining <= batch_size) { + return p.implementation->stage1(&buf[_batch_start], remaining, stage1_mode::streaming_final); + } else { + return p.implementation->stage1(&buf[_batch_start], batch_size, stage1_mode::streaming_partial); + } +} + +simdjson_inline size_t document_stream::iterator::current_index() const noexcept { + return stream->doc_index; +} + +simdjson_inline std::string_view document_stream::iterator::source() const noexcept { + auto depth = stream->doc.iter.depth(); + auto cur_struct_index = stream->doc.iter._root - stream->parser->implementation->structural_indexes.get(); + + // If at root, process the first token to determine if scalar value + if (stream->doc.iter.at_root()) { + switch (stream->buf[stream->batch_start + stream->parser->implementation->structural_indexes[cur_struct_index]]) { + case '{': case '[': // Depth=1 already at start of document + break; + case '}': case ']': + depth--; + break; + default: // Scalar value document + // TODO: Remove any trailing whitespaces + // This returns a string spanning from start of value to the beginning of the next document (excluded) + return std::string_view(reinterpret_cast(stream->buf) + current_index(), stream->parser->implementation->structural_indexes[++cur_struct_index] - current_index() - 1); + } + cur_struct_index++; + } + + while (cur_struct_index <= static_cast(stream->parser->implementation->n_structural_indexes)) { + switch (stream->buf[stream->batch_start + stream->parser->implementation->structural_indexes[cur_struct_index]]) { + case '{': case '[': + depth++; + break; + case '}': case ']': + depth--; + break; + } + if (depth == 0) { break; } + cur_struct_index++; + } + + return std::string_view(reinterpret_cast(stream->buf) + current_index(), stream->parser->implementation->structural_indexes[cur_struct_index] - current_index() + stream->batch_start + 1);; +} + +inline error_code document_stream::iterator::error() const noexcept { + return stream->error; +} + +#ifdef SIMDJSON_THREADS_ENABLED + +inline void document_stream::load_from_stage1_thread() noexcept { + worker->finish(); + // Swap to the parser that was loaded up in the thread. Make sure the parser has + // enough memory to swap to, as well. + std::swap(stage1_thread_parser,*parser); + error = stage1_thread_error; + if (error) { return; } + + // If there's anything left, start the stage 1 thread! + if (next_batch_start() < len) { + start_stage1_thread(); + } +} + +inline void document_stream::start_stage1_thread() noexcept { + // we call the thread on a lambda that will update + // this->stage1_thread_error + // there is only one thread that may write to this value + // TODO this is NOT exception-safe. + this->stage1_thread_error = UNINITIALIZED; // In case something goes wrong, make sure it's an error + size_t _next_batch_start = this->next_batch_start(); + + worker->run(this, & this->stage1_thread_parser, _next_batch_start); +} + +#endif // SIMDJSON_THREADS_ENABLED + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} +simdjson_inline simdjson_result::simdjson_result( + icelake::ondemand::document_stream &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} + +} + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H +/* end file simdjson/generic/ondemand/document_stream-inl.h for icelake */ +/* including simdjson/generic/ondemand/field-inl.h for icelake: #include "simdjson/generic/ondemand/field-inl.h" */ +/* begin file simdjson/generic/ondemand/field-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +// clang 6 doesn't think the default constructor can be noexcept, so we make it explicit +simdjson_inline field::field() noexcept : std::pair() {} + +simdjson_inline field::field(raw_json_string key, ondemand::value &&value) noexcept + : std::pair(key, std::forward(value)) +{ +} + +simdjson_inline simdjson_result field::start(value_iterator &parent_iter) noexcept { + raw_json_string key; + SIMDJSON_TRY( parent_iter.field_key().get(key) ); + SIMDJSON_TRY( parent_iter.field_value() ); + return field::start(parent_iter, key); +} + +simdjson_inline simdjson_result field::start(const value_iterator &parent_iter, raw_json_string key) noexcept { + return field(key, parent_iter.child()); +} + +simdjson_inline simdjson_warn_unused simdjson_result field::unescaped_key(bool allow_replacement) noexcept { + SIMDJSON_ASSUME(first.buf != nullptr); // We would like to call .alive() but Visual Studio won't let us. + simdjson_result answer = first.unescape(second.iter.json_iter(), allow_replacement); + first.consume(); + return answer; +} + +simdjson_inline raw_json_string field::key() const noexcept { + SIMDJSON_ASSUME(first.buf != nullptr); // We would like to call .alive() by Visual Studio won't let us. + return first; +} + +simdjson_inline value &field::value() & noexcept { + return second; +} + +simdjson_inline value field::value() && noexcept { + return std::forward(*this).second; +} + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + icelake::ondemand::field &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} + +simdjson_inline simdjson_result simdjson_result::key() noexcept { + if (error()) { return error(); } + return first.key(); +} +simdjson_inline simdjson_result simdjson_result::unescaped_key(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.unescaped_key(allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::value() noexcept { + if (error()) { return error(); } + return std::move(first.value()); +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H +/* end file simdjson/generic/ondemand/field-inl.h for icelake */ +/* including simdjson/generic/ondemand/json_iterator-inl.h for icelake: #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/json_iterator-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +simdjson_inline json_iterator::json_iterator(json_iterator &&other) noexcept + : token(std::forward(other.token)), + parser{other.parser}, + _string_buf_loc{other._string_buf_loc}, + error{other.error}, + _depth{other._depth}, + _root{other._root}, + _streaming{other._streaming} +{ + other.parser = nullptr; +} +simdjson_inline json_iterator &json_iterator::operator=(json_iterator &&other) noexcept { + token = other.token; + parser = other.parser; + _string_buf_loc = other._string_buf_loc; + error = other.error; + _depth = other._depth; + _root = other._root; + _streaming = other._streaming; + other.parser = nullptr; + return *this; +} + +simdjson_inline json_iterator::json_iterator(const uint8_t *buf, ondemand::parser *_parser) noexcept + : token(buf, &_parser->implementation->structural_indexes[0]), + parser{_parser}, + _string_buf_loc{parser->string_buf.get()}, + _depth{1}, + _root{parser->implementation->structural_indexes.get()}, + _streaming{false} + +{ + logger::log_headers(); +#if SIMDJSON_CHECK_EOF + assert_more_tokens(); +#endif +} + +inline void json_iterator::rewind() noexcept { + token.set_position( root_position() ); + logger::log_headers(); // We start again + _string_buf_loc = parser->string_buf.get(); + _depth = 1; +} + +inline bool json_iterator::balanced() const noexcept { + token_iterator ti(token); + int32_t count{0}; + ti.set_position( root_position() ); + while(ti.peek() <= peek_last()) { + switch (*ti.return_current_and_advance()) + { + case '[': case '{': + count++; + break; + case ']': case '}': + count--; + break; + default: + break; + } + } + return count == 0; +} + + +// GCC 7 warns when the first line of this function is inlined away into oblivion due to the caller +// relating depth and parent_depth, which is a desired effect. The warning does not show up if the +// skip_child() function is not marked inline). +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_warn_unused simdjson_inline error_code json_iterator::skip_child(depth_t parent_depth) noexcept { + if (depth() <= parent_depth) { return SUCCESS; } + switch (*return_current_and_advance()) { + // TODO consider whether matching braces is a requirement: if non-matching braces indicates + // *missing* braces, then future lookups are not in the object/arrays they think they are, + // violating the rule "validate enough structure that the user can be confident they are + // looking at the right values." + // PERF TODO we can eliminate the switch here with a lookup of how much to add to depth + + // For the first open array/object in a value, we've already incremented depth, so keep it the same + // We never stop at colon, but if we did, it wouldn't affect depth + case '[': case '{': case ':': + logger::log_start_value(*this, "skip"); + break; + // If there is a comma, we have just finished a value in an array/object, and need to get back in + case ',': + logger::log_value(*this, "skip"); + break; + // ] or } means we just finished a value and need to jump out of the array/object + case ']': case '}': + logger::log_end_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } +#if SIMDJSON_CHECK_EOF + // If there are no more tokens, the parent is incomplete. + if (at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "Missing [ or { at start"); } +#endif // SIMDJSON_CHECK_EOF + break; + case '"': + if(*peek() == ':') { + // We are at a key!!! + // This might happen if you just started an object and you skip it immediately. + // Performance note: it would be nice to get rid of this check as it is somewhat + // expensive. + // https://github.com/simdjson/simdjson/issues/1742 + logger::log_value(*this, "key"); + return_current_and_advance(); // eat up the ':' + break; // important!!! + } + simdjson_fallthrough; + // Anything else must be a scalar value + default: + // For the first scalar, we will have incremented depth already, so we decrement it here. + logger::log_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } + break; + } + + // Now that we've considered the first value, we only increment/decrement for arrays/objects + while (position() < end_position()) { + switch (*return_current_and_advance()) { + case '[': case '{': + logger::log_start_value(*this, "skip"); + _depth++; + break; + // TODO consider whether matching braces is a requirement: if non-matching braces indicates + // *missing* braces, then future lookups are not in the object/arrays they think they are, + // violating the rule "validate enough structure that the user can be confident they are + // looking at the right values." + // PERF TODO we can eliminate the switch here with a lookup of how much to add to depth + case ']': case '}': + logger::log_end_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } + break; + default: + logger::log_value(*this, "skip", ""); + break; + } + } + + return report_error(TAPE_ERROR, "not enough close braces"); +} + +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline bool json_iterator::at_root() const noexcept { + return position() == root_position(); +} + +simdjson_inline bool json_iterator::is_single_token() const noexcept { + return parser->implementation->n_structural_indexes == 1; +} + +simdjson_inline bool json_iterator::streaming() const noexcept { + return _streaming; +} + +simdjson_inline token_position json_iterator::root_position() const noexcept { + return _root; +} + +simdjson_inline void json_iterator::assert_at_document_depth() const noexcept { + SIMDJSON_ASSUME( _depth == 1 ); +} + +simdjson_inline void json_iterator::assert_at_root() const noexcept { + SIMDJSON_ASSUME( _depth == 1 ); +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + // Under Visual Studio, the next SIMDJSON_ASSUME fails with: the argument + // has side effects that will be discarded. + SIMDJSON_ASSUME( token.position() == _root ); +#endif +} + +simdjson_inline void json_iterator::assert_more_tokens(uint32_t required_tokens) const noexcept { + assert_valid_position(token._position + required_tokens - 1); +} + +simdjson_inline void json_iterator::assert_valid_position(token_position position) const noexcept { +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + SIMDJSON_ASSUME( position >= &parser->implementation->structural_indexes[0] ); + SIMDJSON_ASSUME( position < &parser->implementation->structural_indexes[parser->implementation->n_structural_indexes] ); +#endif +} + +simdjson_inline bool json_iterator::at_end() const noexcept { + return position() == end_position(); +} +simdjson_inline token_position json_iterator::end_position() const noexcept { + uint32_t n_structural_indexes{parser->implementation->n_structural_indexes}; + return &parser->implementation->structural_indexes[n_structural_indexes]; +} + +inline std::string json_iterator::to_string() const noexcept { + if( !is_alive() ) { return "dead json_iterator instance"; } + const char * current_structural = reinterpret_cast(token.peek()); + return std::string("json_iterator [ depth : ") + std::to_string(_depth) + + std::string(", structural : '") + std::string(current_structural,1) + + std::string("', offset : ") + std::to_string(token.current_offset()) + + std::string("', error : ") + error_message(error) + + std::string(" ]"); +} + +inline simdjson_result json_iterator::current_location() const noexcept { + if (!is_alive()) { // Unrecoverable error + if (!at_root()) { + return reinterpret_cast(token.peek(-1)); + } else { + return reinterpret_cast(token.peek()); + } + } + if (at_end()) { + return OUT_OF_BOUNDS; + } + return reinterpret_cast(token.peek()); +} + +simdjson_inline bool json_iterator::is_alive() const noexcept { + return parser; +} + +simdjson_inline void json_iterator::abandon() noexcept { + parser = nullptr; + _depth = 0; +} + +simdjson_inline const uint8_t *json_iterator::return_current_and_advance() noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(); +#endif // SIMDJSON_CHECK_EOF + return token.return_current_and_advance(); +} + +simdjson_inline const uint8_t *json_iterator::unsafe_pointer() const noexcept { + // deliberately done without safety guard: + return token.peek(); +} + +simdjson_inline const uint8_t *json_iterator::peek(int32_t delta) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(delta+1); +#endif // SIMDJSON_CHECK_EOF + return token.peek(delta); +} + +simdjson_inline uint32_t json_iterator::peek_length(int32_t delta) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(delta+1); +#endif // #if SIMDJSON_CHECK_EOF + return token.peek_length(delta); +} + +simdjson_inline const uint8_t *json_iterator::peek(token_position position) const noexcept { + // todo: currently we require end-of-string buffering, but the following + // assert_valid_position should be turned on if/when we lift that condition. + // assert_valid_position(position); + // This is almost surely related to SIMDJSON_CHECK_EOF but given that SIMDJSON_CHECK_EOF + // is ON by default, we have no choice but to disable it for real with a comment. + return token.peek(position); +} + +simdjson_inline uint32_t json_iterator::peek_length(token_position position) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_valid_position(position); +#endif // SIMDJSON_CHECK_EOF + return token.peek_length(position); +} + +simdjson_inline token_position json_iterator::last_position() const noexcept { + // The following line fails under some compilers... + // SIMDJSON_ASSUME(parser->implementation->n_structural_indexes > 0); + // since it has side-effects. + uint32_t n_structural_indexes{parser->implementation->n_structural_indexes}; + SIMDJSON_ASSUME(n_structural_indexes > 0); + return &parser->implementation->structural_indexes[n_structural_indexes - 1]; +} +simdjson_inline const uint8_t *json_iterator::peek_last() const noexcept { + return token.peek(last_position()); +} + +simdjson_inline void json_iterator::ascend_to(depth_t parent_depth) noexcept { + SIMDJSON_ASSUME(parent_depth >= 0 && parent_depth < INT32_MAX - 1); + SIMDJSON_ASSUME(_depth == parent_depth + 1); + _depth = parent_depth; +} + +simdjson_inline void json_iterator::descend_to(depth_t child_depth) noexcept { + SIMDJSON_ASSUME(child_depth >= 1 && child_depth < INT32_MAX); + SIMDJSON_ASSUME(_depth == child_depth - 1); + _depth = child_depth; +} + +simdjson_inline depth_t json_iterator::depth() const noexcept { + return _depth; +} + +simdjson_inline uint8_t *&json_iterator::string_buf_loc() noexcept { + return _string_buf_loc; +} + +simdjson_inline error_code json_iterator::report_error(error_code _error, const char *message) noexcept { + SIMDJSON_ASSUME(_error != SUCCESS && _error != UNINITIALIZED && _error != INCORRECT_TYPE && _error != NO_SUCH_FIELD); + logger::log_error(*this, message); + error = _error; + return error; +} + +simdjson_inline token_position json_iterator::position() const noexcept { + return token.position(); +} + +simdjson_inline simdjson_result json_iterator::unescape(raw_json_string in, bool allow_replacement) noexcept { + return parser->unescape(in, _string_buf_loc, allow_replacement); +} + +simdjson_inline simdjson_result json_iterator::unescape_wobbly(raw_json_string in) noexcept { + return parser->unescape_wobbly(in, _string_buf_loc); +} + +simdjson_inline void json_iterator::reenter_child(token_position position, depth_t child_depth) noexcept { + SIMDJSON_ASSUME(child_depth >= 1 && child_depth < INT32_MAX); + SIMDJSON_ASSUME(_depth == child_depth - 1); +#if SIMDJSON_DEVELOPMENT_CHECKS +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + SIMDJSON_ASSUME(size_t(child_depth) < parser->max_depth()); + SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]); +#endif +#endif + token.set_position(position); + _depth = child_depth; +} + +simdjson_inline error_code json_iterator::consume_character(char c) noexcept { + if (*peek() == c) { + return_current_and_advance(); + return SUCCESS; + } + return TAPE_ERROR; +} + +#if SIMDJSON_DEVELOPMENT_CHECKS + +simdjson_inline token_position json_iterator::start_position(depth_t depth) const noexcept { + SIMDJSON_ASSUME(size_t(depth) < parser->max_depth()); + return size_t(depth) < parser->max_depth() ? parser->start_positions[depth] : 0; +} + +simdjson_inline void json_iterator::set_start_position(depth_t depth, token_position position) noexcept { + SIMDJSON_ASSUME(size_t(depth) < parser->max_depth()); + if(size_t(depth) < parser->max_depth()) { parser->start_positions[depth] = position; } +} + +#endif + + +simdjson_inline error_code json_iterator::optional_error(error_code _error, const char *message) noexcept { + SIMDJSON_ASSUME(_error == INCORRECT_TYPE || _error == NO_SUCH_FIELD); + logger::log_error(*this, message); + return _error; +} + + +simdjson_warn_unused simdjson_inline bool json_iterator::copy_to_buffer(const uint8_t *json, uint32_t max_len, uint8_t *tmpbuf, size_t N) noexcept { + // This function is not expected to be called in performance-sensitive settings. + // Let us guard against silly cases: + if((N < max_len) || (N == 0)) { return false; } + // Copy to the buffer. + std::memcpy(tmpbuf, json, max_len); + if(N > max_len) { // We pad whatever remains with ' '. + std::memset(tmpbuf + max_len, ' ', N - max_len); + } + return true; +} + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(icelake::ondemand::json_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/json_iterator-inl.h for icelake */ +/* including simdjson/generic/ondemand/json_type-inl.h for icelake: #include "simdjson/generic/ondemand/json_type-inl.h" */ +/* begin file simdjson/generic/ondemand/json_type-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +inline std::ostream& operator<<(std::ostream& out, json_type type) noexcept { + switch (type) { + case json_type::array: out << "array"; break; + case json_type::object: out << "object"; break; + case json_type::number: out << "number"; break; + case json_type::string: out << "string"; break; + case json_type::boolean: out << "boolean"; break; + case json_type::null: out << "null"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson_result &type) noexcept(false) { + return out << type.value(); +} +#endif + + + +simdjson_inline number_type number::get_number_type() const noexcept { + return type; +} + +simdjson_inline bool number::is_uint64() const noexcept { + return get_number_type() == number_type::unsigned_integer; +} + +simdjson_inline uint64_t number::get_uint64() const noexcept { + return payload.unsigned_integer; +} + +simdjson_inline number::operator uint64_t() const noexcept { + return get_uint64(); +} + + +simdjson_inline bool number::is_int64() const noexcept { + return get_number_type() == number_type::signed_integer; +} + +simdjson_inline int64_t number::get_int64() const noexcept { + return payload.signed_integer; +} + +simdjson_inline number::operator int64_t() const noexcept { + return get_int64(); +} + +simdjson_inline bool number::is_double() const noexcept { + return get_number_type() == number_type::floating_point_number; +} + +simdjson_inline double number::get_double() const noexcept { + return payload.floating_point_number; +} + +simdjson_inline number::operator double() const noexcept { + return get_double(); +} + +simdjson_inline double number::as_double() const noexcept { + if(is_double()) { + return payload.floating_point_number; + } + if(is_int64()) { + return double(payload.signed_integer); + } + return double(payload.unsigned_integer); +} + +simdjson_inline void number::append_s64(int64_t value) noexcept { + payload.signed_integer = value; + type = number_type::signed_integer; +} + +simdjson_inline void number::append_u64(uint64_t value) noexcept { + payload.unsigned_integer = value; + type = number_type::unsigned_integer; +} + +simdjson_inline void number::append_double(double value) noexcept { + payload.floating_point_number = value; + type = number_type::floating_point_number; +} + +simdjson_inline void number::skip_double() noexcept { + type = number_type::floating_point_number; +} + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(icelake::ondemand::json_type &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H +/* end file simdjson/generic/ondemand/json_type-inl.h for icelake */ +/* including simdjson/generic/ondemand/logger-inl.h for icelake: #include "simdjson/generic/ondemand/logger-inl.h" */ +/* begin file simdjson/generic/ondemand/logger-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include + +namespace simdjson { +namespace icelake { +namespace ondemand { +namespace logger { + +static constexpr const char * DASHES = "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"; +static constexpr const int LOG_EVENT_LEN = 20; +static constexpr const int LOG_BUFFER_LEN = 30; +static constexpr const int LOG_SMALL_BUFFER_LEN = 10; +static int log_depth = 0; // Not threadsafe. Log only. + +// Helper to turn unprintable or newline characters into spaces +static inline char printable_char(char c) { + if (c >= 0x20) { + return c; + } else { + return ' '; + } +} + +template +static inline std::string string_format(const std::string& format, const Args&... args) +{ + SIMDJSON_PUSH_DISABLE_ALL_WARNINGS + int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; + auto size = static_cast(size_s); + if (size <= 0) return std::string(); + std::unique_ptr buf(new char[size]); + std::snprintf(buf.get(), size, format.c_str(), args...); + SIMDJSON_POP_DISABLE_WARNINGS + return std::string(buf.get(), buf.get() + size - 1); +} + +static inline log_level get_log_level_from_env() +{ + SIMDJSON_PUSH_DISABLE_WARNINGS + SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe + char *lvl = getenv("SIMDJSON_LOG_LEVEL"); + SIMDJSON_POP_DISABLE_WARNINGS + if (lvl && simdjson_strcasecmp(lvl, "ERROR") == 0) { return log_level::error; } + return log_level::info; +} + +static inline log_level log_threshold() +{ + static log_level threshold = get_log_level_from_env(); + return threshold; +} + +static inline bool should_log(log_level level) +{ + return level >= log_threshold(); +} + +inline void log_event(const json_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_line(iter, "", type, detail, delta, depth_delta, log_level::info); +} + +inline void log_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail) noexcept { + log_line(iter, index, depth, "", type, detail, log_level::info); +} +inline void log_value(const json_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_line(iter, "", type, detail, delta, depth_delta, log_level::info); +} + +inline void log_start_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail) noexcept { + log_line(iter, index, depth, "+", type, detail, log_level::info); + if (LOG_ENABLED) { log_depth++; } +} +inline void log_start_value(const json_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_line(iter, "+", type, "", delta, depth_delta, log_level::info); + if (LOG_ENABLED) { log_depth++; } +} + +inline void log_end_value(const json_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + if (LOG_ENABLED) { log_depth--; } + log_line(iter, "-", type, "", delta, depth_delta, log_level::info); +} + +inline void log_error(const json_iterator &iter, const char *error, const char *detail, int delta, int depth_delta) noexcept { + log_line(iter, "ERROR: ", error, detail, delta, depth_delta, log_level::error); +} +inline void log_error(const json_iterator &iter, token_position index, depth_t depth, const char *error, const char *detail) noexcept { + log_line(iter, index, depth, "ERROR: ", error, detail, log_level::error); +} + +inline void log_event(const value_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_event(iter.json_iter(), type, detail, delta, depth_delta); +} + +inline void log_value(const value_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_value(iter.json_iter(), type, detail, delta, depth_delta); +} + +inline void log_start_value(const value_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_start_value(iter.json_iter(), type, delta, depth_delta); +} + +inline void log_end_value(const value_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_end_value(iter.json_iter(), type, delta, depth_delta); +} + +inline void log_error(const value_iterator &iter, const char *error, const char *detail, int delta, int depth_delta) noexcept { + log_error(iter.json_iter(), error, detail, delta, depth_delta); +} + +inline void log_headers() noexcept { + if (LOG_ENABLED) { + if (simdjson_unlikely(should_log(log_level::info))) { + // Technically a static variable is not thread-safe, but if you are using threads and logging... well... + static bool displayed_hint{false}; + log_depth = 0; + printf("\n"); + if (!displayed_hint) { + // We only print this helpful header once. + printf("# Logging provides the depth and position of the iterator user-visible steps:\n"); + printf("# +array says 'this is where we were when we discovered the start array'\n"); + printf( + "# -array says 'this is where we were when we ended the array'\n"); + printf("# skip says 'this is a structural or value I am skipping'\n"); + printf("# +/-skip says 'this is a start/end array or object I am skipping'\n"); + printf("#\n"); + printf("# The indentation of the terms (array, string,...) indicates the depth,\n"); + printf("# in addition to the depth being displayed.\n"); + printf("#\n"); + printf("# Every token in the document has a single depth determined by the tokens before it,\n"); + printf("# and is not affected by what the token actually is.\n"); + printf("#\n"); + printf("# Not all structural elements are presented as tokens in the logs.\n"); + printf("#\n"); + printf("# We never give control to the user within an empty array or an empty object.\n"); + printf("#\n"); + printf("# Inside an array, having a depth greater than the array's depth means that\n"); + printf("# we are pointing inside a value.\n"); + printf("# Having a depth equal to the array means that we are pointing right before a value.\n"); + printf("# Having a depth smaller than the array means that we have moved beyond the array.\n"); + displayed_hint = true; + } + printf("\n"); + printf("| %-*s ", LOG_EVENT_LEN, "Event"); + printf("| %-*s ", LOG_BUFFER_LEN, "Buffer"); + printf("| %-*s ", LOG_SMALL_BUFFER_LEN, "Next"); + // printf("| %-*s ", 5, "Next#"); + printf("| %-*s ", 5, "Depth"); + printf("| Detail "); + printf("|\n"); + + printf("|%.*s", LOG_EVENT_LEN + 2, DASHES); + printf("|%.*s", LOG_BUFFER_LEN + 2, DASHES); + printf("|%.*s", LOG_SMALL_BUFFER_LEN + 2, DASHES); + // printf("|%.*s", 5+2, DASHES); + printf("|%.*s", 5 + 2, DASHES); + printf("|--------"); + printf("|\n"); + fflush(stdout); + } + } +} + +template +inline void log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, log_level level, Args&&... args) noexcept { + log_line(iter, iter.position()+delta, depth_t(iter.depth()+depth_delta), title_prefix, title, detail, level, std::forward(args)...); +} + +template +inline void log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, log_level level, Args&&... args) noexcept { + if (LOG_ENABLED) { + if (simdjson_unlikely(should_log(level))) { + const int indent = depth * 2; + const auto buf = iter.token.buf; + auto msg = string_format(title, std::forward(args)...); + printf("| %*s%s%-*s ", indent, "", title_prefix, + LOG_EVENT_LEN - indent - int(strlen(title_prefix)), msg.c_str()); + { + // Print the current structural. + printf("| "); + // Before we begin, the index might point right before the document. + // This could be unsafe, see https://github.com/simdjson/simdjson/discussions/1938 + if (index < iter._root) { + printf("%*s", LOG_BUFFER_LEN, ""); + } else { + auto current_structural = &buf[*index]; + for (int i = 0; i < LOG_BUFFER_LEN; i++) { + printf("%c", printable_char(current_structural[i])); + } + } + printf(" "); + } + { + // Print the next structural. + printf("| "); + auto next_structural = &buf[*(index + 1)]; + for (int i = 0; i < LOG_SMALL_BUFFER_LEN; i++) { + printf("%c", printable_char(next_structural[i])); + } + printf(" "); + } + // printf("| %5u ", *(index+1)); + printf("| %5i ", depth); + printf("| %6.*s ", int(detail.size()), detail.data()); + printf("|\n"); + fflush(stdout); + } + } +} + +} // namespace logger +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H +/* end file simdjson/generic/ondemand/logger-inl.h for icelake */ +/* including simdjson/generic/ondemand/object-inl.h for icelake: #include "simdjson/generic/ondemand/object-inl.h" */ +/* begin file simdjson/generic/ondemand/object-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +simdjson_inline simdjson_result object::find_field_unordered(const std::string_view key) & noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::find_field_unordered(const std::string_view key) && noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::operator[](const std::string_view key) & noexcept { + return find_field_unordered(key); +} +simdjson_inline simdjson_result object::operator[](const std::string_view key) && noexcept { + return std::forward(*this).find_field_unordered(key); +} +simdjson_inline simdjson_result object::find_field(const std::string_view key) & noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::find_field(const std::string_view key) && noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} + +simdjson_inline simdjson_result object::start(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.start_object().error() ); + return object(iter); +} +simdjson_inline simdjson_result object::start_root(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.start_root_object().error() ); + return object(iter); +} +simdjson_inline error_code object::consume() noexcept { + if(iter.is_at_key()) { + /** + * whenever you are pointing at a key, calling skip_child() is + * unsafe because you will hit a string and you will assume that + * it is string value, and this mistake will lead you to make bad + * depth computation. + */ + /** + * We want to 'consume' the key. We could really + * just do _json_iter->return_current_and_advance(); at this + * point, but, for clarity, we will use the high-level API to + * eat the key. We assume that the compiler optimizes away + * most of the work. + */ + simdjson_unused raw_json_string actual_key; + auto error = iter.field_key().get(actual_key); + if (error) { iter.abandon(); return error; }; + // Let us move to the value while we are at it. + if ((error = iter.field_value())) { iter.abandon(); return error; } + } + auto error_skip = iter.json_iter().skip_child(iter.depth()-1); + if(error_skip) { iter.abandon(); } + return error_skip; +} + +simdjson_inline simdjson_result object::raw_json() noexcept { + const uint8_t * starting_point{iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + const uint8_t * final_point{iter._json_iter->peek()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +simdjson_inline simdjson_result object::started(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.started_object().error() ); + return object(iter); +} + +simdjson_inline object object::resume(const value_iterator &iter) noexcept { + return iter; +} + +simdjson_inline object::object(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} + +simdjson_inline simdjson_result object::begin() noexcept { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + return object_iterator(iter); +} +simdjson_inline simdjson_result object::end() noexcept { + return object_iterator(iter); +} + +inline simdjson_result object::at_pointer(std::string_view json_pointer) noexcept { + if (json_pointer[0] != '/') { return INVALID_JSON_POINTER; } + json_pointer = json_pointer.substr(1); + size_t slash = json_pointer.find('/'); + std::string_view key = json_pointer.substr(0, slash); + // Grab the child with the given key + simdjson_result child; + + // If there is an escape character in the key, unescape it and then get the child. + size_t escape = key.find('~'); + if (escape != std::string_view::npos) { + // Unescape the key + std::string unescaped(key); + do { + switch (unescaped[escape+1]) { + case '0': + unescaped.replace(escape, 2, "~"); + break; + case '1': + unescaped.replace(escape, 2, "/"); + break; + default: + return INVALID_JSON_POINTER; // "Unexpected ~ escape character in JSON pointer"); + } + escape = unescaped.find('~', escape+1); + } while (escape != std::string::npos); + child = find_field(unescaped); // Take note find_field does not unescape keys when matching + } else { + child = find_field(key); + } + if(child.error()) { + return child; // we do not continue if there was an error + } + // If there is a /, we have to recurse and look up more of the path + if (slash != std::string_view::npos) { + child = child.at_pointer(json_pointer.substr(slash)); + } + return child; +} + +simdjson_inline simdjson_result object::count_fields() & noexcept { + size_t count{0}; + // Important: we do not consume any of the values. + for(simdjson_unused auto v : *this) { count++; } + // The above loop will always succeed, but we want to report errors. + if(iter.error()) { return iter.error(); } + // We need to move back at the start because we expect users to iterate through + // the object after counting the number of elements. + iter.reset_object(); + return count; +} + +simdjson_inline simdjson_result object::is_empty() & noexcept { + bool is_not_empty; + auto error = iter.reset_object().get(is_not_empty); + if(error) { return error; } + return !is_not_empty; +} + +simdjson_inline simdjson_result object::reset() & noexcept { + return iter.reset_object(); +} + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(icelake::ondemand::object &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +simdjson_inline simdjson_result simdjson_result::begin() noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() noexcept { + if (error()) { return error(); } + return first.end(); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first).find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first)[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first).find_field(key); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + +inline simdjson_result simdjson_result::reset() noexcept { + if (error()) { return error(); } + return first.reset(); +} + +inline simdjson_result simdjson_result::is_empty() noexcept { + if (error()) { return error(); } + return first.is_empty(); +} + +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H +/* end file simdjson/generic/ondemand/object-inl.h for icelake */ +/* including simdjson/generic/ondemand/object_iterator-inl.h for icelake: #include "simdjson/generic/ondemand/object_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/object_iterator-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +// +// object_iterator +// + +simdjson_inline object_iterator::object_iterator(const value_iterator &_iter) noexcept + : iter{_iter} +{} + +simdjson_inline simdjson_result object_iterator::operator*() noexcept { + error_code error = iter.error(); + if (error) { iter.abandon(); return error; } + auto result = field::start(iter); + // TODO this is a safety rail ... users should exit loops as soon as they receive an error. + // Nonetheless, let's see if performance is OK with this if statement--the compiler may give it to us for free. + if (result.error()) { iter.abandon(); } + return result; +} +simdjson_inline bool object_iterator::operator==(const object_iterator &other) const noexcept { + return !(*this != other); +} +simdjson_inline bool object_iterator::operator!=(const object_iterator &) const noexcept { + return iter.is_open(); +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline object_iterator &object_iterator::operator++() noexcept { + // TODO this is a safety rail ... users should exit loops as soon as they receive an error. + // Nonetheless, let's see if performance is OK with this if statement--the compiler may give it to us for free. + if (!iter.is_open()) { return *this; } // Iterator will be released if there is an error + + simdjson_unused error_code error; + if ((error = iter.skip_child() )) { return *this; } + + simdjson_unused bool has_value; + if ((error = iter.has_next_field().get(has_value) )) { return *this; }; + return *this; +} +SIMDJSON_POP_DISABLE_WARNINGS + +// +// ### Live States +// +// While iterating or looking up values, depth >= iter.depth. at_start may vary. Error is +// always SUCCESS: +// +// - Start: This is the state when the object is first found and the iterator is just past the {. +// In this state, at_start == true. +// - Next: After we hand a scalar value to the user, or an array/object which they then fully +// iterate over, the iterator is at the , or } before the next value. In this state, +// depth == iter.depth, at_start == false, and error == SUCCESS. +// - Unfinished Business: When we hand an array/object to the user which they do not fully +// iterate over, we need to finish that iteration by skipping child values until we reach the +// Next state. In this state, depth > iter.depth, at_start == false, and error == SUCCESS. +// +// ## Error States +// +// In error states, we will yield exactly one more value before stopping. iter.depth == depth +// and at_start is always false. We decrement after yielding the error, moving to the Finished +// state. +// +// - Chained Error: When the object iterator is part of an error chain--for example, in +// `for (auto tweet : doc["tweets"])`, where the tweet field may be missing or not be an +// object--we yield that error in the loop, exactly once. In this state, error != SUCCESS and +// iter.depth == depth, and at_start == false. We decrement depth when we yield the error. +// - Missing Comma Error: When the iterator ++ method discovers there is no comma between fields, +// we flag that as an error and treat it exactly the same as a Chained Error. In this state, +// error == TAPE_ERROR, iter.depth == depth, and at_start == false. +// +// Errors that occur while reading a field to give to the user (such as when the key is not a +// string or the field is missing a colon) are yielded immediately. Depth is then decremented, +// moving to the Finished state without transitioning through an Error state at all. +// +// ## Terminal State +// +// The terminal state has iter.depth < depth. at_start is always false. +// +// - Finished: When we have reached a }, we are finished. We signal this by decrementing depth. +// In this state, iter.depth < depth, at_start == false, and error == SUCCESS. +// + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + icelake::ondemand::object_iterator &&value +) noexcept + : implementation_simdjson_result_base(std::forward(value)) +{ + first.iter.assert_is_valid(); +} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base({}, error) +{ +} + +simdjson_inline simdjson_result simdjson_result::operator*() noexcept { + if (error()) { return error(); } + return *first; +} +// If we're iterating and there is an error, return the error once. +simdjson_inline bool simdjson_result::operator==(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return !error(); } + return first == other.first; +} +// If we're iterating and there is an error, return the error once. +simdjson_inline bool simdjson_result::operator!=(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return error(); } + return first != other.first; +} +// Checks for ']' and ',' +simdjson_inline simdjson_result &simdjson_result::operator++() noexcept { + // Clear the error if there is one, so we don't yield it twice + if (error()) { second = SUCCESS; return *this; } + ++first; + return *this; +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/object_iterator-inl.h for icelake */ +/* including simdjson/generic/ondemand/parser-inl.h for icelake: #include "simdjson/generic/ondemand/parser-inl.h" */ +/* begin file simdjson/generic/ondemand/parser-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/padded_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/padded_string_view.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/dom/base.h" // for MINIMAL_DOCUMENT_CAPACITY */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document_stream.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +simdjson_inline parser::parser(size_t max_capacity) noexcept + : _max_capacity{max_capacity} { +} + +simdjson_warn_unused simdjson_inline error_code parser::allocate(size_t new_capacity, size_t new_max_depth) noexcept { + if (new_capacity > max_capacity()) { return CAPACITY; } + if (string_buf && new_capacity == capacity() && new_max_depth == max_depth()) { return SUCCESS; } + + // string_capacity copied from document::allocate + _capacity = 0; + size_t string_capacity = SIMDJSON_ROUNDUP_N(5 * new_capacity / 3 + SIMDJSON_PADDING, 64); + string_buf.reset(new (std::nothrow) uint8_t[string_capacity]); +#if SIMDJSON_DEVELOPMENT_CHECKS + start_positions.reset(new (std::nothrow) token_position[new_max_depth]); +#endif + if (implementation) { + SIMDJSON_TRY( implementation->set_capacity(new_capacity) ); + SIMDJSON_TRY( implementation->set_max_depth(new_max_depth) ); + } else { + SIMDJSON_TRY( simdjson::get_active_implementation()->create_dom_parser_implementation(new_capacity, new_max_depth, implementation) ); + } + _capacity = new_capacity; + _max_depth = new_max_depth; + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(padded_string_view json) & noexcept { + if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; } + + json.remove_utf8_bom(); + + // Allocate if needed + if (capacity() < json.length() || !string_buf) { + SIMDJSON_TRY( allocate(json.length(), max_depth()) ); + } + + // Run stage 1. + SIMDJSON_TRY( implementation->stage1(reinterpret_cast(json.data()), json.length(), stage1_mode::regular) ); + return document::start({ reinterpret_cast(json.data()), this }); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const char *json, size_t len, size_t allocated) & noexcept { + return iterate(padded_string_view(json, len, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const uint8_t *json, size_t len, size_t allocated) & noexcept { + return iterate(padded_string_view(json, len, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(std::string_view json, size_t allocated) & noexcept { + return iterate(padded_string_view(json, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(std::string &json) & noexcept { + if(json.capacity() - json.size() < SIMDJSON_PADDING) { + json.reserve(json.size() + SIMDJSON_PADDING); + } + return iterate(padded_string_view(json)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const std::string &json) & noexcept { + return iterate(padded_string_view(json)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const simdjson_result &result) & noexcept { + // We don't presently have a way to temporarily get a const T& from a simdjson_result without throwing an exception + SIMDJSON_TRY( result.error() ); + padded_string_view json = result.value_unsafe(); + return iterate(json); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const simdjson_result &result) & noexcept { + // We don't presently have a way to temporarily get a const T& from a simdjson_result without throwing an exception + SIMDJSON_TRY( result.error() ); + const padded_string &json = result.value_unsafe(); + return iterate(json); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate_raw(padded_string_view json) & noexcept { + if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; } + + json.remove_utf8_bom(); + + // Allocate if needed + if (capacity() < json.length()) { + SIMDJSON_TRY( allocate(json.length(), max_depth()) ); + } + + // Run stage 1. + SIMDJSON_TRY( implementation->stage1(reinterpret_cast(json.data()), json.length(), stage1_mode::regular) ); + return json_iterator(reinterpret_cast(json.data()), this); +} + +inline simdjson_result parser::iterate_many(const uint8_t *buf, size_t len, size_t batch_size, bool allow_comma_separated) noexcept { + if(batch_size < MINIMAL_BATCH_SIZE) { batch_size = MINIMAL_BATCH_SIZE; } + if((len >= 3) && (std::memcmp(buf, "\xEF\xBB\xBF", 3) == 0)) { + buf += 3; + len -= 3; + } + if(allow_comma_separated && batch_size < len) { batch_size = len; } + return document_stream(*this, buf, len, batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const char *buf, size_t len, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(reinterpret_cast(buf), len, batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const std::string &s, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(s.data(), s.length(), batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const padded_string &s, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(s.data(), s.length(), batch_size, allow_comma_separated); +} + +simdjson_inline size_t parser::capacity() const noexcept { + return _capacity; +} +simdjson_inline size_t parser::max_capacity() const noexcept { + return _max_capacity; +} +simdjson_inline size_t parser::max_depth() const noexcept { + return _max_depth; +} + +simdjson_inline void parser::set_max_capacity(size_t max_capacity) noexcept { + if(max_capacity < dom::MINIMAL_DOCUMENT_CAPACITY) { + _max_capacity = max_capacity; + } else { + _max_capacity = dom::MINIMAL_DOCUMENT_CAPACITY; + } +} + +simdjson_inline simdjson_warn_unused simdjson_result parser::unescape(raw_json_string in, uint8_t *&dst, bool allow_replacement) const noexcept { + uint8_t *end = implementation->parse_string(in.buf, dst, allow_replacement); + if (!end) { return STRING_ERROR; } + std::string_view result(reinterpret_cast(dst), end-dst); + dst = end; + return result; +} + +simdjson_inline simdjson_warn_unused simdjson_result parser::unescape_wobbly(raw_json_string in, uint8_t *&dst) const noexcept { + uint8_t *end = implementation->parse_wobbly_string(in.buf, dst); + if (!end) { return STRING_ERROR; } + std::string_view result(reinterpret_cast(dst), end-dst); + dst = end; + return result; +} + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(icelake::ondemand::parser &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H +/* end file simdjson/generic/ondemand/parser-inl.h for icelake */ +/* including simdjson/generic/ondemand/raw_json_string-inl.h for icelake: #include "simdjson/generic/ondemand/raw_json_string-inl.h" */ +/* begin file simdjson/generic/ondemand/raw_json_string-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +namespace icelake { +namespace ondemand { + +simdjson_inline raw_json_string::raw_json_string(const uint8_t * _buf) noexcept : buf{_buf} {} + +simdjson_inline const char * raw_json_string::raw() const noexcept { return reinterpret_cast(buf); } + + +simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(std::string_view target) noexcept { + size_t pos{0}; + // if the content has no escape character, just scan through it quickly! + for(;pos < target.size() && target[pos] != '\\';pos++) {} + // slow path may begin. + bool escaping{false}; + for(;pos < target.size();pos++) { + if((target[pos] == '"') && !escaping) { + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + return true; +} + +simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(const char* target) noexcept { + size_t pos{0}; + // if the content has no escape character, just scan through it quickly! + for(;target[pos] && target[pos] != '\\';pos++) {} + // slow path may begin. + bool escaping{false}; + for(;target[pos];pos++) { + if((target[pos] == '"') && !escaping) { + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + return true; +} + + +simdjson_inline bool raw_json_string::unsafe_is_equal(size_t length, std::string_view target) const noexcept { + // If we are going to call memcmp, then we must know something about the length of the raw_json_string. + return (length >= target.size()) && (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size()); +} + +simdjson_inline bool raw_json_string::unsafe_is_equal(std::string_view target) const noexcept { + // Assumptions: does not contain unescaped quote characters, and + // the raw content is quote terminated within a valid JSON string. + if(target.size() <= SIMDJSON_PADDING) { + return (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size()); + } + const char * r{raw()}; + size_t pos{0}; + for(;pos < target.size();pos++) { + if(r[pos] != target[pos]) { return false; } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_inline bool raw_json_string::is_equal(std::string_view target) const noexcept { + const char * r{raw()}; + size_t pos{0}; + bool escaping{false}; + for(;pos < target.size();pos++) { + if(r[pos] != target[pos]) { return false; } + // if target is a compile-time constant and it is free from + // quotes, then the next part could get optimized away through + // inlining. + if((target[pos] == '"') && !escaping) { + // We have reached the end of the raw_json_string but + // the target is not done. + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + if(r[pos] != '"') { return false; } + return true; +} + + +simdjson_inline bool raw_json_string::unsafe_is_equal(const char * target) const noexcept { + // Assumptions: 'target' does not contain unescaped quote characters, is null terminated and + // the raw content is quote terminated within a valid JSON string. + const char * r{raw()}; + size_t pos{0}; + for(;target[pos];pos++) { + if(r[pos] != target[pos]) { return false; } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_inline bool raw_json_string::is_equal(const char* target) const noexcept { + // Assumptions: does not contain unescaped quote characters, and + // the raw content is quote terminated within a valid JSON string. + const char * r{raw()}; + size_t pos{0}; + bool escaping{false}; + for(;target[pos];pos++) { + if(r[pos] != target[pos]) { return false; } + // if target is a compile-time constant and it is free from + // quotes, then the next part could get optimized away through + // inlining. + if((target[pos] == '"') && !escaping) { + // We have reached the end of the raw_json_string but + // the target is not done. + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept { + return a.unsafe_is_equal(c); +} + +simdjson_unused simdjson_inline bool operator==(std::string_view c, const raw_json_string &a) noexcept { + return a == c; +} + +simdjson_unused simdjson_inline bool operator!=(const raw_json_string &a, std::string_view c) noexcept { + return !(a == c); +} + +simdjson_unused simdjson_inline bool operator!=(std::string_view c, const raw_json_string &a) noexcept { + return !(a == c); +} + + +simdjson_inline simdjson_warn_unused simdjson_result raw_json_string::unescape(json_iterator &iter, bool allow_replacement) const noexcept { + return iter.unescape(*this, allow_replacement); +} + +simdjson_inline simdjson_warn_unused simdjson_result raw_json_string::unescape_wobbly(json_iterator &iter) const noexcept { + return iter.unescape_wobbly(*this); +} + +simdjson_unused simdjson_inline std::ostream &operator<<(std::ostream &out, const raw_json_string &str) noexcept { + bool in_escape = false; + const char *s = str.raw(); + while (true) { + switch (*s) { + case '\\': in_escape = !in_escape; break; + case '"': if (in_escape) { in_escape = false; } else { return out; } break; + default: if (in_escape) { in_escape = false; } + } + out << *s; + s++; + } +} + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(icelake::ondemand::raw_json_string &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +simdjson_inline simdjson_result simdjson_result::raw() const noexcept { + if (error()) { return error(); } + return first.raw(); +} +simdjson_inline simdjson_warn_unused simdjson_result simdjson_result::unescape(icelake::ondemand::json_iterator &iter, bool allow_replacement) const noexcept { + if (error()) { return error(); } + return first.unescape(iter, allow_replacement); +} +simdjson_inline simdjson_warn_unused simdjson_result simdjson_result::unescape_wobbly(icelake::ondemand::json_iterator &iter) const noexcept { + if (error()) { return error(); } + return first.unescape_wobbly(iter); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H +/* end file simdjson/generic/ondemand/raw_json_string-inl.h for icelake */ +/* including simdjson/generic/ondemand/serialization-inl.h for icelake: #include "simdjson/generic/ondemand/serialization-inl.h" */ +/* begin file simdjson/generic/ondemand/serialization-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/serialization.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +inline std::string_view trim(const std::string_view str) noexcept { + // We can almost surely do better by rolling our own find_first_not_of function. + size_t first = str.find_first_not_of(" \t\n\r"); + // If we have the empty string (just white space), then no trimming is possible, and + // we return the empty string_view. + if (std::string_view::npos == first) { return std::string_view(); } + size_t last = str.find_last_not_of(" \t\n\r"); + return str.substr(first, (last - first + 1)); +} + + +inline simdjson_result to_json_string(icelake::ondemand::document& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(icelake::ondemand::document_reference& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(icelake::ondemand::value& x) noexcept { + /** + * If we somehow receive a value that has already been consumed, + * then the following code could be in trouble. E.g., we create + * an array as needed, but if an array was already created, then + * it could be bad. + */ + using namespace icelake::ondemand; + icelake::ondemand::json_type t; + auto error = x.type().get(t); + if(error != SUCCESS) { return error; } + switch (t) + { + case json_type::array: + { + icelake::ondemand::array array; + error = x.get_array().get(array); + if(error) { return error; } + return to_json_string(array); + } + case json_type::object: + { + icelake::ondemand::object object; + error = x.get_object().get(object); + if(error) { return error; } + return to_json_string(object); + } + default: + return trim(x.raw_json_token()); + } +} + +inline simdjson_result to_json_string(icelake::ondemand::object& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(icelake::ondemand::array& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} +} // namespace simdjson + +namespace simdjson { namespace icelake { namespace ondemand { + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::icelake::ondemand::value x) { + std::string_view v; + auto error = simdjson::to_json_string(x).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::icelake::ondemand::value x) { + std::string_view v; + auto error = simdjson::to_json_string(x).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::icelake::ondemand::array value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::icelake::ondemand::array value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::icelake::ondemand::document& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::icelake::ondemand::document_reference& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::icelake::ondemand::document& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::icelake::ondemand::object value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::icelake::ondemand::object value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif +}}} // namespace simdjson::icelake::ondemand + +#endif // SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H +/* end file simdjson/generic/ondemand/serialization-inl.h for icelake */ +/* including simdjson/generic/ondemand/token_iterator-inl.h for icelake: #include "simdjson/generic/ondemand/token_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/token_iterator-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +simdjson_inline token_iterator::token_iterator( + const uint8_t *_buf, + token_position position +) noexcept : buf{_buf}, _position{position} +{ +} + +simdjson_inline uint32_t token_iterator::current_offset() const noexcept { + return *(_position); +} + + +simdjson_inline const uint8_t *token_iterator::return_current_and_advance() noexcept { + return &buf[*(_position++)]; +} + +simdjson_inline const uint8_t *token_iterator::peek(token_position position) const noexcept { + return &buf[*position]; +} +simdjson_inline uint32_t token_iterator::peek_index(token_position position) const noexcept { + return *position; +} +simdjson_inline uint32_t token_iterator::peek_length(token_position position) const noexcept { + return *(position+1) - *position; +} + +simdjson_inline const uint8_t *token_iterator::peek(int32_t delta) const noexcept { + return &buf[*(_position+delta)]; +} +simdjson_inline uint32_t token_iterator::peek_index(int32_t delta) const noexcept { + return *(_position+delta); +} +simdjson_inline uint32_t token_iterator::peek_length(int32_t delta) const noexcept { + return *(_position+delta+1) - *(_position+delta); +} + +simdjson_inline token_position token_iterator::position() const noexcept { + return _position; +} +simdjson_inline void token_iterator::set_position(token_position target_position) noexcept { + _position = target_position; +} + +simdjson_inline bool token_iterator::operator==(const token_iterator &other) const noexcept { + return _position == other._position; +} +simdjson_inline bool token_iterator::operator!=(const token_iterator &other) const noexcept { + return _position != other._position; +} +simdjson_inline bool token_iterator::operator>(const token_iterator &other) const noexcept { + return _position > other._position; +} +simdjson_inline bool token_iterator::operator>=(const token_iterator &other) const noexcept { + return _position >= other._position; +} +simdjson_inline bool token_iterator::operator<(const token_iterator &other) const noexcept { + return _position < other._position; +} +simdjson_inline bool token_iterator::operator<=(const token_iterator &other) const noexcept { + return _position <= other._position; +} + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(icelake::ondemand::token_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/token_iterator-inl.h for icelake */ +/* including simdjson/generic/ondemand/value-inl.h for icelake: #include "simdjson/generic/ondemand/value-inl.h" */ +/* begin file simdjson/generic/ondemand/value-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +simdjson_inline value::value(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} +simdjson_inline value value::start(const value_iterator &iter) noexcept { + return iter; +} +simdjson_inline value value::resume(const value_iterator &iter) noexcept { + return iter; +} + +simdjson_inline simdjson_result value::get_array() noexcept { + return array::start(iter); +} +simdjson_inline simdjson_result value::get_object() noexcept { + return object::start(iter); +} +simdjson_inline simdjson_result value::start_or_resume_object() noexcept { + if (iter.at_start()) { + return get_object(); + } else { + return object::resume(iter); + } +} + +simdjson_inline simdjson_result value::get_raw_json_string() noexcept { + return iter.get_raw_json_string(); +} +simdjson_inline simdjson_result value::get_string(bool allow_replacement) noexcept { + return iter.get_string(allow_replacement); +} +template +simdjson_inline error_code value::get_string(string_type& receiver, bool allow_replacement) noexcept { + return iter.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result value::get_wobbly_string() noexcept { + return iter.get_wobbly_string(); +} +simdjson_inline simdjson_result value::get_double() noexcept { + return iter.get_double(); +} +simdjson_inline simdjson_result value::get_double_in_string() noexcept { + return iter.get_double_in_string(); +} +simdjson_inline simdjson_result value::get_uint64() noexcept { + return iter.get_uint64(); +} +simdjson_inline simdjson_result value::get_uint64_in_string() noexcept { + return iter.get_uint64_in_string(); +} +simdjson_inline simdjson_result value::get_int64() noexcept { + return iter.get_int64(); +} +simdjson_inline simdjson_result value::get_int64_in_string() noexcept { + return iter.get_int64_in_string(); +} +simdjson_inline simdjson_result value::get_bool() noexcept { + return iter.get_bool(); +} +simdjson_inline simdjson_result value::is_null() noexcept { + return iter.is_null(); +} +template<> simdjson_inline simdjson_result value::get() noexcept { return get_array(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_object(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_number(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_double(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_uint64(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_int64(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_bool(); } + +template simdjson_inline error_code value::get(T &out) noexcept { + return get().get(out); +} + +#if SIMDJSON_EXCEPTIONS +simdjson_inline value::operator array() noexcept(false) { + return get_array(); +} +simdjson_inline value::operator object() noexcept(false) { + return get_object(); +} +simdjson_inline value::operator uint64_t() noexcept(false) { + return get_uint64(); +} +simdjson_inline value::operator int64_t() noexcept(false) { + return get_int64(); +} +simdjson_inline value::operator double() noexcept(false) { + return get_double(); +} +simdjson_inline value::operator std::string_view() noexcept(false) { + return get_string(false); +} +simdjson_inline value::operator raw_json_string() noexcept(false) { + return get_raw_json_string(); +} +simdjson_inline value::operator bool() noexcept(false) { + return get_bool(); +} +#endif + +simdjson_inline simdjson_result value::begin() & noexcept { + return get_array().begin(); +} +simdjson_inline simdjson_result value::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result value::count_elements() & noexcept { + simdjson_result answer; + auto a = get_array(); + answer = a.count_elements(); + // count_elements leaves you pointing inside the array, at the first element. + // We need to move back so that the user can create a new array (which requires that + // we point at '['). + iter.move_at_start(); + return answer; +} +simdjson_inline simdjson_result value::count_fields() & noexcept { + simdjson_result answer; + auto a = get_object(); + answer = a.count_fields(); + iter.move_at_start(); + return answer; +} +simdjson_inline simdjson_result value::at(size_t index) noexcept { + auto a = get_array(); + return a.at(index); +} + +simdjson_inline simdjson_result value::find_field(std::string_view key) noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result value::find_field(const char *key) noexcept { + return start_or_resume_object().find_field(key); +} + +simdjson_inline simdjson_result value::find_field_unordered(std::string_view key) noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result value::find_field_unordered(const char *key) noexcept { + return start_or_resume_object().find_field_unordered(key); +} + +simdjson_inline simdjson_result value::operator[](std::string_view key) noexcept { + return start_or_resume_object()[key]; +} +simdjson_inline simdjson_result value::operator[](const char *key) noexcept { + return start_or_resume_object()[key]; +} + +simdjson_inline simdjson_result value::type() noexcept { + return iter.type(); +} + +simdjson_inline simdjson_result value::is_scalar() noexcept { + json_type this_type; + auto error = type().get(this_type); + if(error) { return error; } + return ! ((this_type == json_type::array) || (this_type == json_type::object)); +} + +simdjson_inline bool value::is_negative() noexcept { + return iter.is_negative(); +} + +simdjson_inline simdjson_result value::is_integer() noexcept { + return iter.is_integer(); +} +simdjson_warn_unused simdjson_inline simdjson_result value::get_number_type() noexcept { + return iter.get_number_type(); +} +simdjson_warn_unused simdjson_inline simdjson_result value::get_number() noexcept { + return iter.get_number(); +} + +simdjson_inline std::string_view value::raw_json_token() noexcept { + return std::string_view(reinterpret_cast(iter.peek_start()), iter.peek_start_length()); +} + +simdjson_inline simdjson_result value::raw_json() noexcept { + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: { + ondemand::array array; + SIMDJSON_TRY(get_array().get(array)); + return array.raw_json(); + } + case json_type::object: { + ondemand::object object; + SIMDJSON_TRY(get_object().get(object)); + return object.raw_json(); + } + default: + return raw_json_token(); + } +} + +simdjson_inline simdjson_result value::current_location() noexcept { + return iter.json_iter().current_location(); +} + +simdjson_inline int32_t value::current_depth() const noexcept{ + return iter.json_iter().depth(); +} + +simdjson_inline simdjson_result value::at_pointer(std::string_view json_pointer) noexcept { + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: + return (*this).get_array().at_pointer(json_pointer); + case json_type::object: + return (*this).get_object().at_pointer(json_pointer); + default: + return INVALID_JSON_POINTER; + } +} + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + icelake::ondemand::value &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + if (error()) { return error(); } + return {}; +} + +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) noexcept { + if (error()) { return error(); } + return first.find_field(key); +} + +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} + +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) noexcept { + if (error()) { return error(); } + return first[key]; +} + +simdjson_inline simdjson_result simdjson_result::get_array() noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} + +template simdjson_inline simdjson_result simdjson_result::get() noexcept { + if (error()) { return error(); } + return first.get(); +} +template simdjson_inline error_code simdjson_result::get(T &out) noexcept { + if (error()) { return error(); } + return first.get(out); +} + +template<> simdjson_inline simdjson_result simdjson_result::get() noexcept { + if (error()) { return error(); } + return std::move(first); +} +template<> simdjson_inline error_code simdjson_result::get(icelake::ondemand::value &out) noexcept { + if (error()) { return error(); } + out = first; + return SUCCESS; +} + +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} +simdjson_inline simdjson_result simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator icelake::ondemand::array() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator icelake::ondemand::object() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator icelake::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline simdjson_result simdjson_result::current_depth() const noexcept { + if (error()) { return error(); } + return first.current_depth(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H +/* end file simdjson/generic/ondemand/value-inl.h for icelake */ +/* including simdjson/generic/ondemand/value_iterator-inl.h for icelake: #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/value_iterator-inl.h for icelake */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/atomparsing.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/numberparsing.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace icelake { +namespace ondemand { + +simdjson_inline value_iterator::value_iterator( + json_iterator *json_iter, + depth_t depth, + token_position start_position +) noexcept : _json_iter{json_iter}, _depth{depth}, _start_position{start_position} +{ +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_object() noexcept { + SIMDJSON_TRY( start_container('{', "Not an object", "object") ); + return started_object(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_root_object() noexcept { + SIMDJSON_TRY( start_container('{', "Not an object", "object") ); + return started_root_object(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_object() noexcept { + assert_at_container_start(); +#if SIMDJSON_DEVELOPMENT_CHECKS + _json_iter->set_start_position(_depth, start_position()); +#endif + if (*_json_iter->peek() == '}') { + logger::log_value(*_json_iter, "empty object"); + _json_iter->return_current_and_advance(); + end_container(); + return false; + } + return true; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::check_root_object() noexcept { + // When in streaming mode, we cannot expect peek_last() to be the last structural element of the + // current document. It only works in the normal mode where we have indexed a single document. + // Note that adding a check for 'streaming' is not expensive since we only have at most + // one root element. + if ( ! _json_iter->streaming() ) { + // The following lines do not fully protect against garbage content within the + // object: e.g., `{"a":2} foo }`. Users concerned with garbage content should + // call `at_end()` on the document instance at the end of the processing to + // ensure that the processing has finished at the end. + // + if (*_json_iter->peek_last() != '}') { + _json_iter->abandon(); + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing } at end"); + } + // If the last character is } *and* the first gibberish character is also '}' + // then on-demand could accidentally go over. So we need additional checks. + // https://github.com/simdjson/simdjson/issues/1834 + // Checking that the document is balanced requires a full scan which is potentially + // expensive, but it only happens in edge cases where the first padding character is + // a closing bracket. + if ((*_json_iter->peek(_json_iter->end_position()) == '}') && (!_json_iter->balanced())) { + _json_iter->abandon(); + // The exact error would require more work. It will typically be an unclosed object. + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "the document is unbalanced"); + } + } + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_root_object() noexcept { + auto error = check_root_object(); + if(error) { return error; } + return started_object(); +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::end_container() noexcept { +#if SIMDJSON_CHECK_EOF + if (depth() > 1 && at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing parent ] or }"); } + // if (depth() <= 1 && !at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing [ or { at start"); } +#endif // SIMDJSON_CHECK_EOF + _json_iter->ascend_to(depth()-1); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::has_next_field() noexcept { + assert_at_next(); + + // It's illegal to call this unless there are more tokens: anything that ends in } or ] is + // obligated to verify there are more tokens if they are not the top level. + switch (*_json_iter->return_current_and_advance()) { + case '}': + logger::log_end_value(*_json_iter, "object"); + SIMDJSON_TRY( end_container() ); + return false; + case ',': + return true; + default: + return report_error(TAPE_ERROR, "Missing comma between object fields"); + } +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::find_field_raw(const std::string_view key) noexcept { + error_code error; + bool has_value; + // + // Initially, the object can be in one of a few different places: + // + // 1. The start of the object, at the first field: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2, index 1) + // ``` + if (at_first_field()) { + has_value = true; + + // + // 2. When a previous search did not yield a value or the object is empty: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // { } + // ^ (depth 0, index 2) + // ``` + // + } else if (!is_open()) { +#if SIMDJSON_DEVELOPMENT_CHECKS + // If we're past the end of the object, we're being iterated out of order. + // Note: this isn't perfect detection. It's possible the user is inside some other object; if so, + // this object iterator will blithely scan that object for fields. + if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; } +#endif + return false; + + // 3. When a previous search found a field or an iterator yielded a value: + // + // ``` + // // When a field was not fully consumed (or not even touched at all) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2) + // // When a field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // When the last field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // ``` + // + } else { + if ((error = skip_child() )) { abandon(); return error; } + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } +#if SIMDJSON_DEVELOPMENT_CHECKS + if (_json_iter->start_position(_depth) != start_position()) { return OUT_OF_ORDER_ITERATION; } +#endif + } + while (has_value) { + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + if ((error = field_key().get(actual_key) )) { abandon(); return error; }; + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + if ((error = field_value() )) { abandon(); return error; } + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + //if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); // Skip the value entirely + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } + } + + // If the loop ended, we're out of fields to look at. + return false; +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::find_field_unordered_raw(const std::string_view key) noexcept { + /** + * When find_field_unordered_raw is called, we can either be pointing at the + * first key, pointing outside (at the closing brace) or if a key was matched + * we can be either pointing right afterthe ':' right before the value (that we need skip), + * or we may have consumed the value and we might be at a comma or at the + * final brace (ready for a call to has_next_field()). + */ + error_code error; + bool has_value; + + // First, we scan from that point to the end. + // If we don't find a match, we may loop back around, and scan from the beginning to that point. + token_position search_start = _json_iter->position(); + + // We want to know whether we need to go back to the beginning. + bool at_first = at_first_field(); + /////////////// + // Initially, the object can be in one of a few different places: + // + // 1. At the first key: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2, index 1) + // ``` + // + if (at_first) { + has_value = true; + + // 2. When a previous search did not yield a value or the object is empty: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // { } + // ^ (depth 0, index 2) + // ``` + // + } else if (!is_open()) { + +#if SIMDJSON_DEVELOPMENT_CHECKS + // If we're past the end of the object, we're being iterated out of order. + // Note: this isn't perfect detection. It's possible the user is inside some other object; if so, + // this object iterator will blithely scan that object for fields. + if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; } +#endif + SIMDJSON_TRY(reset_object().get(has_value)); + at_first = true; + // 3. When a previous search found a field or an iterator yielded a value: + // + // ``` + // // When a field was not fully consumed (or not even touched at all) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2) + // // When a field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // When the last field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // ``` + // + } else { + // If someone queried a key but they not did access the value, then we are left pointing + // at the ':' and we need to move forward through the value... If the value was + // processed then skip_child() does not move the iterator (but may adjust the depth). + if ((error = skip_child() )) { abandon(); return error; } + search_start = _json_iter->position(); + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } +#if SIMDJSON_DEVELOPMENT_CHECKS + if (_json_iter->start_position(_depth) != start_position()) { return OUT_OF_ORDER_ITERATION; } +#endif + } + + // After initial processing, we will be in one of two states: + // + // ``` + // // At the beginning of a field + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // At the end of the object + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // ``` + // + // Next, we find a match starting from the current position. + while (has_value) { + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); // We must be at the start of a field + + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + if ((error = field_key().get(actual_key) )) { abandon(); return error; }; + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + if ((error = field_value() )) { abandon(); return error; } + + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + // if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } + } + // Performance note: it maybe wasteful to rewind to the beginning when there might be + // no other query following. Indeed, it would require reskipping the whole object. + // Instead, you can just stay where you are. If there is a new query, there is always time + // to rewind. + if(at_first) { return false; } + + // If we reach the end without finding a match, search the rest of the fields starting at the + // beginning of the object. + // (We have already run through the object before, so we've already validated its structure. We + // don't check errors in this bit.) + SIMDJSON_TRY(reset_object().get(has_value)); + while (true) { + SIMDJSON_ASSUME(has_value); // we should reach search_start before ever reaching the end of the object + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); // We must be at the start of a field + + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + error = field_key().get(actual_key); SIMDJSON_ASSUME(!error); + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + error = field_value(); SIMDJSON_ASSUME(!error); + + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + // if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); + // If we reached the end of the key-value pair we started from, then we know + // that the key is not there so we return false. We are either right before + // the next comma or the final brace. + if(_json_iter->position() == search_start) { return false; } + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + error = has_next_field().get(has_value); SIMDJSON_ASSUME(!error); + // If we make the mistake of exiting here, then we could be left pointing at a key + // in the middle of an object. That's not an allowable state. + } + // If the loop ended, we're out of fields to look at. The program should + // never reach this point. + return false; +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::field_key() noexcept { + assert_at_next(); + + const uint8_t *key = _json_iter->return_current_and_advance(); + if (*(key++) != '"') { return report_error(TAPE_ERROR, "Object key is not a string"); } + return raw_json_string(key); +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::field_value() noexcept { + assert_at_next(); + + if (*_json_iter->return_current_and_advance() != ':') { return report_error(TAPE_ERROR, "Missing colon in object field"); } + _json_iter->descend_to(depth()+1); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_array() noexcept { + SIMDJSON_TRY( start_container('[', "Not an array", "array") ); + return started_array(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_root_array() noexcept { + SIMDJSON_TRY( start_container('[', "Not an array", "array") ); + return started_root_array(); +} + +inline std::string value_iterator::to_string() const noexcept { + auto answer = std::string("value_iterator [ depth : ") + std::to_string(_depth) + std::string(", "); + if(_json_iter != nullptr) { answer += _json_iter->to_string(); } + answer += std::string(" ]"); + return answer; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_array() noexcept { + assert_at_container_start(); + if (*_json_iter->peek() == ']') { + logger::log_value(*_json_iter, "empty array"); + _json_iter->return_current_and_advance(); + SIMDJSON_TRY( end_container() ); + return false; + } + _json_iter->descend_to(depth()+1); +#if SIMDJSON_DEVELOPMENT_CHECKS + _json_iter->set_start_position(_depth, start_position()); +#endif + return true; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::check_root_array() noexcept { + // When in streaming mode, we cannot expect peek_last() to be the last structural element of the + // current document. It only works in the normal mode where we have indexed a single document. + // Note that adding a check for 'streaming' is not expensive since we only have at most + // one root element. + if ( ! _json_iter->streaming() ) { + // The following lines do not fully protect against garbage content within the + // array: e.g., `[1, 2] foo]`. Users concerned with garbage content should + // also call `at_end()` on the document instance at the end of the processing to + // ensure that the processing has finished at the end. + // + if (*_json_iter->peek_last() != ']') { + _json_iter->abandon(); + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing ] at end"); + } + // If the last character is ] *and* the first gibberish character is also ']' + // then on-demand could accidentally go over. So we need additional checks. + // https://github.com/simdjson/simdjson/issues/1834 + // Checking that the document is balanced requires a full scan which is potentially + // expensive, but it only happens in edge cases where the first padding character is + // a closing bracket. + if ((*_json_iter->peek(_json_iter->end_position()) == ']') && (!_json_iter->balanced())) { + _json_iter->abandon(); + // The exact error would require more work. It will typically be an unclosed array. + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "the document is unbalanced"); + } + } + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_root_array() noexcept { + auto error = check_root_array(); + if (error) { return error; } + return started_array(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::has_next_element() noexcept { + assert_at_next(); + + logger::log_event(*this, "has_next_element"); + switch (*_json_iter->return_current_and_advance()) { + case ']': + logger::log_end_value(*_json_iter, "array"); + SIMDJSON_TRY( end_container() ); + return false; + case ',': + _json_iter->descend_to(depth()+1); + return true; + default: + return report_error(TAPE_ERROR, "Missing comma between array elements"); + } +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::parse_bool(const uint8_t *json) const noexcept { + auto not_true = atomparsing::str4ncmp(json, "true"); + auto not_false = atomparsing::str4ncmp(json, "fals") | (json[4] ^ 'e'); + bool error = (not_true && not_false) || jsoncharutils::is_not_structural_or_whitespace(json[not_true ? 5 : 4]); + if (error) { return incorrect_type_error("Not a boolean"); } + return simdjson_result(!not_true); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::parse_null(const uint8_t *json) const noexcept { + bool is_null_string = !atomparsing::str4ncmp(json, "null") && jsoncharutils::is_structural_or_whitespace(json[4]); + // if we start with 'n', we must be a null + if(!is_null_string && json[0]=='n') { return incorrect_type_error("Not a null but starts with n"); } + return is_null_string; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_string(bool allow_replacement) noexcept { + return get_raw_json_string().unescape(json_iter(), allow_replacement); +} +template +simdjson_warn_unused simdjson_inline error_code value_iterator::get_string(string_type& receiver, bool allow_replacement) noexcept { + std::string_view content; + auto err = get_string(allow_replacement).get(content); + if (err) { return err; } + receiver = content; + return SUCCESS; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_wobbly_string() noexcept { + return get_raw_json_string().unescape_wobbly(json_iter()); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_raw_json_string() noexcept { + auto json = peek_scalar("string"); + if (*json != '"') { return incorrect_type_error("Not a string"); } + advance_scalar("string"); + return raw_json_string(json+1); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_uint64() noexcept { + auto result = numberparsing::parse_unsigned(peek_non_root_scalar("uint64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("uint64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_uint64_in_string() noexcept { + auto result = numberparsing::parse_unsigned_in_string(peek_non_root_scalar("uint64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("uint64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_int64() noexcept { + auto result = numberparsing::parse_integer(peek_non_root_scalar("int64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("int64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_int64_in_string() noexcept { + auto result = numberparsing::parse_integer_in_string(peek_non_root_scalar("int64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("int64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_double() noexcept { + auto result = numberparsing::parse_double(peek_non_root_scalar("double")); + if(result.error() == SUCCESS) { advance_non_root_scalar("double"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_double_in_string() noexcept { + auto result = numberparsing::parse_double_in_string(peek_non_root_scalar("double")); + if(result.error() == SUCCESS) { advance_non_root_scalar("double"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_bool() noexcept { + auto result = parse_bool(peek_non_root_scalar("bool")); + if(result.error() == SUCCESS) { advance_non_root_scalar("bool"); } + return result; +} +simdjson_inline simdjson_result value_iterator::is_null() noexcept { + bool is_null_value; + SIMDJSON_TRY(parse_null(peek_non_root_scalar("null")).get(is_null_value)); + if(is_null_value) { advance_non_root_scalar("null"); } + return is_null_value; +} +simdjson_inline bool value_iterator::is_negative() noexcept { + return numberparsing::is_negative(peek_non_root_scalar("numbersign")); +} +simdjson_inline bool value_iterator::is_root_negative() noexcept { + return numberparsing::is_negative(peek_root_scalar("numbersign")); +} +simdjson_inline simdjson_result value_iterator::is_integer() noexcept { + return numberparsing::is_integer(peek_non_root_scalar("integer")); +} +simdjson_inline simdjson_result value_iterator::get_number_type() noexcept { + return numberparsing::get_number_type(peek_non_root_scalar("integer")); +} +simdjson_inline simdjson_result value_iterator::get_number() noexcept { + number num; + error_code error = numberparsing::parse_number(peek_non_root_scalar("number"), num); + if(error) { return error; } + return num; +} + +simdjson_inline simdjson_result value_iterator::is_root_integer(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("is_root_integer"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + return false; // if there are more than 20 characters, it cannot be represented as an integer. + } + auto answer = numberparsing::is_integer(tmpbuf); + // If the parsing was a success, we must still check that it is + // a single scalar. Note that we parse first because of cases like '[]' where + // getting TRAILING_CONTENT is wrong. + if(check_trailing && (answer.error() == SUCCESS) && (!_json_iter->is_single_token())) { return TRAILING_CONTENT; } + return answer; +} + +simdjson_inline simdjson_result value_iterator::get_root_number_type(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("number"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto answer = numberparsing::get_number_type(tmpbuf); + if (check_trailing && (answer.error() == SUCCESS) && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + return answer; +} +simdjson_inline simdjson_result value_iterator::get_root_number(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("number"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + number num; + error_code error = numberparsing::parse_number(tmpbuf, num); + if(error) { return error; } + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("number"); + return num; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_string(bool check_trailing, bool allow_replacement) noexcept { + return get_root_raw_json_string(check_trailing).unescape(json_iter(), allow_replacement); +} +template +simdjson_warn_unused simdjson_inline error_code value_iterator::get_root_string(string_type& receiver, bool check_trailing, bool allow_replacement) noexcept { + std::string_view content; + auto err = get_root_string(check_trailing, allow_replacement).get(content); + if (err) { return err; } + receiver = content; + return SUCCESS; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_wobbly_string(bool check_trailing) noexcept { + return get_root_raw_json_string(check_trailing).unescape_wobbly(json_iter()); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_raw_json_string(bool check_trailing) noexcept { + auto json = peek_scalar("string"); + if (*json != '"') { return incorrect_type_error("Not a string"); } + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_scalar("string"); + return raw_json_string(json+1); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_uint64(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("uint64"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_unsigned(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("uint64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_uint64_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("uint64"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_unsigned_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("uint64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_int64(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("int64"); + uint8_t tmpbuf[20+1+1]; // -<19 digits> is the longest possible integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + + auto result = numberparsing::parse_integer(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("int64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_int64_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("int64"); + uint8_t tmpbuf[20+1+1]; // -<19 digits> is the longest possible integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + + auto result = numberparsing::parse_integer_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("int64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_double(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("double"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; // +1 for null termination. + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_double(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("double"); + } + return result; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_double_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("double"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; // +1 for null termination. + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_double_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("double"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_bool(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("bool"); + uint8_t tmpbuf[5+1+1]; // +1 for null termination + tmpbuf[5+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 5+1)) { return incorrect_type_error("Not a boolean"); } + auto result = parse_bool(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("bool"); + } + return result; +} +simdjson_inline simdjson_result value_iterator::is_root_null(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("null"); + bool result = (max_len >= 4 && !atomparsing::str4ncmp(json, "null") && + (max_len == 4 || jsoncharutils::is_structural_or_whitespace(json[4]))); + if(result) { // we have something that looks like a null. + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("null"); + } + return result; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::skip_child() noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth >= _depth ); + + return _json_iter->skip_child(depth()); +} + +simdjson_inline value_iterator value_iterator::child() const noexcept { + assert_at_child(); + return { _json_iter, depth()+1, _json_iter->token.position() }; +} + +// GCC 7 warns when the first line of this function is inlined away into oblivion due to the caller +// relating depth and iterator depth, which is a desired effect. It does not happen if is_open is +// marked non-inline. +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline bool value_iterator::is_open() const noexcept { + return _json_iter->depth() >= depth(); +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline bool value_iterator::at_end() const noexcept { + return _json_iter->at_end(); +} + +simdjson_inline bool value_iterator::at_start() const noexcept { + return _json_iter->token.position() == start_position(); +} + +simdjson_inline bool value_iterator::at_first_field() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + return _json_iter->token.position() == start_position() + 1; +} + +simdjson_inline void value_iterator::abandon() noexcept { + _json_iter->abandon(); +} + +simdjson_warn_unused simdjson_inline depth_t value_iterator::depth() const noexcept { + return _depth; +} +simdjson_warn_unused simdjson_inline error_code value_iterator::error() const noexcept { + return _json_iter->error; +} +simdjson_warn_unused simdjson_inline uint8_t *&value_iterator::string_buf_loc() noexcept { + return _json_iter->string_buf_loc(); +} +simdjson_warn_unused simdjson_inline const json_iterator &value_iterator::json_iter() const noexcept { + return *_json_iter; +} +simdjson_warn_unused simdjson_inline json_iterator &value_iterator::json_iter() noexcept { + return *_json_iter; +} + +simdjson_inline const uint8_t *value_iterator::peek_start() const noexcept { + return _json_iter->peek(start_position()); +} +simdjson_inline uint32_t value_iterator::peek_start_length() const noexcept { + return _json_iter->peek_length(start_position()); +} + +simdjson_inline const uint8_t *value_iterator::peek_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + if (!is_at_start()) { return peek_start(); } + + // Get the JSON and advance the cursor, decreasing depth to signify that we have retrieved the value. + assert_at_start(); + return _json_iter->peek(); +} + +simdjson_inline void value_iterator::advance_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + if (!is_at_start()) { return; } + + // Get the JSON and advance the cursor, decreasing depth to signify that we have retrieved the value. + assert_at_start(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} + +simdjson_inline error_code value_iterator::start_container(uint8_t start_char, const char *incorrect_type_message, const char *type) noexcept { + logger::log_start_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + const uint8_t *json; + if (!is_at_start()) { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + json = peek_start(); + if (*json != start_char) { return incorrect_type_error(incorrect_type_message); } + } else { + assert_at_start(); + /** + * We should be prudent. Let us peek. If it is not the right type, we + * return an error. Only once we have determined that we have the right + * type are we allowed to advance! + */ + json = _json_iter->peek(); + if (*json != start_char) { return incorrect_type_error(incorrect_type_message); } + _json_iter->return_current_and_advance(); + } + + + return SUCCESS; +} + + +simdjson_inline const uint8_t *value_iterator::peek_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return peek_start(); } + + assert_at_root(); + return _json_iter->peek(); +} +simdjson_inline const uint8_t *value_iterator::peek_non_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return peek_start(); } + + assert_at_non_root_start(); + return _json_iter->peek(); +} + +simdjson_inline void value_iterator::advance_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return; } + + assert_at_root(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} +simdjson_inline void value_iterator::advance_non_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return; } + + assert_at_non_root_start(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} + +simdjson_inline error_code value_iterator::incorrect_type_error(const char *message) const noexcept { + logger::log_error(*_json_iter, start_position(), depth(), message); + return INCORRECT_TYPE; +} + +simdjson_inline bool value_iterator::is_at_start() const noexcept { + return position() == start_position(); +} + +simdjson_inline bool value_iterator::is_at_key() const noexcept { + // Keys are at the same depth as the object. + // Note here that we could be safer and check that we are within an object, + // but we do not. + return _depth == _json_iter->_depth && *_json_iter->peek() == '"'; +} + +simdjson_inline bool value_iterator::is_at_iterator_start() const noexcept { + // We can legitimately be either at the first value ([1]), or after the array if it's empty ([]). + auto delta = position() - start_position(); + return delta == 1 || delta == 2; +} + +inline void value_iterator::assert_at_start() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position == _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_container_start() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position == _start_position + 1 ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_next() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +simdjson_inline void value_iterator::move_at_start() noexcept { + _json_iter->_depth = _depth; + _json_iter->token.set_position(_start_position); +} + +simdjson_inline void value_iterator::move_at_container_start() noexcept { + _json_iter->_depth = _depth; + _json_iter->token.set_position(_start_position + 1); +} + +simdjson_inline simdjson_result value_iterator::reset_array() noexcept { + if(error()) { return error(); } + move_at_container_start(); + return started_array(); +} + +simdjson_inline simdjson_result value_iterator::reset_object() noexcept { + if(error()) { return error(); } + move_at_container_start(); + return started_object(); +} + +inline void value_iterator::assert_at_child() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth + 1 ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_root() const noexcept { + assert_at_start(); + SIMDJSON_ASSUME( _depth == 1 ); +} + +inline void value_iterator::assert_at_non_root_start() const noexcept { + assert_at_start(); + SIMDJSON_ASSUME( _depth > 1 ); +} + +inline void value_iterator::assert_is_valid() const noexcept { + SIMDJSON_ASSUME( _json_iter != nullptr ); +} + +simdjson_inline bool value_iterator::is_valid() const noexcept { + return _json_iter != nullptr; +} + +simdjson_inline simdjson_result value_iterator::type() const noexcept { + switch (*peek_start()) { + case '{': + return json_type::object; + case '[': + return json_type::array; + case '"': + return json_type::string; + case 'n': + return json_type::null; + case 't': case 'f': + return json_type::boolean; + case '-': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return json_type::number; + default: + return TAPE_ERROR; + } +} + +simdjson_inline token_position value_iterator::start_position() const noexcept { + return _start_position; +} + +simdjson_inline token_position value_iterator::position() const noexcept { + return _json_iter->position(); +} + +simdjson_inline token_position value_iterator::end_position() const noexcept { + return _json_iter->end_position(); +} + +simdjson_inline token_position value_iterator::last_position() const noexcept { + return _json_iter->last_position(); +} + +simdjson_inline error_code value_iterator::report_error(error_code error, const char *message) noexcept { + return _json_iter->report_error(error, message); +} + +} // namespace ondemand +} // namespace icelake +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(icelake::ondemand::value_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/value_iterator-inl.h for icelake */ +/* end file simdjson/generic/ondemand/amalgamated.h for icelake */ +/* including simdjson/icelake/end.h: #include "simdjson/icelake/end.h" */ +/* begin file simdjson/icelake/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/icelake/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_ICELAKE +SIMDJSON_UNTARGET_REGION +#endif + +/* undefining SIMDJSON_IMPLEMENTATION from "icelake" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/icelake/end.h */ + +#endif // SIMDJSON_ICELAKE_ONDEMAND_H +/* end file simdjson/icelake/ondemand.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(ppc64) +/* including simdjson/ppc64/ondemand.h: #include "simdjson/ppc64/ondemand.h" */ +/* begin file simdjson/ppc64/ondemand.h */ +#ifndef SIMDJSON_PPC64_ONDEMAND_H +#define SIMDJSON_PPC64_ONDEMAND_H + +/* including simdjson/ppc64/begin.h: #include "simdjson/ppc64/begin.h" */ +/* begin file simdjson/ppc64/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "ppc64" */ +#define SIMDJSON_IMPLEMENTATION ppc64 +/* including simdjson/ppc64/base.h: #include "simdjson/ppc64/base.h" */ +/* begin file simdjson/ppc64/base.h */ +#ifndef SIMDJSON_PPC64_BASE_H +#define SIMDJSON_PPC64_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Implementation for ALTIVEC (PPC64). + */ +namespace ppc64 { + +class implementation; + +namespace { +namespace simd { +template struct simd8; +template struct simd8x64; +} // namespace simd +} // unnamed namespace + +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_BASE_H +/* end file simdjson/ppc64/base.h */ +/* including simdjson/ppc64/intrinsics.h: #include "simdjson/ppc64/intrinsics.h" */ +/* begin file simdjson/ppc64/intrinsics.h */ +#ifndef SIMDJSON_PPC64_INTRINSICS_H +#define SIMDJSON_PPC64_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// This should be the correct header whether +// you use visual studio or other compilers. +#include + +// These are defined by altivec.h in GCC toolchain, it is safe to undef them. +#ifdef bool +#undef bool +#endif + +#ifdef vector +#undef vector +#endif + +static_assert(sizeof(__vector unsigned char) <= simdjson::SIMDJSON_PADDING, "insufficient padding for ppc64"); + +#endif // SIMDJSON_PPC64_INTRINSICS_H +/* end file simdjson/ppc64/intrinsics.h */ +/* including simdjson/ppc64/bitmanipulation.h: #include "simdjson/ppc64/bitmanipulation.h" */ +/* begin file simdjson/ppc64/bitmanipulation.h */ +#ifndef SIMDJSON_PPC64_BITMANIPULATION_H +#define SIMDJSON_PPC64_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num - 1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline int count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num); // Visual Studio wants two underscores +} +#else +simdjson_inline int count_ones(uint64_t input_num) { + return __builtin_popcountll(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + *result = value1 + value2; + return *result < value1; +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_BITMANIPULATION_H +/* end file simdjson/ppc64/bitmanipulation.h */ +/* including simdjson/ppc64/bitmask.h: #include "simdjson/ppc64/bitmask.h" */ +/* begin file simdjson/ppc64/bitmask.h */ +#ifndef SIMDJSON_PPC64_BITMASK_H +#define SIMDJSON_PPC64_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is +// encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(uint64_t bitmask) { + // You can use the version below, however gcc sometimes miscompiles + // vec_pmsum_be, it happens somewhere around between 8 and 9th version. + // The performance boost was not noticeable, falling back to a usual + // implementation. + // __vector unsigned long long all_ones = {~0ull, ~0ull}; + // __vector unsigned long long mask = {bitmask, 0}; + // // Clang and GCC return different values for pmsum for ull so cast it to one. + // // Generally it is not specified by ALTIVEC ISA what is returned by + // // vec_pmsum_be. + // #if defined(__LITTLE_ENDIAN__) + // return (uint64_t)(((__vector unsigned long long)vec_pmsum_be(all_ones, mask))[0]); + // #else + // return (uint64_t)(((__vector unsigned long long)vec_pmsum_be(all_ones, mask))[1]); + // #endif + bitmask ^= bitmask << 1; + bitmask ^= bitmask << 2; + bitmask ^= bitmask << 4; + bitmask ^= bitmask << 8; + bitmask ^= bitmask << 16; + bitmask ^= bitmask << 32; + return bitmask; +} + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif +/* end file simdjson/ppc64/bitmask.h */ +/* including simdjson/ppc64/numberparsing_defs.h: #include "simdjson/ppc64/numberparsing_defs.h" */ +/* begin file simdjson/ppc64/numberparsing_defs.h */ +#ifndef SIMDJSON_PPC64_NUMBERPARSING_DEFS_H +#define SIMDJSON_PPC64_NUMBERPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/intrinsics.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +#if defined(__linux__) +#include +#elif defined(__FreeBSD__) +#include +#endif + +namespace simdjson { +namespace ppc64 { +namespace numberparsing { + +// we don't have appropriate instructions, so let us use a scalar function +// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + uint64_t val; + std::memcpy(&val, chars, sizeof(uint64_t)); +#ifdef __BIG_ENDIAN__ +#if defined(__linux__) + val = bswap_64(val); +#elif defined(__FreeBSD__) + val = bswap64(val); +#endif +#endif + val = (val & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8; + val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16; + return uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32); +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace ppc64 +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_PPC64_NUMBERPARSING_DEFS_H +/* end file simdjson/ppc64/numberparsing_defs.h */ +/* including simdjson/ppc64/simd.h: #include "simdjson/ppc64/simd.h" */ +/* begin file simdjson/ppc64/simd.h */ +#ifndef SIMDJSON_PPC64_SIMD_H +#define SIMDJSON_PPC64_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace ppc64 { +namespace { +namespace simd { + +using __m128i = __vector unsigned char; + +template struct base { + __m128i value; + + // Zero constructor + simdjson_inline base() : value{__m128i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m128i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m128i &() const { + return this->value; + } + simdjson_inline operator __m128i &() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { + return vec_or(this->value, (__m128i)other); + } + simdjson_inline Child operator&(const Child other) const { + return vec_and(this->value, (__m128i)other); + } + simdjson_inline Child operator^(const Child other) const { + return vec_xor(this->value, (__m128i)other); + } + simdjson_inline Child bit_andnot(const Child other) const { + return vec_andc(this->value, (__m128i)other); + } + simdjson_inline Child &operator|=(const Child other) { + auto this_cast = static_cast(this); + *this_cast = *this_cast | other; + return *this_cast; + } + simdjson_inline Child &operator&=(const Child other) { + auto this_cast = static_cast(this); + *this_cast = *this_cast & other; + return *this_cast; + } + simdjson_inline Child &operator^=(const Child other) { + auto this_cast = static_cast(this); + *this_cast = *this_cast ^ other; + return *this_cast; + } +}; + +template > +struct base8 : base> { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m128i _value) : base>(_value) {} + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { + return (__m128i)vec_cmpeq(lhs.value, (__m128i)rhs); + } + + static const int SIZE = sizeof(base>::value); + + template + simdjson_inline simd8 prev(simd8 prev_chunk) const { + __m128i chunk = this->value; +#ifdef __LITTLE_ENDIAN__ + chunk = (__m128i)vec_reve(this->value); + prev_chunk = (__m128i)vec_reve((__m128i)prev_chunk); +#endif + chunk = (__m128i)vec_sld((__m128i)prev_chunk, (__m128i)chunk, 16 - N); +#ifdef __LITTLE_ENDIAN__ + chunk = (__m128i)vec_reve((__m128i)chunk); +#endif + return chunk; + } +}; + +// SIMD byte mask type (returned by things like eq and gt) +template <> struct simd8 : base8 { + static simdjson_inline simd8 splat(bool _value) { + return (__m128i)vec_splats((unsigned char)(-(!!_value))); + } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m128i _value) + : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) + : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { + __vector unsigned long long result; + const __m128i perm_mask = {0x78, 0x70, 0x68, 0x60, 0x58, 0x50, 0x48, 0x40, + 0x38, 0x30, 0x28, 0x20, 0x18, 0x10, 0x08, 0x00}; + + result = ((__vector unsigned long long)vec_vbpermq((__m128i)this->value, + (__m128i)perm_mask)); +#ifdef __LITTLE_ENDIAN__ + return static_cast(result[1]); +#else + return static_cast(result[0]); +#endif + } + simdjson_inline bool any() const { + return !vec_all_eq(this->value, (__m128i)vec_splats(0)); + } + simdjson_inline simd8 operator~() const { + return this->value ^ (__m128i)splat(true); + } +}; + +template struct base8_numeric : base8 { + static simdjson_inline simd8 splat(T value) { + (void)value; + return (__m128i)vec_splats(value); + } + static simdjson_inline simd8 zero() { return splat(0); } + static simdjson_inline simd8 load(const T values[16]) { + return (__m128i)(vec_vsx_ld(0, reinterpret_cast(values))); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16(T v0, T v1, T v2, T v3, T v4, + T v5, T v6, T v7, T v8, T v9, + T v10, T v11, T v12, T v13, + T v14, T v15) { + return simd8(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m128i _value) + : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[16]) const { + vec_vsx_st(this->value, 0, reinterpret_cast<__m128i *>(dst)); + } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { + return (__m128i)((__m128i)this->value + (__m128i)other); + } + simdjson_inline simd8 operator-(const simd8 other) const { + return (__m128i)((__m128i)this->value - (__m128i)other); + } + simdjson_inline simd8 &operator+=(const simd8 other) { + *this = *this + other; + return *static_cast *>(this); + } + simdjson_inline simd8 &operator-=(const simd8 other) { + *this = *this - other; + return *static_cast *>(this); + } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior + // for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return (__m128i)vec_perm((__m128i)lookup_table, (__m128i)lookup_table, this->value); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted + // as a bitset). Passing a 0 value for mask would be equivalent to writing out + // every byte to output. Only the first 16 - count_ones(mask) bytes of the + // result are significant but 16 bytes get written. Design consideration: it + // seems like a function with the signature simd8 compress(uint32_t mask) + // would be sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L *output) const { + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + using internal::thintable_epi8; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. +#ifdef __LITTLE_ENDIAN__ + __m128i shufmask = (__m128i)(__vector unsigned long long){ + thintable_epi8[mask1], thintable_epi8[mask2]}; +#else + __m128i shufmask = (__m128i)(__vector unsigned long long){ + thintable_epi8[mask2], thintable_epi8[mask1]}; + shufmask = (__m128i)vec_reve((__m128i)shufmask); +#endif + // we increment by 0x08 the second half of the mask + shufmask = ((__m128i)shufmask) + + ((__m128i)(__vector int){0, 0, 0x08080808, 0x08080808}); + + // this is the version "nearly pruned" + __m128i pruned = vec_perm(this->value, this->value, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + __m128i compactmask = + vec_vsx_ld(0, reinterpret_cast(pshufb_combine_table + pop1 * 8)); + __m128i answer = vec_perm(pruned, (__m128i)vec_splats(0), compactmask); + vec_vsx_st(answer, 0, reinterpret_cast<__m128i *>(output)); + } + + template + simdjson_inline simd8 + lookup_16(L replace0, L replace1, L replace2, L replace3, L replace4, + L replace5, L replace6, L replace7, L replace8, L replace9, + L replace10, L replace11, L replace12, L replace13, L replace14, + L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, replace4, replace5, replace6, + replace7, replace8, replace9, replace10, replace11, replace12, + replace13, replace14, replace15)); + } +}; + +// Signed bytes +template <> struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) + : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t *values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8(int8_t v0, int8_t v1, int8_t v2, int8_t v3, + int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, + int8_t v12, int8_t v13, int8_t v14, int8_t v15) + : simd8((__m128i)(__vector signed char){v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, + v15}) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 + repeat_16(int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, + int8_t v6, int8_t v7, int8_t v8, int8_t v9, int8_t v10, int8_t v11, + int8_t v12, int8_t v13, int8_t v14, int8_t v15) { + return simd8(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); + } + + // Order-sensitive comparisons + simdjson_inline simd8 + max_val(const simd8 other) const { + return (__m128i)vec_max((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } + simdjson_inline simd8 + min_val(const simd8 other) const { + return (__m128i)vec_min((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } + simdjson_inline simd8 + operator>(const simd8 other) const { + return (__m128i)vec_cmpgt((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } + simdjson_inline simd8 + operator<(const simd8 other) const { + return (__m128i)vec_cmplt((__vector signed char)this->value, + (__vector signed char)(__m128i)other); + } +}; + +// Unsigned bytes +template <> struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) + : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t *values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline + simd8(uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, + uint8_t v6, uint8_t v7, uint8_t v8, uint8_t v9, uint8_t v10, + uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15) + : simd8((__m128i){v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15}) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 + repeat_16(uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, + uint8_t v5, uint8_t v6, uint8_t v7, uint8_t v8, uint8_t v9, + uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, + uint8_t v15) { + return simd8(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); + } + + // Saturated math + simdjson_inline simd8 + saturating_add(const simd8 other) const { + return (__m128i)vec_adds(this->value, (__m128i)other); + } + simdjson_inline simd8 + saturating_sub(const simd8 other) const { + return (__m128i)vec_subs(this->value, (__m128i)other); + } + + // Order-specific operations + simdjson_inline simd8 + max_val(const simd8 other) const { + return (__m128i)vec_max(this->value, (__m128i)other); + } + simdjson_inline simd8 + min_val(const simd8 other) const { + return (__m128i)vec_min(this->value, (__m128i)other); + } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 + gt_bits(const simd8 other) const { + return this->saturating_sub(other); + } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 + lt_bits(const simd8 other) const { + return other.saturating_sub(*this); + } + simdjson_inline simd8 + operator<=(const simd8 other) const { + return other.max_val(*this) == other; + } + simdjson_inline simd8 + operator>=(const simd8 other) const { + return other.min_val(*this) == other; + } + simdjson_inline simd8 + operator>(const simd8 other) const { + return this->gt_bits(other).any_bits_set(); + } + simdjson_inline simd8 + operator<(const simd8 other) const { + return this->gt_bits(other).any_bits_set(); + } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { + return (__m128i)vec_cmpeq(this->value, (__m128i)vec_splats(uint8_t(0))); + } + simdjson_inline simd8 bits_not_set(simd8 bits) const { + return (*this & bits).bits_not_set(); + } + simdjson_inline simd8 any_bits_set() const { + return ~this->bits_not_set(); + } + simdjson_inline simd8 any_bits_set(simd8 bits) const { + return ~this->bits_not_set(bits); + } + simdjson_inline bool bits_not_set_anywhere() const { + return vec_all_eq(this->value, (__m128i)vec_splats(0)); + } + simdjson_inline bool any_bits_set_anywhere() const { + return !bits_not_set_anywhere(); + } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { + return vec_all_eq(vec_and(this->value, (__m128i)bits), + (__m128i)vec_splats(0)); + } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { + return !bits_not_set_anywhere(bits); + } + template simdjson_inline simd8 shr() const { + return simd8( + (__m128i)vec_sr(this->value, (__m128i)vec_splat_u8(N))); + } + template simdjson_inline simd8 shl() const { + return simd8( + (__m128i)vec_sl(this->value, (__m128i)vec_splat_u8(N))); + } +}; + +template struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, + "PPC64 kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64 &o) = delete; // no copy allowed + simd8x64 & + operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, + const simd8 chunk2, const simd8 chunk3) + : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) + : chunks{simd8::load(ptr), simd8::load(ptr + 16), + simd8::load(ptr + 32), simd8::load(ptr + 48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr + sizeof(simd8) * 0); + this->chunks[1].store(ptr + sizeof(simd8) * 1); + this->chunks[2].store(ptr + sizeof(simd8) * 2); + this->chunks[3].store(ptr + sizeof(simd8) * 3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | + (this->chunks[2] | this->chunks[3]); + } + + simdjson_inline uint64_t compress(uint64_t mask, T *output) const { + this->chunks[0].compress(uint16_t(mask), output); + this->chunks[1].compress(uint16_t(mask >> 16), + output + 16 - count_ones(mask & 0xFFFF)); + this->chunks[2].compress(uint16_t(mask >> 32), + output + 32 - count_ones(mask & 0xFFFFFFFF)); + this->chunks[3].compress(uint16_t(mask >> 48), + output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); + return 64 - count_ones(mask); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r0 = uint32_t(this->chunks[0].to_bitmask()); + uint64_t r1 = this->chunks[1].to_bitmask(); + uint64_t r2 = this->chunks[2].to_bitmask(); + uint64_t r3 = this->chunks[3].to_bitmask(); + return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64(this->chunks[0] == mask, this->chunks[1] == mask, + this->chunks[2] == mask, this->chunks[3] == mask) + .to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64(this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1], + this->chunks[2] == other.chunks[2], + this->chunks[3] == other.chunks[3]) + .to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64(this->chunks[0] <= mask, this->chunks[1] <= mask, + this->chunks[2] <= mask, this->chunks[3] <= mask) + .to_bitmask(); + } +}; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_SIMD_INPUT_H +/* end file simdjson/ppc64/simd.h */ +/* including simdjson/ppc64/stringparsing_defs.h: #include "simdjson/ppc64/stringparsing_defs.h" */ +/* begin file simdjson/ppc64/stringparsing_defs.h */ +#ifndef SIMDJSON_PPC64_STRINGPARSING_DEFS_H +#define SIMDJSON_PPC64_STRINGPARSING_DEFS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/simd.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote + copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { + return ((bs_bits - 1) & quote_bits) != 0; + } + simdjson_inline bool has_backslash() { return bs_bits != 0; } + simdjson_inline int quote_index() { + return trailing_zeroes(quote_bits); + } + simdjson_inline int backslash_index() { + return trailing_zeroes(bs_bits); + } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote +backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 31 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), + "backslash and quote finder must process fewer than " + "SIMDJSON_PADDING bytes"); + simd8 v0(src); + simd8 v1(src + sizeof(v0)); + v0.store(dst); + v1.store(dst + sizeof(v0)); + + // Getting a 64-bit bitmask is much cheaper than multiple 16-bit bitmasks on + // PPC; therefore, we smash them together into a 64-byte mask and get the + // bitmask from there. + uint64_t bs_and_quote = + simd8x64(v0 == '\\', v1 == '\\', v0 == '"', v1 == '"').to_bitmask(); + return { + uint32_t(bs_and_quote), // bs_bits + uint32_t(bs_and_quote >> 32) // quote_bits + }; +} + +} // unnamed namespace +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_PPC64_STRINGPARSING_DEFS_H +/* end file simdjson/ppc64/stringparsing_defs.h */ + +#define SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT 1 +/* end file simdjson/ppc64/begin.h */ +/* including simdjson/generic/ondemand/amalgamated.h for ppc64: #include "simdjson/generic/ondemand/amalgamated.h" */ +/* begin file simdjson/generic/ondemand/amalgamated.h for ppc64 */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H) +#error simdjson/generic/ondemand/dependencies.h must be included before simdjson/generic/ondemand/amalgamated.h! +#endif + +// Stuff other things depend on +/* including simdjson/generic/ondemand/base.h for ppc64: #include "simdjson/generic/ondemand/base.h" */ +/* begin file simdjson/generic/ondemand/base.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +/** + * A fast, simple, DOM-like interface that parses JSON as you use it. + * + * Designed for maximum speed and a lower memory profile. + */ +namespace ondemand { + +/** Represents the depth of a JSON value (number of nested arrays/objects). */ +using depth_t = int32_t; + +/** @copydoc simdjson::ppc64::number_type */ +using number_type = simdjson::ppc64::number_type; + +/** @private Position in the JSON buffer indexes */ +using token_position = const uint32_t *; + +class array; +class array_iterator; +class document; +class document_reference; +class document_stream; +class field; +class json_iterator; +enum class json_type; +struct number; +class object; +class object_iterator; +class parser; +class raw_json_string; +class token_iterator; +class value; +class value_iterator; + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_BASE_H +/* end file simdjson/generic/ondemand/base.h for ppc64 */ +/* including simdjson/generic/ondemand/value_iterator.h for ppc64: #include "simdjson/generic/ondemand/value_iterator.h" */ +/* begin file simdjson/generic/ondemand/value_iterator.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +/** + * Iterates through a single JSON value at a particular depth. + * + * Does not keep track of the type of value: provides methods for objects, arrays and scalars and expects + * the caller to call the right ones. + * + * @private This is not intended for external use. + */ +class value_iterator { +protected: + /** The underlying JSON iterator */ + json_iterator *_json_iter{}; + /** The depth of this value */ + depth_t _depth{}; + /** + * The starting token index for this value + */ + token_position _start_position{}; + +public: + simdjson_inline value_iterator() noexcept = default; + + /** + * Denote that we're starting a document. + */ + simdjson_inline void start_document() noexcept; + + /** + * Skips a non-iterated or partially-iterated JSON value, whether it is a scalar, array or object. + * + * Optimized for scalars. + */ + simdjson_warn_unused simdjson_inline error_code skip_child() noexcept; + + /** + * Tell whether the iterator is at the EOF mark + */ + simdjson_inline bool at_end() const noexcept; + + /** + * Tell whether the iterator is at the start of the value + */ + simdjson_inline bool at_start() const noexcept; + + /** + * Tell whether the value is open--if the value has not been used, or the array/object is still open. + */ + simdjson_inline bool is_open() const noexcept; + + /** + * Tell whether the value is at an object's first field (just after the {). + */ + simdjson_inline bool at_first_field() const noexcept; + + /** + * Abandon all iteration. + */ + simdjson_inline void abandon() noexcept; + + /** + * Get the child value as a value_iterator. + */ + simdjson_inline value_iterator child_value() const noexcept; + + /** + * Get the depth of this value. + */ + simdjson_inline int32_t depth() const noexcept; + + /** + * Get the JSON type of this value. + * + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() const noexcept; + + /** + * @addtogroup object Object iteration + * + * Methods to iterate and find object fields. These methods generally *assume* the value is + * actually an object; the caller is responsible for keeping track of that fact. + * + * @{ + */ + + /** + * Start an object iteration. + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCORRECT_TYPE if there is no opening { + */ + simdjson_warn_unused simdjson_inline simdjson_result start_object() noexcept; + /** + * Start an object iteration from the root. + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCORRECT_TYPE if there is no opening { + * @error TAPE_ERROR if there is no matching } at end of document + */ + simdjson_warn_unused simdjson_inline simdjson_result start_root_object() noexcept; + /** + * Checks whether an object could be started from the root. May be called by start_root_object. + * + * @returns SUCCESS if it is possible to safely start an object from the root (document level). + * @error INCORRECT_TYPE if there is no opening { + * @error TAPE_ERROR if there is no matching } at end of document + */ + simdjson_warn_unused simdjson_inline error_code check_root_object() noexcept; + /** + * Start an object iteration after the user has already checked and moved past the {. + * + * Does not move the iterator unless the object is empty ({}). + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_object() noexcept; + /** + * Start an object iteration from the root, after the user has already checked and moved past the {. + * + * Does not move the iterator unless the object is empty ({}). + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_root_object() noexcept; + + /** + * Moves to the next field in an object. + * + * Looks for , and }. If } is found, the object is finished and the iterator advances past it. + * Otherwise, it advances to the next value. + * + * @return whether there is another field in the object. + * @error TAPE_ERROR If there is a comma missing between fields. + * @error TAPE_ERROR If there is a comma, but not enough tokens remaining to have a key, :, and value. + */ + simdjson_warn_unused simdjson_inline simdjson_result has_next_field() noexcept; + + /** + * Get the current field's key. + */ + simdjson_warn_unused simdjson_inline simdjson_result field_key() noexcept; + + /** + * Pass the : in the field and move to its value. + */ + simdjson_warn_unused simdjson_inline error_code field_value() noexcept; + + /** + * Find the next field with the given key. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline error_code find_field(const std::string_view key) noexcept; + + /** + * Find the next field with the given key, *without* unescaping. This assumes object order: it + * will not find the field if it was already passed when looking for some *other* field. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline simdjson_result find_field_raw(const std::string_view key) noexcept; + + /** + * Find the field with the given key without regard to order, and *without* unescaping. + * + * This is an unordered object lookup: if the field is not found initially, it will cycle around and scan from the beginning. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline simdjson_result find_field_unordered_raw(const std::string_view key) noexcept; + + /** @} */ + + /** + * @addtogroup array Array iteration + * Methods to iterate over array elements. These methods generally *assume* the value is actually + * an object; the caller is responsible for keeping track of that fact. + * @{ + */ + + /** + * Check for an opening [ and start an array iteration. + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCORRECT_TYPE If there is no [. + */ + simdjson_warn_unused simdjson_inline simdjson_result start_array() noexcept; + /** + * Check for an opening [ and start an array iteration while at the root. + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCORRECT_TYPE If there is no [. + * @error TAPE_ERROR if there is no matching ] at end of document + */ + simdjson_warn_unused simdjson_inline simdjson_result start_root_array() noexcept; + /** + * Checks whether an array could be started from the root. May be called by start_root_array. + * + * @returns SUCCESS if it is possible to safely start an array from the root (document level). + * @error INCORRECT_TYPE If there is no [. + * @error TAPE_ERROR if there is no matching ] at end of document + */ + simdjson_warn_unused simdjson_inline error_code check_root_array() noexcept; + /** + * Start an array iteration, after the user has already checked and moved past the [. + * + * Does not move the iterator unless the array is empty ([]). + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_array() noexcept; + /** + * Start an array iteration from the root, after the user has already checked and moved past the [. + * + * Does not move the iterator unless the array is empty ([]). + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_root_array() noexcept; + + /** + * Moves to the next element in an array. + * + * Looks for , and ]. If ] is found, the array is finished and the iterator advances past it. + * Otherwise, it advances to the next value. + * + * @return Whether there is another element in the array. + * @error TAPE_ERROR If there is a comma missing between elements. + */ + simdjson_warn_unused simdjson_inline simdjson_result has_next_element() noexcept; + + /** + * Get a child value iterator. + */ + simdjson_warn_unused simdjson_inline value_iterator child() const noexcept; + + /** @} */ + + /** + * @defgroup scalar Scalar values + * @addtogroup scalar + * @{ + */ + + simdjson_warn_unused simdjson_inline simdjson_result get_string(bool allow_replacement) noexcept; + template + simdjson_warn_unused simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_int64() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_double() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_bool() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_null() noexcept; + simdjson_warn_unused simdjson_inline bool is_negative() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_integer() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + simdjson_warn_unused simdjson_inline simdjson_result get_root_string(bool check_trailing, bool allow_replacement) noexcept; + template + simdjson_warn_unused simdjson_inline error_code get_root_string(string_type& receiver, bool check_trailing, bool allow_replacement) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_wobbly_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_raw_json_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_uint64(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_uint64_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_int64(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_int64_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_double(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_double_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_bool(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline bool is_root_negative() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_root_integer(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_number_type(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_number(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_root_null(bool check_trailing) noexcept; + + simdjson_inline error_code error() const noexcept; + simdjson_inline uint8_t *&string_buf_loc() noexcept; + simdjson_inline const json_iterator &json_iter() const noexcept; + simdjson_inline json_iterator &json_iter() noexcept; + + simdjson_inline void assert_is_valid() const noexcept; + simdjson_inline bool is_valid() const noexcept; + + /** @} */ +protected: + /** + * Restarts an array iteration. + * @returns Whether the array has any elements (returns false for empty). + */ + simdjson_inline simdjson_result reset_array() noexcept; + /** + * Restarts an object iteration. + * @returns Whether the object has any fields (returns false for empty). + */ + simdjson_inline simdjson_result reset_object() noexcept; + /** + * move_at_start(): moves us so that we are pointing at the beginning of + * the container. It updates the index so that at_start() is true and it + * syncs the depth. The user can then create a new container instance. + * + * Usage: used with value::count_elements(). + **/ + simdjson_inline void move_at_start() noexcept; + + /** + * move_at_container_start(): moves us so that we are pointing at the beginning of + * the container so that assert_at_container_start() passes. + * + * Usage: used with reset_array() and reset_object(). + **/ + simdjson_inline void move_at_container_start() noexcept; + /* Useful for debugging and logging purposes. */ + inline std::string to_string() const noexcept; + simdjson_inline value_iterator(json_iterator *json_iter, depth_t depth, token_position start_index) noexcept; + + simdjson_inline simdjson_result parse_null(const uint8_t *json) const noexcept; + simdjson_inline simdjson_result parse_bool(const uint8_t *json) const noexcept; + simdjson_inline const uint8_t *peek_start() const noexcept; + simdjson_inline uint32_t peek_start_length() const noexcept; + + /** + * The general idea of the advance_... methods and the peek_* methods + * is that you first peek and check that you have desired type. If you do, + * and only if you do, then you advance. + * + * We used to unconditionally advance. But this made reasoning about our + * current state difficult. + * Suppose you always advance. Look at the 'value' matching the key + * "shadowable" in the following example... + * + * ({"globals":{"a":{"shadowable":[}}}}) + * + * If the user thinks it is a Boolean and asks for it, then we check the '[', + * decide it is not a Boolean, but still move into the next character ('}'). Now + * we are left pointing at '}' right after a '['. And we have not yet reported + * an error, only that we do not have a Boolean. + * + * If, instead, you just stand your ground until it is content that you know, then + * you will only even move beyond the '[' if the user tells you that you have an + * array. So you will be at the '}' character inside the array and, hopefully, you + * will then catch the error because an array cannot start with '}', but the code + * processing Boolean values does not know this. + * + * So the contract is: first call 'peek_...' and then call 'advance_...' only + * if you have determined that it is a type you can handle. + * + * Unfortunately, it makes the code more verbose, longer and maybe more error prone. + */ + + simdjson_inline void advance_scalar(const char *type) noexcept; + simdjson_inline void advance_root_scalar(const char *type) noexcept; + simdjson_inline void advance_non_root_scalar(const char *type) noexcept; + + simdjson_inline const uint8_t *peek_scalar(const char *type) noexcept; + simdjson_inline const uint8_t *peek_root_scalar(const char *type) noexcept; + simdjson_inline const uint8_t *peek_non_root_scalar(const char *type) noexcept; + + + simdjson_inline error_code start_container(uint8_t start_char, const char *incorrect_type_message, const char *type) noexcept; + simdjson_inline error_code end_container() noexcept; + + /** + * Advance to a place expecting a value (increasing depth). + * + * @return The current token (the one left behind). + * @error TAPE_ERROR If the document ended early. + */ + simdjson_inline simdjson_result advance_to_value() noexcept; + + simdjson_inline error_code incorrect_type_error(const char *message) const noexcept; + simdjson_inline error_code error_unless_more_tokens(uint32_t tokens=1) const noexcept; + + simdjson_inline bool is_at_start() const noexcept; + /** + * is_at_iterator_start() returns true on an array or object after it has just been + * created, whether the instance is empty or not. + * + * Usage: used by array::begin() in debug mode (SIMDJSON_DEVELOPMENT_CHECKS) + */ + simdjson_inline bool is_at_iterator_start() const noexcept; + + /** + * Assuming that we are within an object, this returns true if we + * are pointing at a key. + * + * Usage: the skip_child() method should never be used while we are pointing + * at a key inside an object. + */ + simdjson_inline bool is_at_key() const noexcept; + + inline void assert_at_start() const noexcept; + inline void assert_at_container_start() const noexcept; + inline void assert_at_root() const noexcept; + inline void assert_at_child() const noexcept; + inline void assert_at_next() const noexcept; + inline void assert_at_non_root_start() const noexcept; + + /** Get the starting position of this value */ + simdjson_inline token_position start_position() const noexcept; + + /** @copydoc error_code json_iterator::position() const noexcept; */ + simdjson_inline token_position position() const noexcept; + /** @copydoc error_code json_iterator::end_position() const noexcept; */ + simdjson_inline token_position last_position() const noexcept; + /** @copydoc error_code json_iterator::end_position() const noexcept; */ + simdjson_inline token_position end_position() const noexcept; + /** @copydoc error_code json_iterator::report_error(error_code error, const char *message) noexcept; */ + simdjson_inline error_code report_error(error_code error, const char *message) noexcept; + + friend class document; + friend class object; + friend class array; + friend class value; +}; // value_iterator + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::value_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H +/* end file simdjson/generic/ondemand/value_iterator.h for ppc64 */ +/* including simdjson/generic/ondemand/value.h for ppc64: #include "simdjson/generic/ondemand/value.h" */ +/* begin file simdjson/generic/ondemand/value.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +/** + * An ephemeral JSON value returned during iteration. It is only valid for as long as you do + * not access more data in the JSON document. + */ +class value { +public: + /** + * Create a new invalid value. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline value() noexcept = default; + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * You may use get_double(), get_bool(), get_uint64(), get_int64(), + * get_object(), get_array(), get_raw_json_string(), or get_string() instead. + * + * @returns A value of the given type, parsed from the JSON. + * @returns INCORRECT_TYPE If the JSON value is not the given type. + */ + template simdjson_inline simdjson_result get() noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * @param out This is set to a value of the given type, parsed from the JSON. If there is an error, this may not be initialized. + * @returns INCORRECT_TYPE If the JSON value is not an object. + * @returns SUCCESS If the parse succeeded and the out parameter was set to the value. + */ + template simdjson_inline error_code get(T &out) noexcept; + + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result get_array() noexcept; + + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @returns INCORRECT_TYPE If the JSON value is not an object. + */ + simdjson_inline simdjson_result get_object() noexcept; + + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A unsigned 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64() noexcept; + + /** + * Cast this JSON value (inside string) to a unsigned integer. + * + * @returns A unsigned 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64() noexcept; + + /** + * Cast this JSON value (inside string) to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64_in_string() noexcept; + + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double() noexcept; + + /** + * Cast this JSON value (inside string) to a double + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double_in_string() noexcept; + + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Equivalent to get(). + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + + /** + * Attempts to fill the provided std::string reference with the parsed value of the current string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory. + * We recommend you avoid allocating an std::string unless you need to. + * + * @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS. + */ + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + + /** + * Cast this JSON value to a "wobbly" string. + * + * The string is may not be a valid UTF-8 string. + * See https://simonsapin.github.io/wtf-8/ + * + * Important: a value should be consumed once. Calling get_wobbly_string() twice on the same value + * is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_wobbly_string() noexcept; + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_raw_json_string() noexcept; + + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @returns INCORRECT_TYPE if the JSON value is not true or false. + */ + simdjson_inline simdjson_result get_bool() noexcept; + + /** + * Checks if this JSON value is null. If and only if the value is + * null, then it is consumed (we advance). If we find a token that + * begins with 'n' but is not 'null', then an error is returned. + * + * @returns Whether the value is null. + * @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'. + */ + simdjson_inline simdjson_result is_null() noexcept; + +#if SIMDJSON_EXCEPTIONS + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an array. + */ + simdjson_inline operator array() noexcept(false); + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an object. + */ + simdjson_inline operator object() noexcept(false); + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline operator uint64_t() noexcept(false); + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer. + */ + simdjson_inline operator int64_t() noexcept(false); + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number. + */ + simdjson_inline operator double() noexcept(false); + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Equivalent to get(). + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator std::string_view() noexcept(false); + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator raw_json_string() noexcept(false); + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false. + */ + simdjson_inline operator bool() noexcept(false); +#endif + + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + * + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result begin() & noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() & noexcept; + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * Performance hint: You should only call count_elements() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method on the object instance. + * + * Performance hint: You should only call count_fields() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Get the value at the given index in the array. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) noexcept; + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) noexcept; + + /** + * Get the type of this JSON value. It does not validate or consume the value. + * E.g., you must still call "is_null()" to check that a value is null even if + * "type()" returns json_type::null. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + * + * @return The type of JSON value (json_type::array, json_type::object, json_type::string, + * json_type::number, json_type::boolean, or json_type::null). + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() noexcept; + + /** + * Checks whether the value is a scalar (string, number, null, Boolean). + * Returns false when there it is an array or object. + * + * @returns true if the type is string, number, null, Boolean + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result is_scalar() noexcept; + + /** + * Checks whether the value is a negative number. + * + * @returns true if the number if negative. + */ + simdjson_inline bool is_negative() noexcept; + /** + * Checks whether the value is an integer number. Note that + * this requires to partially parse the number string. If + * the value is determined to be an integer, it may still + * not parse properly as an integer in subsequent steps + * (e.g., it might overflow). + * + * Performance note: if you call this function systematically + * before parsing a number, you may have fallen for a performance + * anti-pattern. + * + * @returns true if the number if negative. + */ + simdjson_inline simdjson_result is_integer() noexcept; + /** + * Determine the number type (integer or floating-point number) as quickly + * as possible. This function does not fully validate the input. It is + * useful when you only need to classify the numbers, without parsing them. + * + * If you are planning to retrieve the value or you need full validation, + * consider using the get_number() method instead: it will fully parse + * and validate the input, and give you access to the type: + * get_number().get_number_type(). + * + * get_number_type() is number_type::unsigned_integer if we have + * an integer greater or equal to 9223372036854775808 + * get_number_type() is number_type::signed_integer if we have an + * integer that is less than 9223372036854775808 + * Otherwise, get_number_type() has value number_type::floating_point_number + * + * This function requires processing the number string, but it is expected + * to be faster than get_number().get_number_type() because it is does not + * parse the number value. + * + * @returns the type of the number + */ + simdjson_inline simdjson_result get_number_type() noexcept; + + /** + * Attempt to parse an ondemand::number. An ondemand::number may + * contain an integer value or a floating-point value, the simdjson + * library will autodetect the type. Thus it is a dynamically typed + * number. Before accessing the value, you must determine the detected + * type. + * + * number.get_number_type() is number_type::signed_integer if we have + * an integer in [-9223372036854775808,9223372036854775808) + * You can recover the value by calling number.get_int64() and you + * have that number.is_int64() is true. + * + * number.get_number_type() is number_type::unsigned_integer if we have + * an integer in [9223372036854775808,18446744073709551616) + * You can recover the value by calling number.get_uint64() and you + * have that number.is_uint64() is true. + * + * Otherwise, number.get_number_type() has value number_type::floating_point_number + * and we have a binary64 number. + * You can recover the value by calling number.get_double() and you + * have that number.is_double() is true. + * + * You must check the type before accessing the value: it is an error + * to call "get_int64()" when number.get_number_type() is not + * number_type::signed_integer and when number.is_int64() is false. + * + * Performance note: this is designed with performance in mind. When + * calling 'get_number()', you scan the number string only once, determining + * efficiently the type and storing it in an efficient manner. + */ + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + + /** + * Get the raw JSON for this token. + * + * The string_view will always point into the input buffer. + * + * The string_view will start at the beginning of the token, and include the entire token + * *as well as all spaces until the next token (or EOF).* This means, for example, that a + * string token always begins with a " and is always terminated by the final ", possibly + * followed by a number of spaces. + * + * The string_view is *not* null-terminated. However, if this is a scalar (string, number, + * boolean, or null), the character after the end of the string_view is guaranteed to be + * a non-space token. + * + * Tokens include: + * - { + * - [ + * - "a string (possibly with UTF-8 or backslashed characters like \\\")". + * - -1.2e-100 + * - true + * - false + * - null + * + * See also value::raw_json(). + */ + simdjson_inline std::string_view raw_json_token() noexcept; + + /** + * Get a string_view pointing at this value in the JSON document. + * If this element is an array or an object, it consumes the array or the object + * and returns a string_view instance corresponding to the + * array as represented in JSON. It points inside the original document. + * If this element is a scalar (string, number, Boolean, null), it returns what + * raw_json_token() would return. + */ + simdjson_inline simdjson_result raw_json() noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + simdjson_inline simdjson_result current_location() noexcept; + + /** + * Returns the current depth in the document if in bounds. + * + * E.g., + * 0 = finished with document + * 1 = document root value (could be [ or {, not yet known) + * 2 = , or } inside root array/object + * 3 = key or value inside root array/object. + */ + simdjson_inline int32_t current_depth() const noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. + * + * Calling at_pointer() on non-document instances (e.g., arrays and objects) is not + * standardized (by RFC 6901). We provide some experimental support for JSON pointers + * on non-document instances. Yet it is not the case when calling at_pointer on an array + * or an object instance: there is no rewind and no invalidation. + * + * You may only call at_pointer on an array after it has been created, but before it has + * been first accessed. When calling at_pointer on an array, the pointer is advanced to + * the location indicated by the JSON pointer (in case of success). It is no longer possible + * to call at_pointer on the same array. + * + * You may call at_pointer more than once on an object, but each time the pointer is advanced + * to be within the value matched by the key indicated by the JSON pointer query. Thus any preceding + * key (as well as the current key) can no longer be used with following JSON pointer calls. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + +protected: + /** + * Create a value. + */ + simdjson_inline value(const value_iterator &iter) noexcept; + + /** + * Skip this value, allowing iteration to continue. + */ + simdjson_inline void skip() noexcept; + + /** + * Start a value at the current position. + * + * (It should already be started; this is just a self-documentation method.) + */ + static simdjson_inline value start(const value_iterator &iter) noexcept; + + /** + * Resume a value. + */ + static simdjson_inline value resume(const value_iterator &iter) noexcept; + + /** + * Get the object, starting or resuming it as necessary + */ + simdjson_inline simdjson_result start_or_resume_object() noexcept; + + // simdjson_inline void log_value(const char *type) const noexcept; + // simdjson_inline void log_error(const char *message) const noexcept; + + value_iterator iter{}; + + friend class document; + friend class array_iterator; + friend class field; + friend class object; + friend struct simdjson_result; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::value &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result get_array() noexcept; + simdjson_inline simdjson_result get_object() noexcept; + + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + + template simdjson_inline simdjson_result get() noexcept; + + template simdjson_inline error_code get(T &out) noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator ppc64::ondemand::array() noexcept(false); + simdjson_inline operator ppc64::ondemand::object() noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator ppc64::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) noexcept; + + /** + * Get the type of this JSON value. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + */ + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + + /** @copydoc simdjson_inline std::string_view value::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + + /** @copydoc simdjson_inline simdjson_result current_location() noexcept */ + simdjson_inline simdjson_result current_location() noexcept; + /** @copydoc simdjson_inline int32_t current_depth() const noexcept */ + simdjson_inline simdjson_result current_depth() const noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_H +/* end file simdjson/generic/ondemand/value.h for ppc64 */ +/* including simdjson/generic/ondemand/logger.h for ppc64: #include "simdjson/generic/ondemand/logger.h" */ +/* begin file simdjson/generic/ondemand/logger.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_LOGGER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_LOGGER_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +// Logging should be free unless SIMDJSON_VERBOSE_LOGGING is set. Importantly, it is critical +// that the call to the log functions be side-effect free. Thus, for example, you should not +// create temporary std::string instances. +namespace logger { + +enum class log_level : int32_t { + info = 0, + error = 1 +}; + +#if SIMDJSON_VERBOSE_LOGGING + static constexpr const bool LOG_ENABLED = true; +#else + static constexpr const bool LOG_ENABLED = false; +#endif + +// We do not want these functions to be 'really inlined' since real inlining is +// for performance purposes and if you are using the loggers, you do not care about +// performance (or should not). +static inline void log_headers() noexcept; +// If args are provided, title will be treated as format string +template +static inline void log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +template +static inline void log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; +static inline void log_event(const json_iterator &iter, const char *type, std::string_view detail="", int delta=0, int depth_delta=0) noexcept; +static inline void log_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail="") noexcept; +static inline void log_value(const json_iterator &iter, const char *type, std::string_view detail="", int delta=-1, int depth_delta=0) noexcept; +static inline void log_start_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail="") noexcept; +static inline void log_start_value(const json_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_end_value(const json_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; + +static inline void log_error(const json_iterator &iter, token_position index, depth_t depth, const char *error, const char *detail="") noexcept; +static inline void log_error(const json_iterator &iter, const char *error, const char *detail="", int delta=-1, int depth_delta=0) noexcept; + +static inline void log_event(const value_iterator &iter, const char *type, std::string_view detail="", int delta=0, int depth_delta=0) noexcept; +static inline void log_value(const value_iterator &iter, const char *type, std::string_view detail="", int delta=-1, int depth_delta=0) noexcept; +static inline void log_start_value(const value_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_end_value(const value_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_error(const value_iterator &iter, const char *error, const char *detail="", int delta=-1, int depth_delta=0) noexcept; + +} // namespace logger +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_LOGGER_H +/* end file simdjson/generic/ondemand/logger.h for ppc64 */ +/* including simdjson/generic/ondemand/token_iterator.h for ppc64: #include "simdjson/generic/ondemand/token_iterator.h" */ +/* begin file simdjson/generic/ondemand/token_iterator.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +/** + * Iterates through JSON tokens (`{` `}` `[` `]` `,` `:` `""` `123` `true` `false` `null`) + * detected by stage 1. + * + * @private This is not intended for external use. + */ +class token_iterator { +public: + /** + * Create a new invalid token_iterator. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline token_iterator() noexcept = default; + simdjson_inline token_iterator(token_iterator &&other) noexcept = default; + simdjson_inline token_iterator &operator=(token_iterator &&other) noexcept = default; + simdjson_inline token_iterator(const token_iterator &other) noexcept = default; + simdjson_inline token_iterator &operator=(const token_iterator &other) noexcept = default; + + /** + * Advance to the next token (returning the current one). + */ + simdjson_inline const uint8_t *return_current_and_advance() noexcept; + /** + * Reports the current offset in bytes from the start of the underlying buffer. + */ + simdjson_inline uint32_t current_offset() const noexcept; + /** + * Get the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(int32_t delta=0) const noexcept; + /** + * Get the maximum length of the JSON text for a given token. + * + * The length will include any whitespace at the end of the token. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_length(int32_t delta=0) const noexcept; + + /** + * Get the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token. + * + */ + simdjson_inline const uint8_t *peek(token_position position) const noexcept; + /** + * Get the maximum length of the JSON text for a given token. + * + * The length will include any whitespace at the end of the token. + * + * @param position The position of the token. + */ + simdjson_inline uint32_t peek_length(token_position position) const noexcept; + + /** + * Return the current index. + */ + simdjson_inline token_position position() const noexcept; + /** + * Reset to a previously saved index. + */ + simdjson_inline void set_position(token_position target_position) noexcept; + + // NOTE: we don't support a full C++ iterator interface, because we expect people to make + // different calls to advance the iterator based on *their own* state. + + simdjson_inline bool operator==(const token_iterator &other) const noexcept; + simdjson_inline bool operator!=(const token_iterator &other) const noexcept; + simdjson_inline bool operator>(const token_iterator &other) const noexcept; + simdjson_inline bool operator>=(const token_iterator &other) const noexcept; + simdjson_inline bool operator<(const token_iterator &other) const noexcept; + simdjson_inline bool operator<=(const token_iterator &other) const noexcept; + +protected: + simdjson_inline token_iterator(const uint8_t *buf, token_position position) noexcept; + + /** + * Get the index of the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_index(int32_t delta=0) const noexcept; + /** + * Get the index of the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token. + * + */ + simdjson_inline uint32_t peek_index(token_position position) const noexcept; + + const uint8_t *buf{}; + token_position _position{}; + + friend class json_iterator; + friend class value_iterator; + friend class object; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +}; + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::token_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H +/* end file simdjson/generic/ondemand/token_iterator.h for ppc64 */ +/* including simdjson/generic/ondemand/json_iterator.h for ppc64: #include "simdjson/generic/ondemand/json_iterator.h" */ +/* begin file simdjson/generic/ondemand/json_iterator.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +/** + * Iterates through JSON tokens, keeping track of depth and string buffer. + * + * @private This is not intended for external use. + */ +class json_iterator { +protected: + token_iterator token{}; + ondemand::parser *parser{}; + /** + * Next free location in the string buffer. + * + * Used by raw_json_string::unescape() to have a place to unescape strings to. + */ + uint8_t *_string_buf_loc{}; + /** + * JSON error, if there is one. + * + * INCORRECT_TYPE and NO_SUCH_FIELD are *not* stored here, ever. + * + * PERF NOTE: we *hope* this will be elided into control flow, as it is only used (a) in the first + * iteration of the loop, or (b) for the final iteration after a missing comma is found in ++. If + * this is not elided, we should make sure it's at least not using up a register. Failing that, + * we should store it in document so there's only one of them. + */ + error_code error{SUCCESS}; + /** + * Depth of the current token in the JSON. + * + * - 0 = finished with document + * - 1 = document root value (could be [ or {, not yet known) + * - 2 = , or } inside root array/object + * - 3 = key or value inside root array/object. + */ + depth_t _depth{}; + /** + * Beginning of the document indexes. + * Normally we have root == parser->implementation->structural_indexes.get() + * but this may differ, especially in streaming mode (where we have several + * documents); + */ + token_position _root{}; + /** + * Normally, a json_iterator operates over a single document, but in + * some cases, we may have a stream of documents. This attribute is meant + * as meta-data: the json_iterator works the same irrespective of the + * value of this attribute. + */ + bool _streaming{false}; + +public: + simdjson_inline json_iterator() noexcept = default; + simdjson_inline json_iterator(json_iterator &&other) noexcept; + simdjson_inline json_iterator &operator=(json_iterator &&other) noexcept; + simdjson_inline explicit json_iterator(const json_iterator &other) noexcept = default; + simdjson_inline json_iterator &operator=(const json_iterator &other) noexcept = default; + /** + * Skips a JSON value, whether it is a scalar, array or object. + */ + simdjson_warn_unused simdjson_inline error_code skip_child(depth_t parent_depth) noexcept; + + /** + * Tell whether the iterator is still at the start + */ + simdjson_inline bool at_root() const noexcept; + + /** + * Tell whether we should be expected to run in streaming + * mode (iterating over many documents). It is pure metadata + * that does not affect how the iterator works. It is used by + * start_root_array() and start_root_object(). + */ + simdjson_inline bool streaming() const noexcept; + + /** + * Get the root value iterator + */ + simdjson_inline token_position root_position() const noexcept; + /** + * Assert that we are at the document depth (== 1) + */ + simdjson_inline void assert_at_document_depth() const noexcept; + /** + * Assert that we are at the root of the document + */ + simdjson_inline void assert_at_root() const noexcept; + + /** + * Tell whether the iterator is at the EOF mark + */ + simdjson_inline bool at_end() const noexcept; + + /** + * Tell whether the iterator is live (has not been moved). + */ + simdjson_inline bool is_alive() const noexcept; + + /** + * Abandon this iterator, setting depth to 0 (as if the document is finished). + */ + simdjson_inline void abandon() noexcept; + + /** + * Advance the current token without modifying depth. + */ + simdjson_inline const uint8_t *return_current_and_advance() noexcept; + + /** + * Returns true if there is a single token in the index (i.e., it is + * a JSON with a scalar value such as a single number). + * + * @return whether there is a single token + */ + simdjson_inline bool is_single_token() const noexcept; + + /** + * Assert that there are at least the given number of tokens left. + * + * Has no effect in release builds. + */ + simdjson_inline void assert_more_tokens(uint32_t required_tokens=1) const noexcept; + /** + * Assert that the given position addresses an actual token (is within bounds). + * + * Has no effect in release builds. + */ + simdjson_inline void assert_valid_position(token_position position) const noexcept; + /** + * Get the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = next token, -1 = prev token. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(int32_t delta=0) const noexcept; + /** + * Get the maximum length of the JSON text for the current token (or relative). + * + * The length will include any whitespace at the end of the token. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_length(int32_t delta=0) const noexcept; + /** + * Get a pointer to the current location in the input buffer. + * + * This is not null-terminated; it is a view into the JSON. + * + * You may be pointing outside of the input buffer: it is not generally + * safe to dereference this pointer. + */ + simdjson_inline const uint8_t *unsafe_pointer() const noexcept; + /** + * Get the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token to retrieve. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(token_position position) const noexcept; + /** + * Get the maximum length of the JSON text for the current token (or relative). + * + * The length will include any whitespace at the end of the token. + * + * @param position The position of the token to retrieve. + */ + simdjson_inline uint32_t peek_length(token_position position) const noexcept; + /** + * Get the JSON text for the last token in the document. + * + * This is not null-terminated; it is a view into the JSON. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek_last() const noexcept; + + /** + * Ascend one level. + * + * Validates that the depth - 1 == parent_depth. + * + * @param parent_depth the expected parent depth. + */ + simdjson_inline void ascend_to(depth_t parent_depth) noexcept; + + /** + * Descend one level. + * + * Validates that the new depth == child_depth. + * + * @param child_depth the expected child depth. + */ + simdjson_inline void descend_to(depth_t child_depth) noexcept; + simdjson_inline void descend_to(depth_t child_depth, int32_t delta) noexcept; + + /** + * Get current depth. + */ + simdjson_inline depth_t depth() const noexcept; + + /** + * Get current (writeable) location in the string buffer. + */ + simdjson_inline uint8_t *&string_buf_loc() noexcept; + + /** + * Report an unrecoverable error, preventing further iteration. + * + * @param error The error to report. Must not be SUCCESS, UNINITIALIZED, INCORRECT_TYPE, or NO_SUCH_FIELD. + * @param message An error message to report with the error. + */ + simdjson_inline error_code report_error(error_code error, const char *message) noexcept; + + /** + * Log error, but don't stop iteration. + * @param error The error to report. Must be INCORRECT_TYPE, or NO_SUCH_FIELD. + * @param message An error message to report with the error. + */ + simdjson_inline error_code optional_error(error_code error, const char *message) noexcept; + + /** + * Take an input in json containing max_len characters and attempt to copy it over to tmpbuf, a buffer with + * N bytes of capacity. It will return false if N is too small (smaller than max_len) of if it is zero. + * The buffer (tmpbuf) is padded with space characters. + */ + simdjson_warn_unused simdjson_inline bool copy_to_buffer(const uint8_t *json, uint32_t max_len, uint8_t *tmpbuf, size_t N) noexcept; + + simdjson_inline token_position position() const noexcept; + /** + * Write the raw_json_string to the string buffer and return a string_view. + * Each raw_json_string should be unescaped once, or else the string buffer might + * overflow. + */ + simdjson_inline simdjson_result unescape(raw_json_string in, bool allow_replacement) noexcept; + simdjson_inline simdjson_result unescape_wobbly(raw_json_string in) noexcept; + + simdjson_inline void reenter_child(token_position position, depth_t child_depth) noexcept; + + simdjson_inline error_code consume_character(char c) noexcept; +#if SIMDJSON_DEVELOPMENT_CHECKS + simdjson_inline token_position start_position(depth_t depth) const noexcept; + simdjson_inline void set_start_position(depth_t depth, token_position position) noexcept; +#endif + + /* Useful for debugging and logging purposes. */ + inline std::string to_string() const noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + inline simdjson_result current_location() const noexcept; + + /** + * Updates this json iterator so that it is back at the beginning of the document, + * as if it had just been created. + */ + inline void rewind() noexcept; + /** + * This checks whether the {,},[,] are balanced so that the document + * ends with proper zero depth. This requires scanning the whole document + * and it may be expensive. It is expected that it will be rarely called. + * It does not attempt to match { with } and [ with ]. + */ + inline bool balanced() const noexcept; +protected: + simdjson_inline json_iterator(const uint8_t *buf, ondemand::parser *parser) noexcept; + /// The last token before the end + simdjson_inline token_position last_position() const noexcept; + /// The token *at* the end. This points at gibberish and should only be used for comparison. + simdjson_inline token_position end_position() const noexcept; + /// The end of the buffer. + simdjson_inline token_position end() const noexcept; + + friend class document; + friend class document_stream; + friend class object; + friend class array; + friend class value; + friend class raw_json_string; + friend class parser; + friend class value_iterator; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +}; // json_iterator + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::json_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H +/* end file simdjson/generic/ondemand/json_iterator.h for ppc64 */ +/* including simdjson/generic/ondemand/json_type.h for ppc64: #include "simdjson/generic/ondemand/json_type.h" */ +/* begin file simdjson/generic/ondemand/json_type.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/numberparsing.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +/** + * The type of a JSON value. + */ +enum class json_type { + // Start at 1 to catch uninitialized / default values more easily + array=1, ///< A JSON array ( [ 1, 2, 3 ... ] ) + object, ///< A JSON object ( { "a": 1, "b" 2, ... } ) + number, ///< A JSON number ( 1 or -2.3 or 4.5e6 ...) + string, ///< A JSON string ( "a" or "hello world\n" ...) + boolean, ///< A JSON boolean (true or false) + null ///< A JSON null (null) +}; + +/** + * A type representing a JSON number. + * The design of the struct is deliberately straight-forward. All + * functions return standard values with no error check. + */ +struct number { + + /** + * return the automatically determined type of + * the number: number_type::floating_point_number, + * number_type::signed_integer or number_type::unsigned_integer. + * + * enum class number_type { + * floating_point_number=1, /// a binary64 number + * signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + * unsigned_integer /// a positive integer larger or equal to 1<<63 + * }; + */ + simdjson_inline ondemand::number_type get_number_type() const noexcept; + /** + * return true if the automatically determined type of + * the number is number_type::unsigned_integer. + */ + simdjson_inline bool is_uint64() const noexcept; + /** + * return the value as a uint64_t, only valid if is_uint64() is true. + */ + simdjson_inline uint64_t get_uint64() const noexcept; + simdjson_inline operator uint64_t() const noexcept; + + /** + * return true if the automatically determined type of + * the number is number_type::signed_integer. + */ + simdjson_inline bool is_int64() const noexcept; + /** + * return the value as a int64_t, only valid if is_int64() is true. + */ + simdjson_inline int64_t get_int64() const noexcept; + simdjson_inline operator int64_t() const noexcept; + + + /** + * return true if the automatically determined type of + * the number is number_type::floating_point_number. + */ + simdjson_inline bool is_double() const noexcept; + /** + * return the value as a double, only valid if is_double() is true. + */ + simdjson_inline double get_double() const noexcept; + simdjson_inline operator double() const noexcept; + + /** + * Convert the number to a double. Though it always succeed, the conversion + * may be lossy if the number cannot be represented exactly. + */ + simdjson_inline double as_double() const noexcept; + + +protected: + /** + * The next block of declaration is designed so that we can call the number parsing + * functions on a number type. They are protected and should never be used outside + * of the core simdjson library. + */ + friend class value_iterator; + template + friend error_code numberparsing::write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer); + template + friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer); + /** Store a signed 64-bit value to the number. */ + simdjson_inline void append_s64(int64_t value) noexcept; + /** Store an unsigned 64-bit value to the number. */ + simdjson_inline void append_u64(uint64_t value) noexcept; + /** Store a double value to the number. */ + simdjson_inline void append_double(double value) noexcept; + /** Specifies that the value is a double, but leave it undefined. */ + simdjson_inline void skip_double() noexcept; + /** + * End of friend declarations. + */ + + /** + * Our attributes are a union type (size = 64 bits) + * followed by a type indicator. + */ + union { + double floating_point_number; + int64_t signed_integer; + uint64_t unsigned_integer; + } payload{0}; + number_type type{number_type::signed_integer}; +}; + +/** + * Write the JSON type to the output stream + * + * @param out The output stream. + * @param type The json_type. + */ +inline std::ostream& operator<<(std::ostream& out, json_type type) noexcept; + +#if SIMDJSON_EXCEPTIONS +/** + * Send JSON type to an output stream. + * + * @param out The output stream. + * @param type The json_type. + * @throw simdjson_error if the result being printed has an error. If there is an error with the + * underlying output stream, that error will be propagated (simdjson_error will not be + * thrown). + */ +inline std::ostream& operator<<(std::ostream& out, simdjson_result &type) noexcept(false); +#endif + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::json_type &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H +/* end file simdjson/generic/ondemand/json_type.h for ppc64 */ +/* including simdjson/generic/ondemand/raw_json_string.h for ppc64: #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* begin file simdjson/generic/ondemand/raw_json_string.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +/** + * A string escaped per JSON rules, terminated with quote ("). They are used to represent + * unescaped keys inside JSON documents. + * + * (In other words, a pointer to the beginning of a string, just after the start quote, inside a + * JSON file.) + * + * This class is deliberately simplistic and has little functionality. You can + * compare a raw_json_string instance with an unescaped C string, but + * that is nearly all you can do. + * + * The raw_json_string is unescaped. If you wish to write an unescaped version of it to your own + * buffer, you may do so using the parser.unescape(string, buff) method, using an ondemand::parser + * instance. Doing so requires you to have a sufficiently large buffer. + * + * The raw_json_string instances originate typically from field instance which in turn represent + * key-value pairs from object instances. From a field instance, you get the raw_json_string + * instance by calling key(). You can, if you want a more usable string_view instance, call + * the unescaped_key() method on the field instance. You may also create a raw_json_string from + * any other string value, with the value.get_raw_json_string() method. Again, you can get + * a more usable string_view instance by calling get_string(). + * + */ +class raw_json_string { +public: + /** + * Create a new invalid raw_json_string. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline raw_json_string() noexcept = default; + + /** + * Create a new invalid raw_json_string pointed at the given location in the JSON. + * + * The given location must be just *after* the beginning quote (") in the JSON file. + * + * It *must* be terminated by a ", and be a valid JSON string. + */ + simdjson_inline raw_json_string(const uint8_t * _buf) noexcept; + /** + * Get the raw pointer to the beginning of the string in the JSON (just after the "). + * + * It is possible for this function to return a null pointer if the instance + * has outlived its existence. + */ + simdjson_inline const char * raw() const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done) on target.size() characters, + * and if the raw_json_string instance has a quote character at byte index target.size(). + * We never read more than length + 1 bytes in the raw_json_string instance. + * If length is smaller than target.size(), this will return false. + * + * The std::string_view instance may contain any characters. However, the caller + * is responsible for setting length so that length bytes may be read in the + * raw_json_string. + * + * Performance: the comparison may be done using memcmp which may be efficient + * for long strings. + */ + simdjson_inline bool unsafe_is_equal(size_t length, std::string_view target) const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done). + * The std::string_view instance should not contain unescaped quote characters: + * the caller is responsible for this check. See is_free_from_unescaped_quote. + * + * Performance: the comparison is done byte-by-byte which might be inefficient for + * long strings. + * + * If target is a compile-time constant, and your compiler likes you, + * you should be able to do the following without performance penalty... + * + * static_assert(raw_json_string::is_free_from_unescaped_quote(target), ""); + * s.unsafe_is_equal(target); + */ + simdjson_inline bool unsafe_is_equal(std::string_view target) const noexcept; + + /** + * This compares the current instance to the C string target: returns true if + * they are byte-by-byte equal (no escaping is done). + * The provided C string should not contain an unescaped quote character: + * the caller is responsible for this check. See is_free_from_unescaped_quote. + * + * If target is a compile-time constant, and your compiler likes you, + * you should be able to do the following without performance penalty... + * + * static_assert(raw_json_string::is_free_from_unescaped_quote(target), ""); + * s.unsafe_is_equal(target); + */ + simdjson_inline bool unsafe_is_equal(const char* target) const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done). + */ + simdjson_inline bool is_equal(std::string_view target) const noexcept; + + /** + * This compares the current instance to the C string target: returns true if + * they are byte-by-byte equal (no escaping is done). + */ + simdjson_inline bool is_equal(const char* target) const noexcept; + + /** + * Returns true if target is free from unescaped quote. If target is known at + * compile-time, we might expect the computation to happen at compile time with + * many compilers (not all!). + */ + static simdjson_inline bool is_free_from_unescaped_quote(std::string_view target) noexcept; + static simdjson_inline bool is_free_from_unescaped_quote(const char* target) noexcept; + +private: + + + /** + * This will set the inner pointer to zero, effectively making + * this instance unusable. + */ + simdjson_inline void consume() noexcept { buf = nullptr; } + + /** + * Checks whether the inner pointer is non-null and thus usable. + */ + simdjson_inline simdjson_warn_unused bool alive() const noexcept { return buf != nullptr; } + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. + * The result will be a valid UTF-8. + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid until the next parse() call on the parser. + * + * @param iter A json_iterator, which contains a buffer where the string will be written. + * @param allow_replacement Whether we allow replacement of invalid surrogate pairs. + */ + simdjson_inline simdjson_warn_unused simdjson_result unescape(json_iterator &iter, bool allow_replacement) const noexcept; + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. + * The result may not be a valid UTF-8. https://simonsapin.github.io/wtf-8/ + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid until the next parse() call on the parser. + * + * @param iter A json_iterator, which contains a buffer where the string will be written. + */ + simdjson_inline simdjson_warn_unused simdjson_result unescape_wobbly(json_iterator &iter) const noexcept; + const uint8_t * buf{}; + friend class object; + friend class field; + friend class parser; + friend struct simdjson_result; +}; + +simdjson_unused simdjson_inline std::ostream &operator<<(std::ostream &, const raw_json_string &) noexcept; + +/** + * Comparisons between raw_json_string and std::string_view instances are potentially unsafe: the user is responsible + * for providing a string with no unescaped quote. Note that unescaped quotes cannot be present in valid JSON strings. + */ +simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept; +simdjson_unused simdjson_inline bool operator==(std::string_view c, const raw_json_string &a) noexcept; +simdjson_unused simdjson_inline bool operator!=(const raw_json_string &a, std::string_view c) noexcept; +simdjson_unused simdjson_inline bool operator!=(std::string_view c, const raw_json_string &a) noexcept; + + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::raw_json_string &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private + + simdjson_inline simdjson_result raw() const noexcept; + simdjson_inline simdjson_warn_unused simdjson_result unescape(ppc64::ondemand::json_iterator &iter, bool allow_replacement) const noexcept; + simdjson_inline simdjson_warn_unused simdjson_result unescape_wobbly(ppc64::ondemand::json_iterator &iter) const noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H +/* end file simdjson/generic/ondemand/raw_json_string.h for ppc64 */ +/* including simdjson/generic/ondemand/parser.h for ppc64: #include "simdjson/generic/ondemand/parser.h" */ +/* begin file simdjson/generic/ondemand/parser.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_PARSER_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +/** + * The default batch size for document_stream instances for this On Demand kernel. + * Note that different On Demand kernel may use a different DEFAULT_BATCH_SIZE value + * in the future. + */ +static constexpr size_t DEFAULT_BATCH_SIZE = 1000000; +/** + * Some adversary might try to set the batch size to 0 or 1, which might cause problems. + * We set a minimum of 32B since anything else is highly likely to be an error. In practice, + * most users will want a much larger batch size. + * + * All non-negative MINIMAL_BATCH_SIZE values should be 'safe' except that, obviously, no JSON + * document can ever span 0 or 1 byte and that very large values would create memory allocation issues. + */ +static constexpr size_t MINIMAL_BATCH_SIZE = 32; + +/** + * A JSON fragment iterator. + * + * This holds the actual iterator as well as the buffer for writing strings. + */ +class parser { +public: + /** + * Create a JSON parser. + * + * The new parser will have zero capacity. + */ + inline explicit parser(size_t max_capacity = SIMDJSON_MAXSIZE_BYTES) noexcept; + + inline parser(parser &&other) noexcept = default; + simdjson_inline parser(const parser &other) = delete; + simdjson_inline parser &operator=(const parser &other) = delete; + simdjson_inline parser &operator=(parser &&other) noexcept = default; + + /** Deallocate the JSON parser. */ + inline ~parser() noexcept = default; + + /** + * Start iterating an on-demand JSON document. + * + * ondemand::parser parser; + * document doc = parser.iterate(json); + * + * It is expected that the content is a valid UTF-8 file, containing a valid JSON document. + * Otherwise the iterate method may return an error. In particular, the whole input should be + * valid: we do not attempt to tolerate incorrect content either before or after a JSON + * document. If there is a UTF-8 BOM, the parser skips it. + * + * ### IMPORTANT: Validate what you use + * + * Calling iterate on an invalid JSON document may not immediately trigger an error. The call to + * iterate does not parse and validate the whole document. + * + * ### IMPORTANT: Buffer Lifetime + * + * Because parsing is done while you iterate, you *must* keep the JSON buffer around at least as + * long as the document iteration. + * + * ### IMPORTANT: Document Lifetime + * + * Only one iteration at a time can happen per parser, and the parser *must* be kept alive during + * iteration to ensure intermediate buffers can be accessed. Any document must be destroyed before + * you call parse() again or destroy the parser. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * @param json The JSON to parse. + * @param len The length of the JSON. + * @param capacity The number of bytes allocated in the JSON (must be at least len+SIMDJSON_PADDING). + * + * @return The document, or an error: + * - INSUFFICIENT_PADDING if the input has less than SIMDJSON_PADDING extra bytes. + * - MEMALLOC if realloc_if_needed the parser does not have enough capacity, and memory + * allocation fails. + * - EMPTY if the document is all whitespace. + * - UTF8_ERROR if the document is not valid UTF-8. + * - UNESCAPED_CHARS if a string contains control characters that must be escaped + * - UNCLOSED_STRING if there is an unclosed string in the document. + */ + simdjson_warn_unused simdjson_result iterate(padded_string_view json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const char *json, size_t len, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const uint8_t *json, size_t len, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(std::string_view json, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const std::string &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(std::string &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const simdjson_result &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const simdjson_result &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(padded_string &&json) & noexcept = delete; + + /** + * @private + * + * Start iterating an on-demand JSON document. + * + * ondemand::parser parser; + * json_iterator doc = parser.iterate(json); + * + * ### IMPORTANT: Buffer Lifetime + * + * Because parsing is done while you iterate, you *must* keep the JSON buffer around at least as + * long as the document iteration. + * + * ### IMPORTANT: Document Lifetime + * + * Only one iteration at a time can happen per parser, and the parser *must* be kept alive during + * iteration to ensure intermediate buffers can be accessed. Any document must be destroyed before + * you call parse() again or destroy the parser. + * + * The ondemand::document instance holds the iterator. The document must remain in scope + * while you are accessing instances of ondemand::value, ondemand::object, ondemand::array. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * @param json The JSON to parse. + * + * @return The iterator, or an error: + * - INSUFFICIENT_PADDING if the input has less than SIMDJSON_PADDING extra bytes. + * - MEMALLOC if realloc_if_needed the parser does not have enough capacity, and memory + * allocation fails. + * - EMPTY if the document is all whitespace. + * - UTF8_ERROR if the document is not valid UTF-8. + * - UNESCAPED_CHARS if a string contains control characters that must be escaped + * - UNCLOSED_STRING if there is an unclosed string in the document. + */ + simdjson_warn_unused simdjson_result iterate_raw(padded_string_view json) & noexcept; + + + /** + * Parse a buffer containing many JSON documents. + * + * auto json = R"({ "foo": 1 } { "foo": 2 } { "foo": 3 } )"_padded; + * ondemand::parser parser; + * ondemand::document_stream docs = parser.iterate_many(json); + * for (auto & doc : docs) { + * std::cout << doc["foo"] << std::endl; + * } + * // Prints 1 2 3 + * + * No copy of the input buffer is made. + * + * The function is lazy: it may be that no more than one JSON document at a time is parsed. + * + * The caller is responsabile to ensure that the input string data remains unchanged and is + * not deleted during the loop. + * + * ### Format + * + * The buffer must contain a series of one or more JSON documents, concatenated into a single + * buffer, separated by ASCII whitespace. It effectively parses until it has a fully valid document, + * then starts parsing the next document at that point. (It does this with more parallelism and + * lookahead than you might think, though.) + * + * documents that consist of an object or array may omit the whitespace between them, concatenating + * with no separator. Documents that consist of a single primitive (i.e. documents that are not + * arrays or objects) MUST be separated with ASCII whitespace. + * + * The characters inside a JSON document, and between JSON documents, must be valid Unicode (UTF-8). + * If there is a UTF-8 BOM, the parser skips it. + * + * The documents must not exceed batch_size bytes (by default 1MB) or they will fail to parse. + * Setting batch_size to excessively large or excessively small values may impact negatively the + * performance. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * ### Threads + * + * When compiled with SIMDJSON_THREADS_ENABLED, this method will use a single thread under the + * hood to do some lookahead. + * + * ### Parser Capacity + * + * If the parser's current capacity is less than batch_size, it will allocate enough capacity + * to handle it (up to max_capacity). + * + * @param buf The concatenated JSON to parse. + * @param len The length of the concatenated JSON. + * @param batch_size The batch size to use. MUST be larger than the largest document. The sweet + * spot is cache-related: small enough to fit in cache, yet big enough to + * parse as many documents as possible in one tight loop. + * Defaults to 10MB, which has been a reasonable sweet spot in our tests. + * @param allow_comma_separated (defaults on false) This allows a mode where the documents are + * separated by commas instead of whitespace. It comes with a performance + * penalty because the entire document is indexed at once (and the document must be + * less than 4 GB), and there is no multithreading. In this mode, the batch_size parameter + * is effectively ignored, as it is set to at least the document size. + * @return The stream, or an error. An empty input will yield 0 documents rather than an EMPTY error. Errors: + * - MEMALLOC if the parser does not have enough capacity and memory allocation fails + * - CAPACITY if the parser does not have enough capacity and batch_size > max_capacity. + * - other json errors if parsing fails. You should not rely on these errors to always the same for the + * same document: they may vary under runtime dispatch (so they may vary depending on your system and hardware). + */ + inline simdjson_result iterate_many(const uint8_t *buf, size_t len, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const char *buf, size_t len, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const std::string &s, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + inline simdjson_result iterate_many(const std::string &&s, size_t batch_size, bool allow_comma_separated = false) = delete;// unsafe + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const padded_string &s, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + inline simdjson_result iterate_many(const padded_string &&s, size_t batch_size, bool allow_comma_separated = false) = delete;// unsafe + + /** @private We do not want to allow implicit conversion from C string to std::string. */ + simdjson_result iterate_many(const char *buf, size_t batch_size = DEFAULT_BATCH_SIZE) noexcept = delete; + + /** The capacity of this parser (the largest document it can process). */ + simdjson_inline size_t capacity() const noexcept; + /** The maximum capacity of this parser (the largest document it is allowed to process). */ + simdjson_inline size_t max_capacity() const noexcept; + simdjson_inline void set_max_capacity(size_t max_capacity) noexcept; + /** + * The maximum depth of this parser (the most deeply nested objects and arrays it can process). + * This parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true. + * The document's instance current_depth() method should be used to monitor the parsing + * depth and limit it if desired. + */ + simdjson_inline size_t max_depth() const noexcept; + + /** + * Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length + * and `max_depth` depth. + * + * The max_depth parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true. + * The document's instance current_depth() method should be used to monitor the parsing + * depth and limit it if desired. + * + * @param capacity The new capacity. + * @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH. + * @return The error, if there is one. + */ + simdjson_warn_unused error_code allocate(size_t capacity, size_t max_depth=DEFAULT_MAX_DEPTH) noexcept; + + #ifdef SIMDJSON_THREADS_ENABLED + /** + * The parser instance can use threads when they are available to speed up some + * operations. It is enabled by default. Changing this attribute will change the + * behavior of the parser for future operations. + */ + bool threaded{true}; + #endif + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. to a user-provided buffer. + * The result must be valid UTF-8. + * The provided pointer is advanced to the end of the string by reference, and a string_view instance + * is returned. You can ensure that your buffer is large enough by allocating a block of memory at least + * as large as the input JSON plus SIMDJSON_PADDING and then unescape all strings to this one buffer. + * + * This unescape function is a low-level function. If you want a more user-friendly approach, you should + * avoid raw_json_string instances (e.g., by calling unescaped_key() instead of key() or get_string() + * instead of get_raw_json_string()). + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid as long as the bytes in dst. + * + * @param raw_json_string input + * @param dst A pointer to a buffer at least large enough to write this string as well as + * an additional SIMDJSON_PADDING bytes. + * @param allow_replacement Whether we allow a replacement if the input string contains unmatched surrogate pairs. + * @return A string_view pointing at the unescaped string in dst + * @error STRING_ERROR if escapes are incorrect. + */ + simdjson_inline simdjson_result unescape(raw_json_string in, uint8_t *&dst, bool allow_replacement = false) const noexcept; + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. to a user-provided buffer. + * The result may not be valid UTF-8. See https://simonsapin.github.io/wtf-8/ + * The provided pointer is advanced to the end of the string by reference, and a string_view instance + * is returned. You can ensure that your buffer is large enough by allocating a block of memory at least + * as large as the input JSON plus SIMDJSON_PADDING and then unescape all strings to this one buffer. + * + * This unescape function is a low-level function. If you want a more user-friendly approach, you should + * avoid raw_json_string instances (e.g., by calling unescaped_key() instead of key() or get_string() + * instead of get_raw_json_string()). + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid as long as the bytes in dst. + * + * @param raw_json_string input + * @param dst A pointer to a buffer at least large enough to write this string as well as + * an additional SIMDJSON_PADDING bytes. + * @return A string_view pointing at the unescaped string in dst + * @error STRING_ERROR if escapes are incorrect. + */ + simdjson_inline simdjson_result unescape_wobbly(raw_json_string in, uint8_t *&dst) const noexcept; + +private: + /** @private [for benchmarking access] The implementation to use */ + std::unique_ptr implementation{}; + size_t _capacity{0}; + size_t _max_capacity; + size_t _max_depth{DEFAULT_MAX_DEPTH}; + std::unique_ptr string_buf{}; +#if SIMDJSON_DEVELOPMENT_CHECKS + std::unique_ptr start_positions{}; +#endif + + friend class json_iterator; + friend class document_stream; +}; + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::parser &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_PARSER_H +/* end file simdjson/generic/ondemand/parser.h for ppc64 */ + +// All other declarations +/* including simdjson/generic/ondemand/array.h for ppc64: #include "simdjson/generic/ondemand/array.h" */ +/* begin file simdjson/generic/ondemand/array.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +/** + * A forward-only JSON array. + */ +class array { +public: + /** + * Create a new invalid array. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline array() noexcept = default; + + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result begin() noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() noexcept; + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an array is empty, it is more performant to use + * the is_empty() method. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the beginning of the array and checks whether the + * array is empty. + * The runtime complexity is constant time. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + simdjson_inline simdjson_result is_empty() & noexcept; + /** + * Reset the iterator so that we are pointing back at the + * beginning of the array. You should still consume values only once even if you + * can iterate through the array more than once. If you unescape a string + * within the array more than once, you have unsafe code. Note that rewinding + * an array means that you may need to reparse it anew: it is not a free + * operation. + * + * @returns true if the array contains some elements (not empty) + */ + inline simdjson_result reset() & noexcept; + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard, interpreting the current node + * as the root of its own JSON document. + * + * ondemand::parser parser; + * auto json = R"([ { "foo": { "a": [ 10, 20, 30 ] }} ])"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/0/foo/a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. Yet it is not the case when calling at_pointer on an array + * instance: there is no rewind and no invalidation. + * + * You may only call at_pointer on an array after it has been created, but before it has + * been first accessed. When calling at_pointer on an array, the pointer is advanced to + * the location indicated by the JSON pointer (in case of success). It is no longer possible + * to call at_pointer on the same array. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching. + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + /** + * Consumes the array and returns a string_view instance corresponding to the + * array as represented in JSON. It points inside the original document. + */ + simdjson_inline simdjson_result raw_json() noexcept; + + /** + * Get the value at the given index. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) noexcept; +protected: + /** + * Go to the end of the array, no matter where you are right now. + */ + simdjson_inline error_code consume() noexcept; + + /** + * Begin array iteration. + * + * @param iter The iterator. Must be where the initial [ is expected. Will be *moved* into the + * resulting array. + * @error INCORRECT_TYPE if the iterator is not at [. + */ + static simdjson_inline simdjson_result start(value_iterator &iter) noexcept; + /** + * Begin array iteration from the root. + * + * @param iter The iterator. Must be where the initial [ is expected. Will be *moved* into the + * resulting array. + * @error INCORRECT_TYPE if the iterator is not at [. + * @error TAPE_ERROR if there is no closing ] at the end of the document. + */ + static simdjson_inline simdjson_result start_root(value_iterator &iter) noexcept; + /** + * Begin array iteration. + * + * This version of the method should be called after the initial [ has been verified, and is + * intended for use by switch statements that check the type of a value. + * + * @param iter The iterator. Must be after the initial [. Will be *moved* into the resulting array. + */ + static simdjson_inline simdjson_result started(value_iterator &iter) noexcept; + + /** + * Create an array at the given Internal array creation. Call array::start() or array::started() instead of this. + * + * @param iter The iterator. Must either be at the start of the first element with iter.is_alive() + * == true, or past the [] with is_alive() == false if the array is empty. Will be *moved* + * into the resulting array. + */ + simdjson_inline array(const value_iterator &iter) noexcept; + + /** + * Iterator marking current position. + * + * iter.is_alive() == false indicates iteration is complete. + */ + value_iterator iter{}; + + friend class value; + friend class document; + friend struct simdjson_result; + friend struct simdjson_result; + friend class array_iterator; +}; + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::array &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + inline simdjson_result count_elements() & noexcept; + inline simdjson_result is_empty() & noexcept; + inline simdjson_result reset() & noexcept; + simdjson_inline simdjson_result at(size_t index) noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_H +/* end file simdjson/generic/ondemand/array.h for ppc64 */ +/* including simdjson/generic/ondemand/array_iterator.h for ppc64: #include "simdjson/generic/ondemand/array_iterator.h" */ +/* begin file simdjson/generic/ondemand/array_iterator.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +/** + * A forward-only JSON array. + * + * This is an input_iterator, meaning: + * - It is forward-only + * - * must be called exactly once per element. + * - ++ must be called exactly once in between each * (*, ++, *, ++, * ...) + */ +class array_iterator { +public: + /** Create a new, invalid array iterator. */ + simdjson_inline array_iterator() noexcept = default; + + // + // Iterator interface + // + + /** + * Get the current element. + * + * Part of the std::iterator interface. + */ + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + /** + * Check if we are at the end of the JSON. + * + * Part of the std::iterator interface. + * + * @return true if there are no more elements in the JSON array. + */ + simdjson_inline bool operator==(const array_iterator &) const noexcept; + /** + * Check if there are more elements in the JSON array. + * + * Part of the std::iterator interface. + * + * @return true if there are more elements in the JSON array. + */ + simdjson_inline bool operator!=(const array_iterator &) const noexcept; + /** + * Move to the next element. + * + * Part of the std::iterator interface. + */ + simdjson_inline array_iterator &operator++() noexcept; + +private: + value_iterator iter{}; + + simdjson_inline array_iterator(const value_iterator &iter) noexcept; + + friend class array; + friend class value; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::array_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + // + // Iterator interface + // + + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + simdjson_inline bool operator==(const simdjson_result &) const noexcept; + simdjson_inline bool operator!=(const simdjson_result &) const noexcept; + simdjson_inline simdjson_result &operator++() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H +/* end file simdjson/generic/ondemand/array_iterator.h for ppc64 */ +/* including simdjson/generic/ondemand/document.h for ppc64: #include "simdjson/generic/ondemand/document.h" */ +/* begin file simdjson/generic/ondemand/document.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +/** + * A JSON document. It holds a json_iterator instance. + * + * Used by tokens to get text, and string buffer location. + * + * You must keep the document around during iteration. + */ +class document { +public: + /** + * Create a new invalid document. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline document() noexcept = default; + simdjson_inline document(const document &other) noexcept = delete; // pass your documents by reference, not by copy + simdjson_inline document(document &&other) noexcept = default; + simdjson_inline document &operator=(const document &other) noexcept = delete; + simdjson_inline document &operator=(document &&other) noexcept = default; + + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result get_array() & noexcept; + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @returns INCORRECT_TYPE If the JSON value is not an object. + */ + simdjson_inline simdjson_result get_object() & noexcept; + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64() noexcept; + /** + * Cast this JSON value (inside string) to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64() noexcept; + /** + * Cast this JSON value (inside string) to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64_in_string() noexcept; + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double() noexcept; + + /** + * Cast this JSON value (inside string) to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double_in_string() noexcept; + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: Calling get_string() twice on the same document is an error. + * + * @param Whether to allow a replacement character for unmatched surrogate pairs. + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + /** + * Attempts to fill the provided std::string reference with the parsed value of the current string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory. + * We recommend you avoid allocating an std::string unless you need to. + * + * @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS. + */ + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + /** + * Cast this JSON value to a string. + * + * The string is not guaranteed to be valid UTF-8. See https://simonsapin.github.io/wtf-8/ + * + * Important: Calling get_wobbly_string() twice on the same document is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_wobbly_string() noexcept; + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_raw_json_string() noexcept; + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @returns INCORRECT_TYPE if the JSON value is not true or false. + */ + simdjson_inline simdjson_result get_bool() noexcept; + /** + * Cast this JSON value to a value when the document is an object or an array. + * + * You must not have begun iterating through the object or array. When + * SIMDJSON_DEVELOPMENT_CHECKS is set to 1 (which is the case when building in Debug mode + * by default), and you have already begun iterating, + * you will get an OUT_OF_ORDER_ITERATION error. If you have begun iterating, you can use + * rewind() to reset the document to its initial state before calling this method. + * + * @returns A value if a JSON array or object cannot be found. + * @returns SCALAR_DOCUMENT_AS_VALUE error is the document is a scalar (see is_scalar() function). + */ + simdjson_inline simdjson_result get_value() noexcept; + + /** + * Checks if this JSON value is null. If and only if the value is + * null, then it is consumed (we advance). If we find a token that + * begins with 'n' but is not 'null', then an error is returned. + * + * @returns Whether the value is null. + * @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'. + */ + simdjson_inline simdjson_result is_null() noexcept; + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * You may use get_double(), get_bool(), get_uint64(), get_int64(), + * get_object(), get_array(), get_raw_json_string(), or get_string() instead. + * + * @returns A value of the given type, parsed from the JSON. + * @returns INCORRECT_TYPE If the JSON value is not the given type. + */ + template simdjson_inline simdjson_result get() & noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + /** @overload template simdjson_result get() & noexcept */ + template simdjson_inline simdjson_result get() && noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool, value + * + * Be mindful that the document instance must remain in scope while you are accessing object, array and value instances. + * + * @param out This is set to a value of the given type, parsed from the JSON. If there is an error, this may not be initialized. + * @returns INCORRECT_TYPE If the JSON value is not an object. + * @returns SUCCESS If the parse succeeded and the out parameter was set to the value. + */ + template simdjson_inline error_code get(T &out) & noexcept; + /** @overload template error_code get(T &out) & noexcept */ + template simdjson_inline error_code get(T &out) && noexcept; + +#if SIMDJSON_EXCEPTIONS + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an array. + */ + simdjson_inline operator array() & noexcept(false); + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an object. + */ + simdjson_inline operator object() & noexcept(false); + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline operator uint64_t() noexcept(false); + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer. + */ + simdjson_inline operator int64_t() noexcept(false); + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number. + */ + simdjson_inline operator double() noexcept(false); + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator std::string_view() noexcept(false); + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator raw_json_string() noexcept(false); + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false. + */ + simdjson_inline operator bool() noexcept(false); + /** + * Cast this JSON value to a value when the document is an object or an array. + * + * You must not have begun iterating through the object or array. When + * SIMDJSON_DEVELOPMENT_CHECKS is defined, and you have already begun iterating, + * you will get an OUT_OF_ORDER_ITERATION error. If you have begun iterating, you can use + * rewind() to reset the document to its initial state before calling this method. + * + * @returns A value value if a JSON array or object cannot be found. + * @exception SCALAR_DOCUMENT_AS_VALUE error is the document is a scalar (see is_scalar() function). + */ + simdjson_inline operator value() noexcept(false); +#endif + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Get the value at the given index in the array. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) & noexcept; + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result begin() & noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() & noexcept; + + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. E.g., the array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to + * a key a single time. Doing object["mykey"].to_string()and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. E.g., the array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a key + * a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + + /** + * Get the type of this JSON value. It does not validate or consume the value. + * E.g., you must still call "is_null()" to check that a value is null even if + * "type()" returns json_type::null. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + * + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() noexcept; + + /** + * Checks whether the document is a scalar (string, number, null, Boolean). + * Returns false when there it is an array or object. + * + * @returns true if the type is string, number, null, Boolean + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result is_scalar() noexcept; + + /** + * Checks whether the document is a negative number. + * + * @returns true if the number if negative. + */ + simdjson_inline bool is_negative() noexcept; + /** + * Checks whether the document is an integer number. Note that + * this requires to partially parse the number string. If + * the value is determined to be an integer, it may still + * not parse properly as an integer in subsequent steps + * (e.g., it might overflow). + * + * @returns true if the number if negative. + */ + simdjson_inline simdjson_result is_integer() noexcept; + /** + * Determine the number type (integer or floating-point number) as quickly + * as possible. This function does not fully validate the input. It is + * useful when you only need to classify the numbers, without parsing them. + * + * If you are planning to retrieve the value or you need full validation, + * consider using the get_number() method instead: it will fully parse + * and validate the input, and give you access to the type: + * get_number().get_number_type(). + * + * get_number_type() is number_type::unsigned_integer if we have + * an integer greater or equal to 9223372036854775808 + * get_number_type() is number_type::signed_integer if we have an + * integer that is less than 9223372036854775808 + * Otherwise, get_number_type() has value number_type::floating_point_number + * + * This function requires processing the number string, but it is expected + * to be faster than get_number().get_number_type() because it is does not + * parse the number value. + * + * @returns the type of the number + */ + simdjson_inline simdjson_result get_number_type() noexcept; + + /** + * Attempt to parse an ondemand::number. An ondemand::number may + * contain an integer value or a floating-point value, the simdjson + * library will autodetect the type. Thus it is a dynamically typed + * number. Before accessing the value, you must determine the detected + * type. + * + * number.get_number_type() is number_type::signed_integer if we have + * an integer in [-9223372036854775808,9223372036854775808) + * You can recover the value by calling number.get_int64() and you + * have that number.is_int64() is true. + * + * number.get_number_type() is number_type::unsigned_integer if we have + * an integer in [9223372036854775808,18446744073709551616) + * You can recover the value by calling number.get_uint64() and you + * have that number.is_uint64() is true. + * + * Otherwise, number.get_number_type() has value number_type::floating_point_number + * and we have a binary64 number. + * You can recover the value by calling number.get_double() and you + * have that number.is_double() is true. + * + * You must check the type before accessing the value: it is an error + * to call "get_int64()" when number.get_number_type() is not + * number_type::signed_integer and when number.is_int64() is false. + */ + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + /** + * Get the raw JSON for this token. + * + * The string_view will always point into the input buffer. + * + * The string_view will start at the beginning of the token, and include the entire token + * *as well as all spaces until the next token (or EOF).* This means, for example, that a + * string token always begins with a " and is always terminated by the final ", possibly + * followed by a number of spaces. + * + * The string_view is *not* null-terminated. If this is a scalar (string, number, + * boolean, or null), the character after the end of the string_view may be the padded buffer. + * + * Tokens include: + * - { + * - [ + * - "a string (possibly with UTF-8 or backslashed characters like \\\")". + * - -1.2e-100 + * - true + * - false + * - null + */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + /** + * Reset the iterator inside the document instance so we are pointing back at the + * beginning of the document, as if it had just been created. It invalidates all + * values, objects and arrays that you have created so far (including unescaped strings). + */ + inline void rewind() noexcept; + /** + * Returns debugging information. + */ + inline std::string to_debug_string() noexcept; + /** + * Some unrecoverable error conditions may render the document instance unusable. + * The is_alive() method returns true when the document is still suitable. + */ + inline bool is_alive() noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + inline simdjson_result current_location() const noexcept; + + /** + * Returns true if this document has been fully parsed. + * If you have consumed the whole document and at_end() returns + * false, then there may be trailing content. + */ + inline bool at_end() const noexcept; + + /** + * Returns the current depth in the document if in bounds. + * + * E.g., + * 0 = finished with document + * 1 = document root value (could be [ or {, not yet known) + * 2 = , or } inside root array/object + * 3 = key or value inside root array/object. + */ + simdjson_inline int32_t current_depth() const noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() automatically calls rewind between each call. Thus + * all values, objects and arrays that you have created so far (including unescaped strings) + * are invalidated. After calling at_pointer, you need to consume the result: string values + * should be stored in your own variables, arrays should be decoded and stored in your own array-like + * structures and so forth. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + * - SCALAR_DOCUMENT_AS_VALUE if the json_pointer is empty and the document is not a scalar (see is_scalar() function). + */ + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + /** + * Consumes the document and returns a string_view instance corresponding to the + * document as represented in JSON. It points inside the original byte array containing + * the JSON document. + */ + simdjson_inline simdjson_result raw_json() noexcept; +protected: + /** + * Consumes the document. + */ + simdjson_inline error_code consume() noexcept; + + simdjson_inline document(ondemand::json_iterator &&iter) noexcept; + simdjson_inline const uint8_t *text(uint32_t idx) const noexcept; + + simdjson_inline value_iterator resume_value_iterator() noexcept; + simdjson_inline value_iterator get_root_value_iterator() noexcept; + simdjson_inline simdjson_result start_or_resume_object() noexcept; + static simdjson_inline document start(ondemand::json_iterator &&iter) noexcept; + + // + // Fields + // + json_iterator iter{}; ///< Current position in the document + static constexpr depth_t DOCUMENT_DEPTH = 0; ///< document depth is always 0 + + friend class array_iterator; + friend class value; + friend class ondemand::parser; + friend class object; + friend class array; + friend class field; + friend class token; + friend class document_stream; + friend class document_reference; +}; + + +/** + * A document_reference is a thin wrapper around a document reference instance. + */ +class document_reference { +public: + simdjson_inline document_reference() noexcept; + simdjson_inline document_reference(document &d) noexcept; + simdjson_inline document_reference(const document_reference &other) noexcept = default; + simdjson_inline document_reference& operator=(const document_reference &other) noexcept = default; + simdjson_inline void rewind() noexcept; + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + + simdjson_inline simdjson_result is_null() noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + simdjson_inline operator document&() const noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator array() & noexcept(false); + simdjson_inline operator object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline int32_t current_depth() const noexcept; + simdjson_inline bool is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + simdjson_inline simdjson_result raw_json_token() noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +private: + document *doc{nullptr}; +}; +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::document &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline error_code rewind() noexcept; + + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + + template simdjson_inline simdjson_result get() & noexcept; + template simdjson_inline simdjson_result get() && noexcept; + + template simdjson_inline error_code get(T &out) & noexcept; + template simdjson_inline error_code get(T &out) && noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator ppc64::ondemand::array() & noexcept(false); + simdjson_inline operator ppc64::ondemand::object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator ppc64::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator ppc64::ondemand::value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline int32_t current_depth() const noexcept; + simdjson_inline bool at_end() const noexcept; + simdjson_inline bool is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + /** @copydoc simdjson_inline std::string_view document::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + + +} // namespace simdjson + + + +namespace simdjson { + +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::document_reference value, error_code error) noexcept; + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline error_code rewind() noexcept; + + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator ppc64::ondemand::array() & noexcept(false); + simdjson_inline operator ppc64::ondemand::object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator ppc64::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator ppc64::ondemand::value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline simdjson_result current_depth() const noexcept; + simdjson_inline simdjson_result is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + /** @copydoc simdjson_inline std::string_view document_reference::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H +/* end file simdjson/generic/ondemand/document.h for ppc64 */ +/* including simdjson/generic/ondemand/document_stream.h for ppc64: #include "simdjson/generic/ondemand/document_stream.h" */ +/* begin file simdjson/generic/ondemand/document_stream.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#ifdef SIMDJSON_THREADS_ENABLED +#include +#include +#include +#endif + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +#ifdef SIMDJSON_THREADS_ENABLED +/** @private Custom worker class **/ +struct stage1_worker { + stage1_worker() noexcept = default; + stage1_worker(const stage1_worker&) = delete; + stage1_worker(stage1_worker&&) = delete; + stage1_worker operator=(const stage1_worker&) = delete; + ~stage1_worker(); + /** + * We only start the thread when it is needed, not at object construction, this may throw. + * You should only call this once. + **/ + void start_thread(); + /** + * Start a stage 1 job. You should first call 'run', then 'finish'. + * You must call start_thread once before. + */ + void run(document_stream * ds, parser * stage1, size_t next_batch_start); + /** Wait for the run to finish (blocking). You should first call 'run', then 'finish'. **/ + void finish(); + +private: + + /** + * Normally, we would never stop the thread. But we do in the destructor. + * This function is only safe assuming that you are not waiting for results. You + * should have called run, then finish, and be done. + **/ + void stop_thread(); + + std::thread thread{}; + /** These three variables define the work done by the thread. **/ + ondemand::parser * stage1_thread_parser{}; + size_t _next_batch_start{}; + document_stream * owner{}; + /** + * We have two state variables. This could be streamlined to one variable in the future but + * we use two for clarity. + */ + bool has_work{false}; + bool can_work{true}; + + /** + * We lock using a mutex. + */ + std::mutex locking_mutex{}; + std::condition_variable cond_var{}; + + friend class document_stream; +}; +#endif // SIMDJSON_THREADS_ENABLED + +/** + * A forward-only stream of documents. + * + * Produced by parser::iterate_many. + * + */ +class document_stream { +public: + /** + * Construct an uninitialized document_stream. + * + * ```c++ + * document_stream docs; + * auto error = parser.iterate_many(json).get(docs); + * ``` + */ + simdjson_inline document_stream() noexcept; + /** Move one document_stream to another. */ + simdjson_inline document_stream(document_stream &&other) noexcept = default; + /** Move one document_stream to another. */ + simdjson_inline document_stream &operator=(document_stream &&other) noexcept = default; + + simdjson_inline ~document_stream() noexcept; + + /** + * Returns the input size in bytes. + */ + inline size_t size_in_bytes() const noexcept; + + /** + * After iterating through the stream, this method + * returns the number of bytes that were not parsed at the end + * of the stream. If truncated_bytes() differs from zero, + * then the input was truncated maybe because incomplete JSON + * documents were found at the end of the stream. You + * may need to process the bytes in the interval [size_in_bytes()-truncated_bytes(), size_in_bytes()). + * + * You should only call truncated_bytes() after streaming through all + * documents, like so: + * + * document_stream stream = parser.iterate_many(json,window); + * for(auto & doc : stream) { + * // do something with doc + * } + * size_t truncated = stream.truncated_bytes(); + * + */ + inline size_t truncated_bytes() const noexcept; + + class iterator { + public: + using value_type = simdjson_result; + using reference = value_type; + + using difference_type = std::ptrdiff_t; + + using iterator_category = std::input_iterator_tag; + + /** + * Default constructor. + */ + simdjson_inline iterator() noexcept; + /** + * Get the current document (or error). + */ + simdjson_inline simdjson_result operator*() noexcept; + /** + * Advance to the next document (prefix). + */ + inline iterator& operator++() noexcept; + /** + * Check if we're at the end yet. + * @param other the end iterator to compare to. + */ + simdjson_inline bool operator!=(const iterator &other) const noexcept; + /** + * @private + * + * Gives the current index in the input document in bytes. + * + * document_stream stream = parser.parse_many(json,window); + * for(auto i = stream.begin(); i != stream.end(); ++i) { + * auto doc = *i; + * size_t index = i.current_index(); + * } + * + * This function (current_index()) is experimental and the usage + * may change in future versions of simdjson: we find the API somewhat + * awkward and we would like to offer something friendlier. + */ + simdjson_inline size_t current_index() const noexcept; + + /** + * @private + * + * Gives a view of the current document at the current position. + * + * document_stream stream = parser.iterate_many(json,window); + * for(auto i = stream.begin(); i != stream.end(); ++i) { + * std::string_view v = i.source(); + * } + * + * The returned string_view instance is simply a map to the (unparsed) + * source string: it may thus include white-space characters and all manner + * of padding. + * + * This function (source()) is experimental and the usage + * may change in future versions of simdjson: we find the API somewhat + * awkward and we would like to offer something friendlier. + * + */ + simdjson_inline std::string_view source() const noexcept; + + /** + * Returns error of the stream (if any). + */ + inline error_code error() const noexcept; + + private: + simdjson_inline iterator(document_stream *s, bool finished) noexcept; + /** The document_stream we're iterating through. */ + document_stream* stream; + /** Whether we're finished or not. */ + bool finished; + + friend class document; + friend class document_stream; + friend class json_iterator; + }; + + /** + * Start iterating the documents in the stream. + */ + simdjson_inline iterator begin() noexcept; + /** + * The end of the stream, for iterator comparison purposes. + */ + simdjson_inline iterator end() noexcept; + +private: + + document_stream &operator=(const document_stream &) = delete; // Disallow copying + document_stream(const document_stream &other) = delete; // Disallow copying + + /** + * Construct a document_stream. Does not allocate or parse anything until the iterator is + * used. + * + * @param parser is a reference to the parser instance used to generate this document_stream + * @param buf is the raw byte buffer we need to process + * @param len is the length of the raw byte buffer in bytes + * @param batch_size is the size of the windows (must be strictly greater or equal to the largest JSON document) + */ + simdjson_inline document_stream( + ondemand::parser &parser, + const uint8_t *buf, + size_t len, + size_t batch_size, + bool allow_comma_separated + ) noexcept; + + /** + * Parse the first document in the buffer. Used by begin(), to handle allocation and + * initialization. + */ + inline void start() noexcept; + + /** + * Parse the next document found in the buffer previously given to document_stream. + * + * The content should be a valid JSON document encoded as UTF-8. If there is a + * UTF-8 BOM, the parser skips it. + * + * You do NOT need to pre-allocate a parser. This function takes care of + * pre-allocating a capacity defined by the batch_size defined when creating the + * document_stream object. + * + * The function returns simdjson::EMPTY if there is no more data to be parsed. + * + * The function returns simdjson::SUCCESS (as integer = 0) in case of success + * and indicates that the buffer has successfully been parsed to the end. + * Every document it contained has been parsed without error. + * + * The function returns an error code from simdjson/simdjson.h in case of failure + * such as simdjson::CAPACITY, simdjson::MEMALLOC, simdjson::DEPTH_ERROR and so forth; + * the simdjson::error_message function converts these error codes into a string). + * + * You can also check validity by calling parser.is_valid(). The same parser can + * and should be reused for the other documents in the buffer. + */ + inline void next() noexcept; + + /** Move the json_iterator of the document to the location of the next document in the stream. */ + inline void next_document() noexcept; + + /** Get the next document index. */ + inline size_t next_batch_start() const noexcept; + + /** Pass the next batch through stage 1 with the given parser. */ + inline error_code run_stage1(ondemand::parser &p, size_t batch_start) noexcept; + + // Fields + ondemand::parser *parser; + const uint8_t *buf; + size_t len; + size_t batch_size; + bool allow_comma_separated; + /** + * We are going to use just one document instance. The document owns + * the json_iterator. It implies that we only ever pass a reference + * to the document to the users. + */ + document doc{}; + /** The error (or lack thereof) from the current document. */ + error_code error; + size_t batch_start{0}; + size_t doc_index{}; + + #ifdef SIMDJSON_THREADS_ENABLED + /** Indicates whether we use threads. Note that this needs to be a constant during the execution of the parsing. */ + bool use_thread; + + inline void load_from_stage1_thread() noexcept; + + /** Start a thread to run stage 1 on the next batch. */ + inline void start_stage1_thread() noexcept; + + /** Wait for the stage 1 thread to finish and capture the results. */ + inline void finish_stage1_thread() noexcept; + + /** The error returned from the stage 1 thread. */ + error_code stage1_thread_error{UNINITIALIZED}; + /** The thread used to run stage 1 against the next batch in the background. */ + std::unique_ptr worker{new(std::nothrow) stage1_worker()}; + /** + * The parser used to run stage 1 in the background. Will be swapped + * with the regular parser when finished. + */ + ondemand::parser stage1_thread_parser{}; + + friend struct stage1_worker; + #endif // SIMDJSON_THREADS_ENABLED + + friend class parser; + friend class document; + friend class json_iterator; + friend struct simdjson_result; + friend struct internal::simdjson_result_base; +}; // document_stream + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::document_stream &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H +/* end file simdjson/generic/ondemand/document_stream.h for ppc64 */ +/* including simdjson/generic/ondemand/field.h for ppc64: #include "simdjson/generic/ondemand/field.h" */ +/* begin file simdjson/generic/ondemand/field.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_FIELD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_FIELD_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +/** + * A JSON field (key/value pair) in an object. + * + * Returned from object iteration. + * + * Extends from std::pair so you can use C++ algorithms that rely on pairs. + */ +class field : public std::pair { +public: + /** + * Create a new invalid field. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline field() noexcept; + + /** + * Get the key as a string_view (for higher speed, consider raw_key). + * We deliberately use a more cumbersome name (unescaped_key) to force users + * to think twice about using it. + * + * This consumes the key: once you have called unescaped_key(), you cannot + * call it again nor can you call key(). + */ + simdjson_inline simdjson_warn_unused simdjson_result unescaped_key(bool allow_replacement) noexcept; + /** + * Get the key as a raw_json_string. Can be used for direct comparison with + * an unescaped C string: e.g., key() == "test". + */ + simdjson_inline raw_json_string key() const noexcept; + /** + * Get the field value. + */ + simdjson_inline ondemand::value &value() & noexcept; + /** + * @overload ondemand::value &ondemand::value() & noexcept + */ + simdjson_inline ondemand::value value() && noexcept; + +protected: + simdjson_inline field(raw_json_string key, ondemand::value &&value) noexcept; + static simdjson_inline simdjson_result start(value_iterator &parent_iter) noexcept; + static simdjson_inline simdjson_result start(const value_iterator &parent_iter, raw_json_string key) noexcept; + friend struct simdjson_result; + friend class object_iterator; +}; + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::field &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result unescaped_key(bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result key() noexcept; + simdjson_inline simdjson_result value() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_FIELD_H +/* end file simdjson/generic/ondemand/field.h for ppc64 */ +/* including simdjson/generic/ondemand/object.h for ppc64: #include "simdjson/generic/ondemand/object.h" */ +/* begin file simdjson/generic/ondemand/object.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +/** + * A forward-only JSON object field iterator. + */ +class object { +public: + /** + * Create a new invalid object. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline object() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. The value instance you get + * from `content["bids"]` becomes invalid when you call `content["asks"]`. The array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a + * key a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field(std::string_view key) && noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. The value instance you get + * from `content["bids"]` becomes invalid when you call `content["asks"]`. The array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a key + * a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) && noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) && noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard, interpreting the current node + * as the root of its own JSON document. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. Yet it is not the case when calling at_pointer on an object + * instance: there is no rewind and no invalidation. + * + * You may call at_pointer more than once on an object, but each time the pointer is advanced + * to be within the value matched by the key indicated by the JSON pointer query. Thus any preceding + * key (as well as the current key) can no longer be used with following JSON pointer calls. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching. + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + + /** + * Reset the iterator so that we are pointing back at the + * beginning of the object. You should still consume values only once even if you + * can iterate through the object more than once. If you unescape a string within + * the object more than once, you have unsafe code. Note that rewinding an object + * means that you may need to reparse it anew: it is not a free operation. + * + * @returns true if the object contains some elements (not empty) + */ + inline simdjson_result reset() & noexcept; + /** + * This method scans the beginning of the object and checks whether the + * object is empty. + * The runtime complexity is constant time. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + inline simdjson_result is_empty() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method. + * + * Performance hint: You should only call count_fields() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Consumes the object and returns a string_view instance corresponding to the + * object as represented in JSON. It points inside the original byte array containing + * the JSON document. + */ + simdjson_inline simdjson_result raw_json() noexcept; + +protected: + /** + * Go to the end of the object, no matter where you are right now. + */ + simdjson_inline error_code consume() noexcept; + static simdjson_inline simdjson_result start(value_iterator &iter) noexcept; + static simdjson_inline simdjson_result start_root(value_iterator &iter) noexcept; + static simdjson_inline simdjson_result started(value_iterator &iter) noexcept; + static simdjson_inline object resume(const value_iterator &iter) noexcept; + simdjson_inline object(const value_iterator &iter) noexcept; + + simdjson_warn_unused simdjson_inline error_code find_field_raw(const std::string_view key) noexcept; + + value_iterator iter{}; + + friend class value; + friend class document; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::object &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) && noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) && noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) && noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + inline simdjson_result reset() noexcept; + inline simdjson_result is_empty() noexcept; + inline simdjson_result count_fields() & noexcept; + inline simdjson_result raw_json() noexcept; + +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_H +/* end file simdjson/generic/ondemand/object.h for ppc64 */ +/* including simdjson/generic/ondemand/object_iterator.h for ppc64: #include "simdjson/generic/ondemand/object_iterator.h" */ +/* begin file simdjson/generic/ondemand/object_iterator.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +class object_iterator { +public: + /** + * Create a new invalid object_iterator. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline object_iterator() noexcept = default; + + // + // Iterator interface + // + + // Reads key and value, yielding them to the user. + // MUST ONLY BE CALLED ONCE PER ITERATION. + simdjson_inline simdjson_result operator*() noexcept; + // Assumes it's being compared with the end. true if depth < iter->depth. + simdjson_inline bool operator==(const object_iterator &) const noexcept; + // Assumes it's being compared with the end. true if depth >= iter->depth. + simdjson_inline bool operator!=(const object_iterator &) const noexcept; + // Checks for ']' and ',' + simdjson_inline object_iterator &operator++() noexcept; + +private: + /** + * The underlying JSON iterator. + * + * PERF NOTE: expected to be elided in favor of the parent document: this is set when the object + * is first used, and never changes afterwards. + */ + value_iterator iter{}; + + simdjson_inline object_iterator(const value_iterator &iter) noexcept; + friend struct simdjson_result; + friend class object; +}; + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public ppc64::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(ppc64::ondemand::object_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + // + // Iterator interface + // + + // Reads key and value, yielding them to the user. + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + // Assumes it's being compared with the end. true if depth < iter->depth. + simdjson_inline bool operator==(const simdjson_result &) const noexcept; + // Assumes it's being compared with the end. true if depth >= iter->depth. + simdjson_inline bool operator!=(const simdjson_result &) const noexcept; + // Checks for ']' and ',' + simdjson_inline simdjson_result &operator++() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H +/* end file simdjson/generic/ondemand/object_iterator.h for ppc64 */ +/* including simdjson/generic/ondemand/serialization.h for ppc64: #include "simdjson/generic/ondemand/serialization.h" */ +/* begin file simdjson/generic/ondemand/serialization.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Create a string-view instance out of a document instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(ppc64::ondemand::document& x) noexcept; +/** + * Create a string-view instance out of a value instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. The value must + * not have been accessed previously. It does not + * validate the content. + */ +inline simdjson_result to_json_string(ppc64::ondemand::value& x) noexcept; +/** + * Create a string-view instance out of an object instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(ppc64::ondemand::object& x) noexcept; +/** + * Create a string-view instance out of an array instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(ppc64::ondemand::array& x) noexcept; +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +} // namespace simdjson + +/** + * We want to support argument-dependent lookup (ADL). + * Hence we should define operator<< in the namespace + * where the argument (here value, object, etc.) resides. + * Credit: @madhur4127 + * See https://github.com/simdjson/simdjson/issues/1768 + */ +namespace simdjson { namespace ppc64 { namespace ondemand { + +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The element. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::ppc64::ondemand::value x); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The array. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::ppc64::ondemand::array value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The array. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::ppc64::ondemand::document& value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x); +#endif +inline std::ostream& operator<<(std::ostream& out, simdjson::ppc64::ondemand::document_reference& value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The object. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::ppc64::ondemand::object value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +}}} // namespace simdjson::ppc64::ondemand + +#endif // SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H +/* end file simdjson/generic/ondemand/serialization.h for ppc64 */ + +// Inline definitions +/* including simdjson/generic/ondemand/array-inl.h for ppc64: #include "simdjson/generic/ondemand/array-inl.h" */ +/* begin file simdjson/generic/ondemand/array-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +// +// ### Live States +// +// While iterating or looking up values, depth >= iter->depth. at_start may vary. Error is +// always SUCCESS: +// +// - Start: This is the state when the array is first found and the iterator is just past the `{`. +// In this state, at_start == true. +// - Next: After we hand a scalar value to the user, or an array/object which they then fully +// iterate over, the iterator is at the `,` before the next value (or `]`). In this state, +// depth == iter->depth, at_start == false, and error == SUCCESS. +// - Unfinished Business: When we hand an array/object to the user which they do not fully +// iterate over, we need to finish that iteration by skipping child values until we reach the +// Next state. In this state, depth > iter->depth, at_start == false, and error == SUCCESS. +// +// ## Error States +// +// In error states, we will yield exactly one more value before stopping. iter->depth == depth +// and at_start is always false. We decrement after yielding the error, moving to the Finished +// state. +// +// - Chained Error: When the array iterator is part of an error chain--for example, in +// `for (auto tweet : doc["tweets"])`, where the tweet element may be missing or not be an +// array--we yield that error in the loop, exactly once. In this state, error != SUCCESS and +// iter->depth == depth, and at_start == false. We decrement depth when we yield the error. +// - Missing Comma Error: When the iterator ++ method discovers there is no comma between elements, +// we flag that as an error and treat it exactly the same as a Chained Error. In this state, +// error == TAPE_ERROR, iter->depth == depth, and at_start == false. +// +// ## Terminal State +// +// The terminal state has iter->depth < depth. at_start is always false. +// +// - Finished: When we have reached a `]` or have reported an error, we are finished. We signal this +// by decrementing depth. In this state, iter->depth < depth, at_start == false, and +// error == SUCCESS. +// + +simdjson_inline array::array(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} + +simdjson_inline simdjson_result array::start(value_iterator &iter) noexcept { + // We don't need to know if the array is empty to start iteration, but we do want to know if there + // is an error--thus `simdjson_unused`. + simdjson_unused bool has_value; + SIMDJSON_TRY( iter.start_array().get(has_value) ); + return array(iter); +} +simdjson_inline simdjson_result array::start_root(value_iterator &iter) noexcept { + simdjson_unused bool has_value; + SIMDJSON_TRY( iter.start_root_array().get(has_value) ); + return array(iter); +} +simdjson_inline simdjson_result array::started(value_iterator &iter) noexcept { + bool has_value; + SIMDJSON_TRY(iter.started_array().get(has_value)); + return array(iter); +} + +simdjson_inline simdjson_result array::begin() noexcept { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + return array_iterator(iter); +} +simdjson_inline simdjson_result array::end() noexcept { + return array_iterator(iter); +} +simdjson_inline error_code array::consume() noexcept { + auto error = iter.json_iter().skip_child(iter.depth()-1); + if(error) { iter.abandon(); } + return error; +} + +simdjson_inline simdjson_result array::raw_json() noexcept { + const uint8_t * starting_point{iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + // After 'consume()', we could be left pointing just beyond the document, but that + // is ok because we are not going to dereference the final pointer position, we just + // use it to compute the length in bytes. + const uint8_t * final_point{iter._json_iter->unsafe_pointer()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline simdjson_result array::count_elements() & noexcept { + size_t count{0}; + // Important: we do not consume any of the values. + for(simdjson_unused auto v : *this) { count++; } + // The above loop will always succeed, but we want to report errors. + if(iter.error()) { return iter.error(); } + // We need to move back at the start because we expect users to iterate through + // the array after counting the number of elements. + iter.reset_array(); + return count; +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline simdjson_result array::is_empty() & noexcept { + bool is_not_empty; + auto error = iter.reset_array().get(is_not_empty); + if(error) { return error; } + return !is_not_empty; +} + +inline simdjson_result array::reset() & noexcept { + return iter.reset_array(); +} + +inline simdjson_result array::at_pointer(std::string_view json_pointer) noexcept { + if (json_pointer[0] != '/') { return INVALID_JSON_POINTER; } + json_pointer = json_pointer.substr(1); + // - 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; } + + // Read the array index + size_t array_index = 0; + size_t i; + for (i = 0; i < json_pointer.length() && json_pointer[i] != '/'; i++) { + uint8_t digit = uint8_t(json_pointer[i] - '0'); + // Check for non-digit in array index. If it's there, we're trying to get a field in an object + if (digit > 9) { return INCORRECT_TYPE; } + array_index = array_index*10 + digit; + } + + // 0 followed by other digits is invalid + if (i > 1 && json_pointer[0] == '0') { return INVALID_JSON_POINTER; } // "JSON pointer array index has other characters after 0" + + // Empty string is invalid; so is a "/" with no digits before it + if (i == 0) { return INVALID_JSON_POINTER; } // "Empty string in JSON pointer array index" + // Get the child + auto child = at(array_index); + // If there is an error, it ends here + if(child.error()) { + return child; + } + + // If there is a /, we're not done yet, call recursively. + if (i < json_pointer.length()) { + child = child.at_pointer(json_pointer.substr(i)); + } + return child; +} + +simdjson_inline simdjson_result array::at(size_t index) noexcept { + size_t i = 0; + for (auto value : *this) { + if (i == index) { return value; } + i++; + } + return INDEX_OUT_OF_BOUNDS; +} + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + ppc64::ondemand::array &&value +) noexcept + : implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept + : implementation_simdjson_result_base(error) +{ +} + +simdjson_inline simdjson_result simdjson_result::begin() noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() noexcept { + if (error()) { return error(); } + return first.end(); +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::is_empty() & noexcept { + if (error()) { return error(); } + return first.is_empty(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H +/* end file simdjson/generic/ondemand/array-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/array_iterator-inl.h for ppc64: #include "simdjson/generic/ondemand/array_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/array_iterator-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +simdjson_inline array_iterator::array_iterator(const value_iterator &_iter) noexcept + : iter{_iter} +{} + +simdjson_inline simdjson_result array_iterator::operator*() noexcept { + if (iter.error()) { iter.abandon(); return iter.error(); } + return value(iter.child()); +} +simdjson_inline bool array_iterator::operator==(const array_iterator &other) const noexcept { + return !(*this != other); +} +simdjson_inline bool array_iterator::operator!=(const array_iterator &) const noexcept { + return iter.is_open(); +} +simdjson_inline array_iterator &array_iterator::operator++() noexcept { + error_code error; + // PERF NOTE this is a safety rail ... users should exit loops as soon as they receive an error, so we'll never get here. + // However, it does not seem to make a perf difference, so we add it out of an abundance of caution. + if (( error = iter.error() )) { return *this; } + if (( error = iter.skip_child() )) { return *this; } + if (( error = iter.has_next_element().error() )) { return *this; } + return *this; +} + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + ppc64::ondemand::array_iterator &&value +) noexcept + : ppc64::implementation_simdjson_result_base(std::forward(value)) +{ + first.iter.assert_is_valid(); +} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : ppc64::implementation_simdjson_result_base({}, error) +{ +} + +simdjson_inline simdjson_result simdjson_result::operator*() noexcept { + if (error()) { return error(); } + return *first; +} +simdjson_inline bool simdjson_result::operator==(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return !error(); } + return first == other.first; +} +simdjson_inline bool simdjson_result::operator!=(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return error(); } + return first != other.first; +} +simdjson_inline simdjson_result &simdjson_result::operator++() noexcept { + // Clear the error if there is one, so we don't yield it twice + if (error()) { second = SUCCESS; return *this; } + ++(first); + return *this; +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/array_iterator-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/document-inl.h for ppc64: #include "simdjson/generic/ondemand/document-inl.h" */ +/* begin file simdjson/generic/ondemand/document-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +simdjson_inline document::document(ondemand::json_iterator &&_iter) noexcept + : iter{std::forward(_iter)} +{ + logger::log_start_value(iter, "document"); +} + +simdjson_inline document document::start(json_iterator &&iter) noexcept { + return document(std::forward(iter)); +} + +inline void document::rewind() noexcept { + iter.rewind(); +} + +inline std::string document::to_debug_string() noexcept { + return iter.to_string(); +} + +inline simdjson_result document::current_location() const noexcept { + return iter.current_location(); +} + +inline int32_t document::current_depth() const noexcept { + return iter.depth(); +} + +inline bool document::at_end() const noexcept { + return iter.at_end(); +} + + +inline bool document::is_alive() noexcept { + return iter.is_alive(); +} +simdjson_inline value_iterator document::resume_value_iterator() noexcept { + return value_iterator(&iter, 1, iter.root_position()); +} +simdjson_inline value_iterator document::get_root_value_iterator() noexcept { + return resume_value_iterator(); +} +simdjson_inline simdjson_result document::start_or_resume_object() noexcept { + if (iter.at_root()) { + return get_object(); + } else { + return object::resume(resume_value_iterator()); + } +} +simdjson_inline simdjson_result document::get_value() noexcept { + // Make sure we start any arrays or objects before returning, so that start_root_() + // gets called. + + // It is the convention throughout the code that the macro `SIMDJSON_DEVELOPMENT_CHECKS` determines whether + // we check for OUT_OF_ORDER_ITERATION. Proper on::demand code should never trigger this error. +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.at_root()) { return OUT_OF_ORDER_ITERATION; } +#endif + // assert_at_root() serves two purposes: in Debug mode, whether or not + // SIMDJSON_DEVELOPMENT_CHECKS is set or not, it checks that we are at the root of + // the document (this will typically be redundant). In release mode, it generates + // SIMDJSON_ASSUME statements to allow the compiler to make assumptions. + iter.assert_at_root(); + switch (*iter.peek()) { + case '[': { + // The following lines check that the document ends with ]. + auto value_iterator = get_root_value_iterator(); + auto error = value_iterator.check_root_array(); + if(error) { return error; } + return value(get_root_value_iterator()); + } + case '{': { + // The following lines would check that the document ends with }. + auto value_iterator = get_root_value_iterator(); + auto error = value_iterator.check_root_object(); + if(error) { return error; } + return value(get_root_value_iterator()); + } + default: + // Unfortunately, scalar documents are a special case in simdjson and they cannot + // be safely converted to value instances. + return SCALAR_DOCUMENT_AS_VALUE; + } +} +simdjson_inline simdjson_result document::get_array() & noexcept { + auto value = get_root_value_iterator(); + return array::start_root(value); +} +simdjson_inline simdjson_result document::get_object() & noexcept { + auto value = get_root_value_iterator(); + return object::start_root(value); +} + +/** + * We decided that calling 'get_double()' on the JSON document '1.233 blabla' should + * give an error, so we check for trailing content. We want to disallow trailing + * content. + * Thus, in several implementations below, we pass a 'true' parameter value to + * a get_root_value_iterator() method: this indicates that we disallow trailing content. + */ + +simdjson_inline simdjson_result document::get_uint64() noexcept { + return get_root_value_iterator().get_root_uint64(true); +} +simdjson_inline simdjson_result document::get_uint64_in_string() noexcept { + return get_root_value_iterator().get_root_uint64_in_string(true); +} +simdjson_inline simdjson_result document::get_int64() noexcept { + return get_root_value_iterator().get_root_int64(true); +} +simdjson_inline simdjson_result document::get_int64_in_string() noexcept { + return get_root_value_iterator().get_root_int64_in_string(true); +} +simdjson_inline simdjson_result document::get_double() noexcept { + return get_root_value_iterator().get_root_double(true); +} +simdjson_inline simdjson_result document::get_double_in_string() noexcept { + return get_root_value_iterator().get_root_double_in_string(true); +} +simdjson_inline simdjson_result document::get_string(bool allow_replacement) noexcept { + return get_root_value_iterator().get_root_string(true, allow_replacement); +} +template +simdjson_inline error_code document::get_string(string_type& receiver, bool allow_replacement) noexcept { + return get_root_value_iterator().get_root_string(receiver, true, allow_replacement); +} +simdjson_inline simdjson_result document::get_wobbly_string() noexcept { + return get_root_value_iterator().get_root_wobbly_string(true); +} +simdjson_inline simdjson_result document::get_raw_json_string() noexcept { + return get_root_value_iterator().get_root_raw_json_string(true); +} +simdjson_inline simdjson_result document::get_bool() noexcept { + return get_root_value_iterator().get_root_bool(true); +} +simdjson_inline simdjson_result document::is_null() noexcept { + return get_root_value_iterator().is_root_null(true); +} + +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_array(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_object(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_double(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_uint64(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_int64(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_bool(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_value(); } + +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_double(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_uint64(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_int64(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_bool(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_value(); } + +template simdjson_inline error_code document::get(T &out) & noexcept { + return get().get(out); +} +template simdjson_inline error_code document::get(T &out) && noexcept { + return std::forward(*this).get().get(out); +} + +#if SIMDJSON_EXCEPTIONS +simdjson_inline document::operator array() & noexcept(false) { return get_array(); } +simdjson_inline document::operator object() & noexcept(false) { return get_object(); } +simdjson_inline document::operator uint64_t() noexcept(false) { return get_uint64(); } +simdjson_inline document::operator int64_t() noexcept(false) { return get_int64(); } +simdjson_inline document::operator double() noexcept(false) { return get_double(); } +simdjson_inline document::operator std::string_view() noexcept(false) { return get_string(false); } +simdjson_inline document::operator raw_json_string() noexcept(false) { return get_raw_json_string(); } +simdjson_inline document::operator bool() noexcept(false) { return get_bool(); } +simdjson_inline document::operator value() noexcept(false) { return get_value(); } + +#endif +simdjson_inline simdjson_result document::count_elements() & noexcept { + auto a = get_array(); + simdjson_result answer = a.count_elements(); + /* If there was an array, we are now left pointing at its first element. */ + if(answer.error() == SUCCESS) { rewind(); } + return answer; +} +simdjson_inline simdjson_result document::count_fields() & noexcept { + auto a = get_object(); + simdjson_result answer = a.count_fields(); + /* If there was an object, we are now left pointing at its first element. */ + if(answer.error() == SUCCESS) { rewind(); } + return answer; +} +simdjson_inline simdjson_result document::at(size_t index) & noexcept { + auto a = get_array(); + return a.at(index); +} +simdjson_inline simdjson_result document::begin() & noexcept { + return get_array().begin(); +} +simdjson_inline simdjson_result document::end() & noexcept { + return {}; +} + +simdjson_inline simdjson_result document::find_field(std::string_view key) & noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result document::find_field(const char *key) & noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result document::find_field_unordered(std::string_view key) & noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result document::find_field_unordered(const char *key) & noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result document::operator[](std::string_view key) & noexcept { + return start_or_resume_object()[key]; +} +simdjson_inline simdjson_result document::operator[](const char *key) & noexcept { + return start_or_resume_object()[key]; +} + +simdjson_inline error_code document::consume() noexcept { + auto error = iter.skip_child(0); + if(error) { iter.abandon(); } + return error; +} + +simdjson_inline simdjson_result document::raw_json() noexcept { + auto _iter = get_root_value_iterator(); + const uint8_t * starting_point{_iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + // After 'consume()', we could be left pointing just beyond the document, but that + // is ok because we are not going to dereference the final pointer position, we just + // use it to compute the length in bytes. + const uint8_t * final_point{iter.unsafe_pointer()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +simdjson_inline simdjson_result document::type() noexcept { + return get_root_value_iterator().type(); +} + +simdjson_inline simdjson_result document::is_scalar() noexcept { + json_type this_type; + auto error = type().get(this_type); + if(error) { return error; } + return ! ((this_type == json_type::array) || (this_type == json_type::object)); +} + +simdjson_inline bool document::is_negative() noexcept { + return get_root_value_iterator().is_root_negative(); +} + +simdjson_inline simdjson_result document::is_integer() noexcept { + return get_root_value_iterator().is_root_integer(true); +} + +simdjson_inline simdjson_result document::get_number_type() noexcept { + return get_root_value_iterator().get_root_number_type(true); +} + +simdjson_inline simdjson_result document::get_number() noexcept { + return get_root_value_iterator().get_root_number(true); +} + + +simdjson_inline simdjson_result document::raw_json_token() noexcept { + auto _iter = get_root_value_iterator(); + return std::string_view(reinterpret_cast(_iter.peek_start()), _iter.peek_start_length()); +} + +simdjson_inline simdjson_result document::at_pointer(std::string_view json_pointer) noexcept { + rewind(); // Rewind the document each time at_pointer is called + if (json_pointer.empty()) { + return this->get_value(); + } + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: + return (*this).get_array().at_pointer(json_pointer); + case json_type::object: + return (*this).get_object().at_pointer(json_pointer); + default: + return INVALID_JSON_POINTER; + } +} + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + ppc64::ondemand::document &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base( + error + ) +{ +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) & noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline error_code simdjson_result::rewind() noexcept { + if (error()) { return error(); } + first.rewind(); + return SUCCESS; +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::get_array() & noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() & noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::get_value() noexcept { + if (error()) { return error(); } + return first.get_value(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} + +template +simdjson_inline simdjson_result simdjson_result::get() & noexcept { + if (error()) { return error(); } + return first.get(); +} +template +simdjson_inline simdjson_result simdjson_result::get() && noexcept { + if (error()) { return error(); } + return std::forward(first).get(); +} +template +simdjson_inline error_code simdjson_result::get(T &out) & noexcept { + if (error()) { return error(); } + return first.get(out); +} +template +simdjson_inline error_code simdjson_result::get(T &out) && noexcept { + if (error()) { return error(); } + return std::forward(first).get(out); +} + +template<> simdjson_inline simdjson_result simdjson_result::get() & noexcept = delete; +template<> simdjson_inline simdjson_result simdjson_result::get() && noexcept { + if (error()) { return error(); } + return std::forward(first); +} +template<> simdjson_inline error_code simdjson_result::get(ppc64::ondemand::document &out) & noexcept = delete; +template<> simdjson_inline error_code simdjson_result::get(ppc64::ondemand::document &out) && noexcept { + if (error()) { return error(); } + out = std::forward(first); + return SUCCESS; +} + +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} + +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} + + +simdjson_inline bool simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} + +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} + +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} + +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} + + +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator ppc64::ondemand::array() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator ppc64::ondemand::object() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator ppc64::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator ppc64::ondemand::value() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline bool simdjson_result::at_end() const noexcept { + if (error()) { return error(); } + return first.at_end(); +} + + +simdjson_inline int32_t simdjson_result::current_depth() const noexcept { + if (error()) { return error(); } + return first.current_depth(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + + +} // namespace simdjson + + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +simdjson_inline document_reference::document_reference() noexcept : doc{nullptr} {} +simdjson_inline document_reference::document_reference(document &d) noexcept : doc(&d) {} +simdjson_inline void document_reference::rewind() noexcept { doc->rewind(); } +simdjson_inline simdjson_result document_reference::get_array() & noexcept { return doc->get_array(); } +simdjson_inline simdjson_result document_reference::get_object() & noexcept { return doc->get_object(); } +/** + * The document_reference instances are used primarily/solely for streams of JSON + * documents. + * We decided that calling 'get_double()' on the JSON document '1.233 blabla' should + * give an error, so we check for trailing content. + * + * However, for streams of JSON documents, we want to be able to start from + * "321" "321" "321" + * and parse it successfully as a stream of JSON documents, calling get_uint64_in_string() + * successfully each time. + * + * To achieve this result, we pass a 'false' to a get_root_value_iterator() method: + * this indicates that we allow trailing content. + */ +simdjson_inline simdjson_result document_reference::get_uint64() noexcept { return doc->get_root_value_iterator().get_root_uint64(false); } +simdjson_inline simdjson_result document_reference::get_uint64_in_string() noexcept { return doc->get_root_value_iterator().get_root_uint64_in_string(false); } +simdjson_inline simdjson_result document_reference::get_int64() noexcept { return doc->get_root_value_iterator().get_root_int64(false); } +simdjson_inline simdjson_result document_reference::get_int64_in_string() noexcept { return doc->get_root_value_iterator().get_root_int64_in_string(false); } +simdjson_inline simdjson_result document_reference::get_double() noexcept { return doc->get_root_value_iterator().get_root_double(false); } +simdjson_inline simdjson_result document_reference::get_double_in_string() noexcept { return doc->get_root_value_iterator().get_root_double(false); } +simdjson_inline simdjson_result document_reference::get_string(bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(false, allow_replacement); } +template +simdjson_inline error_code document_reference::get_string(string_type& receiver, bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(receiver, false, allow_replacement); } +simdjson_inline simdjson_result document_reference::get_wobbly_string() noexcept { return doc->get_root_value_iterator().get_root_wobbly_string(false); } +simdjson_inline simdjson_result document_reference::get_raw_json_string() noexcept { return doc->get_root_value_iterator().get_root_raw_json_string(false); } +simdjson_inline simdjson_result document_reference::get_bool() noexcept { return doc->get_root_value_iterator().get_root_bool(false); } +simdjson_inline simdjson_result document_reference::get_value() noexcept { return doc->get_value(); } +simdjson_inline simdjson_result document_reference::is_null() noexcept { return doc->get_root_value_iterator().is_root_null(false); } + +#if SIMDJSON_EXCEPTIONS +simdjson_inline document_reference::operator array() & noexcept(false) { return array(*doc); } +simdjson_inline document_reference::operator object() & noexcept(false) { return object(*doc); } +simdjson_inline document_reference::operator uint64_t() noexcept(false) { return get_uint64(); } +simdjson_inline document_reference::operator int64_t() noexcept(false) { return get_int64(); } +simdjson_inline document_reference::operator double() noexcept(false) { return get_double(); } +simdjson_inline document_reference::operator std::string_view() noexcept(false) { return std::string_view(*doc); } +simdjson_inline document_reference::operator raw_json_string() noexcept(false) { return raw_json_string(*doc); } +simdjson_inline document_reference::operator bool() noexcept(false) { return get_bool(); } +simdjson_inline document_reference::operator value() noexcept(false) { return value(*doc); } +#endif +simdjson_inline simdjson_result document_reference::count_elements() & noexcept { return doc->count_elements(); } +simdjson_inline simdjson_result document_reference::count_fields() & noexcept { return doc->count_fields(); } +simdjson_inline simdjson_result document_reference::at(size_t index) & noexcept { return doc->at(index); } +simdjson_inline simdjson_result document_reference::begin() & noexcept { return doc->begin(); } +simdjson_inline simdjson_result document_reference::end() & noexcept { return doc->end(); } +simdjson_inline simdjson_result document_reference::find_field(std::string_view key) & noexcept { return doc->find_field(key); } +simdjson_inline simdjson_result document_reference::find_field(const char *key) & noexcept { return doc->find_field(key); } +simdjson_inline simdjson_result document_reference::operator[](std::string_view key) & noexcept { return (*doc)[key]; } +simdjson_inline simdjson_result document_reference::operator[](const char *key) & noexcept { return (*doc)[key]; } +simdjson_inline simdjson_result document_reference::find_field_unordered(std::string_view key) & noexcept { return doc->find_field_unordered(key); } +simdjson_inline simdjson_result document_reference::find_field_unordered(const char *key) & noexcept { return doc->find_field_unordered(key); } +simdjson_inline simdjson_result document_reference::type() noexcept { return doc->type(); } +simdjson_inline simdjson_result document_reference::is_scalar() noexcept { return doc->is_scalar(); } +simdjson_inline simdjson_result document_reference::current_location() noexcept { return doc->current_location(); } +simdjson_inline int32_t document_reference::current_depth() const noexcept { return doc->current_depth(); } +simdjson_inline bool document_reference::is_negative() noexcept { return doc->is_negative(); } +simdjson_inline simdjson_result document_reference::is_integer() noexcept { return doc->get_root_value_iterator().is_root_integer(false); } +simdjson_inline simdjson_result document_reference::get_number_type() noexcept { return doc->get_root_value_iterator().get_root_number_type(false); } +simdjson_inline simdjson_result document_reference::get_number() noexcept { return doc->get_root_value_iterator().get_root_number(false); } +simdjson_inline simdjson_result document_reference::raw_json_token() noexcept { return doc->raw_json_token(); } +simdjson_inline simdjson_result document_reference::at_pointer(std::string_view json_pointer) noexcept { return doc->at_pointer(json_pointer); } +simdjson_inline simdjson_result document_reference::raw_json() noexcept { return doc->raw_json();} +simdjson_inline document_reference::operator document&() const noexcept { return *doc; } + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + + + +namespace simdjson { +simdjson_inline simdjson_result::simdjson_result(ppc64::ondemand::document_reference value, error_code error) + noexcept : implementation_simdjson_result_base(std::forward(value), error) {} + + +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) & noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline error_code simdjson_result::rewind() noexcept { + if (error()) { return error(); } + first.rewind(); + return SUCCESS; +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::get_array() & noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() & noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::get_value() noexcept { + if (error()) { return error(); } + return first.get_value(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} +simdjson_inline simdjson_result simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator ppc64::ondemand::array() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator ppc64::ondemand::object() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator ppc64::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator ppc64::ondemand::value() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H +/* end file simdjson/generic/ondemand/document-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/document_stream-inl.h for ppc64: #include "simdjson/generic/ondemand/document_stream-inl.h" */ +/* begin file simdjson/generic/ondemand/document_stream-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document_stream.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +#ifdef SIMDJSON_THREADS_ENABLED + +inline void stage1_worker::finish() { + // After calling "run" someone would call finish() to wait + // for the end of the processing. + // This function will wait until either the thread has done + // the processing or, else, the destructor has been called. + std::unique_lock lock(locking_mutex); + cond_var.wait(lock, [this]{return has_work == false;}); +} + +inline stage1_worker::~stage1_worker() { + // The thread may never outlive the stage1_worker instance + // and will always be stopped/joined before the stage1_worker + // instance is gone. + stop_thread(); +} + +inline void stage1_worker::start_thread() { + std::unique_lock lock(locking_mutex); + if(thread.joinable()) { + return; // This should never happen but we never want to create more than one thread. + } + thread = std::thread([this]{ + while(true) { + std::unique_lock thread_lock(locking_mutex); + // We wait for either "run" or "stop_thread" to be called. + cond_var.wait(thread_lock, [this]{return has_work || !can_work;}); + // If, for some reason, the stop_thread() method was called (i.e., the + // destructor of stage1_worker is called, then we want to immediately destroy + // the thread (and not do any more processing). + if(!can_work) { + break; + } + this->owner->stage1_thread_error = this->owner->run_stage1(*this->stage1_thread_parser, + this->_next_batch_start); + this->has_work = false; + // The condition variable call should be moved after thread_lock.unlock() for performance + // reasons but thread sanitizers may report it as a data race if we do. + // See https://stackoverflow.com/questions/35775501/c-should-condition-variable-be-notified-under-lock + cond_var.notify_one(); // will notify "finish" + thread_lock.unlock(); + } + } + ); +} + + +inline void stage1_worker::stop_thread() { + std::unique_lock lock(locking_mutex); + // We have to make sure that all locks can be released. + can_work = false; + has_work = false; + cond_var.notify_all(); + lock.unlock(); + if(thread.joinable()) { + thread.join(); + } +} + +inline void stage1_worker::run(document_stream * ds, parser * stage1, size_t next_batch_start) { + std::unique_lock lock(locking_mutex); + owner = ds; + _next_batch_start = next_batch_start; + stage1_thread_parser = stage1; + has_work = true; + // The condition variable call should be moved after thread_lock.unlock() for performance + // reasons but thread sanitizers may report it as a data race if we do. + // See https://stackoverflow.com/questions/35775501/c-should-condition-variable-be-notified-under-lock + cond_var.notify_one(); // will notify the thread lock that we have work + lock.unlock(); +} + +#endif // SIMDJSON_THREADS_ENABLED + +simdjson_inline document_stream::document_stream( + ondemand::parser &_parser, + const uint8_t *_buf, + size_t _len, + size_t _batch_size, + bool _allow_comma_separated +) noexcept + : parser{&_parser}, + buf{_buf}, + len{_len}, + batch_size{_batch_size <= MINIMAL_BATCH_SIZE ? MINIMAL_BATCH_SIZE : _batch_size}, + allow_comma_separated{_allow_comma_separated}, + error{SUCCESS} + #ifdef SIMDJSON_THREADS_ENABLED + , use_thread(_parser.threaded) // we need to make a copy because _parser.threaded can change + #endif +{ +#ifdef SIMDJSON_THREADS_ENABLED + if(worker.get() == nullptr) { + error = MEMALLOC; + } +#endif +} + +simdjson_inline document_stream::document_stream() noexcept + : parser{nullptr}, + buf{nullptr}, + len{0}, + batch_size{0}, + allow_comma_separated{false}, + error{UNINITIALIZED} + #ifdef SIMDJSON_THREADS_ENABLED + , use_thread(false) + #endif +{ +} + +simdjson_inline document_stream::~document_stream() noexcept +{ + #ifdef SIMDJSON_THREADS_ENABLED + worker.reset(); + #endif +} + +inline size_t document_stream::size_in_bytes() const noexcept { + return len; +} + +inline size_t document_stream::truncated_bytes() const noexcept { + if(error == CAPACITY) { return len - batch_start; } + return parser->implementation->structural_indexes[parser->implementation->n_structural_indexes] - parser->implementation->structural_indexes[parser->implementation->n_structural_indexes + 1]; +} + +simdjson_inline document_stream::iterator::iterator() noexcept + : stream{nullptr}, finished{true} { +} + +simdjson_inline document_stream::iterator::iterator(document_stream* _stream, bool is_end) noexcept + : stream{_stream}, finished{is_end} { +} + +simdjson_inline simdjson_result document_stream::iterator::operator*() noexcept { + //if(stream->error) { return stream->error; } + return simdjson_result(stream->doc, stream->error); +} + +simdjson_inline document_stream::iterator& document_stream::iterator::operator++() noexcept { + // If there is an error, then we want the iterator + // to be finished, no matter what. (E.g., we do not + // keep generating documents with errors, or go beyond + // a document with errors.) + // + // Users do not have to call "operator*()" when they use operator++, + // so we need to end the stream in the operator++ function. + // + // Note that setting finished = true is essential otherwise + // we would enter an infinite loop. + if (stream->error) { finished = true; } + // Note that stream->error() is guarded against error conditions + // (it will immediately return if stream->error casts to false). + // In effect, this next function does nothing when (stream->error) + // is true (hence the risk of an infinite loop). + stream->next(); + // If that was the last document, we're finished. + // It is the only type of error we do not want to appear + // in operator*. + if (stream->error == EMPTY) { finished = true; } + // If we had any other kind of error (not EMPTY) then we want + // to pass it along to the operator* and we cannot mark the result + // as "finished" just yet. + return *this; +} + +simdjson_inline bool document_stream::iterator::operator!=(const document_stream::iterator &other) const noexcept { + return finished != other.finished; +} + +simdjson_inline document_stream::iterator document_stream::begin() noexcept { + start(); + // If there are no documents, we're finished. + return iterator(this, error == EMPTY); +} + +simdjson_inline document_stream::iterator document_stream::end() noexcept { + return iterator(this, true); +} + +inline void document_stream::start() noexcept { + if (error) { return; } + error = parser->allocate(batch_size); + if (error) { return; } + // Always run the first stage 1 parse immediately + batch_start = 0; + error = run_stage1(*parser, batch_start); + while(error == EMPTY) { + // In exceptional cases, we may start with an empty block + batch_start = next_batch_start(); + if (batch_start >= len) { return; } + error = run_stage1(*parser, batch_start); + } + if (error) { return; } + doc_index = batch_start; + doc = document(json_iterator(&buf[batch_start], parser)); + doc.iter._streaming = true; + + #ifdef SIMDJSON_THREADS_ENABLED + if (use_thread && next_batch_start() < len) { + // Kick off the first thread on next batch if needed + error = stage1_thread_parser.allocate(batch_size); + if (error) { return; } + worker->start_thread(); + start_stage1_thread(); + if (error) { return; } + } + #endif // SIMDJSON_THREADS_ENABLED +} + +inline void document_stream::next() noexcept { + // We always enter at once once in an error condition. + if (error) { return; } + next_document(); + if (error) { return; } + auto cur_struct_index = doc.iter._root - parser->implementation->structural_indexes.get(); + doc_index = batch_start + parser->implementation->structural_indexes[cur_struct_index]; + + // Check if at end of structural indexes (i.e. at end of batch) + if(cur_struct_index >= static_cast(parser->implementation->n_structural_indexes)) { + error = EMPTY; + // Load another batch (if available) + while (error == EMPTY) { + batch_start = next_batch_start(); + if (batch_start >= len) { break; } + #ifdef SIMDJSON_THREADS_ENABLED + if(use_thread) { + load_from_stage1_thread(); + } else { + error = run_stage1(*parser, batch_start); + } + #else + error = run_stage1(*parser, batch_start); + #endif + /** + * Whenever we move to another window, we need to update all pointers to make + * it appear as if the input buffer started at the beginning of the window. + * + * Take this input: + * + * {"z":5} {"1":1,"2":2,"4":4} [7, 10, 9] [15, 11, 12, 13] [154, 110, 112, 1311] + * + * Say you process the following window... + * + * '{"z":5} {"1":1,"2":2,"4":4} [7, 10, 9]' + * + * When you do so, the json_iterator has a pointer at the beginning of the memory region + * (pointing at the beginning of '{"z"...'. + * + * When you move to the window that starts at... + * + * '[7, 10, 9] [15, 11, 12, 13] ... + * + * then it is not sufficient to just run stage 1. You also need to re-anchor the + * json_iterator so that it believes we are starting at '[7, 10, 9]...'. + * + * Under the DOM front-end, this gets done automatically because the parser owns + * the pointer the data, and when you call stage1 and then stage2 on the same + * parser, then stage2 will run on the pointer acquired by stage1. + * + * That is, stage1 calls "this->buf = _buf" so the parser remembers the buffer that + * we used. But json_iterator has no callback when stage1 is called on the parser. + * In fact, I think that the parser is unaware of json_iterator. + * + * + * So we need to re-anchor the json_iterator after each call to stage 1 so that + * all of the pointers are in sync. + */ + doc.iter = json_iterator(&buf[batch_start], parser); + doc.iter._streaming = true; + /** + * End of resync. + */ + + if (error) { continue; } // If the error was EMPTY, we may want to load another batch. + doc_index = batch_start; + } + } +} + +inline void document_stream::next_document() noexcept { + // Go to next place where depth=0 (document depth) + error = doc.iter.skip_child(0); + if (error) { return; } + // Always set depth=1 at the start of document + doc.iter._depth = 1; + // consume comma if comma separated is allowed + if (allow_comma_separated) { doc.iter.consume_character(','); } + // Resets the string buffer at the beginning, thus invalidating the strings. + doc.iter._string_buf_loc = parser->string_buf.get(); + doc.iter._root = doc.iter.position(); +} + +inline size_t document_stream::next_batch_start() const noexcept { + return batch_start + parser->implementation->structural_indexes[parser->implementation->n_structural_indexes]; +} + +inline error_code document_stream::run_stage1(ondemand::parser &p, size_t _batch_start) noexcept { + // This code only updates the structural index in the parser, it does not update any json_iterator + // instance. + size_t remaining = len - _batch_start; + if (remaining <= batch_size) { + return p.implementation->stage1(&buf[_batch_start], remaining, stage1_mode::streaming_final); + } else { + return p.implementation->stage1(&buf[_batch_start], batch_size, stage1_mode::streaming_partial); + } +} + +simdjson_inline size_t document_stream::iterator::current_index() const noexcept { + return stream->doc_index; +} + +simdjson_inline std::string_view document_stream::iterator::source() const noexcept { + auto depth = stream->doc.iter.depth(); + auto cur_struct_index = stream->doc.iter._root - stream->parser->implementation->structural_indexes.get(); + + // If at root, process the first token to determine if scalar value + if (stream->doc.iter.at_root()) { + switch (stream->buf[stream->batch_start + stream->parser->implementation->structural_indexes[cur_struct_index]]) { + case '{': case '[': // Depth=1 already at start of document + break; + case '}': case ']': + depth--; + break; + default: // Scalar value document + // TODO: Remove any trailing whitespaces + // This returns a string spanning from start of value to the beginning of the next document (excluded) + return std::string_view(reinterpret_cast(stream->buf) + current_index(), stream->parser->implementation->structural_indexes[++cur_struct_index] - current_index() - 1); + } + cur_struct_index++; + } + + while (cur_struct_index <= static_cast(stream->parser->implementation->n_structural_indexes)) { + switch (stream->buf[stream->batch_start + stream->parser->implementation->structural_indexes[cur_struct_index]]) { + case '{': case '[': + depth++; + break; + case '}': case ']': + depth--; + break; + } + if (depth == 0) { break; } + cur_struct_index++; + } + + return std::string_view(reinterpret_cast(stream->buf) + current_index(), stream->parser->implementation->structural_indexes[cur_struct_index] - current_index() + stream->batch_start + 1);; +} + +inline error_code document_stream::iterator::error() const noexcept { + return stream->error; +} + +#ifdef SIMDJSON_THREADS_ENABLED + +inline void document_stream::load_from_stage1_thread() noexcept { + worker->finish(); + // Swap to the parser that was loaded up in the thread. Make sure the parser has + // enough memory to swap to, as well. + std::swap(stage1_thread_parser,*parser); + error = stage1_thread_error; + if (error) { return; } + + // If there's anything left, start the stage 1 thread! + if (next_batch_start() < len) { + start_stage1_thread(); + } +} + +inline void document_stream::start_stage1_thread() noexcept { + // we call the thread on a lambda that will update + // this->stage1_thread_error + // there is only one thread that may write to this value + // TODO this is NOT exception-safe. + this->stage1_thread_error = UNINITIALIZED; // In case something goes wrong, make sure it's an error + size_t _next_batch_start = this->next_batch_start(); + + worker->run(this, & this->stage1_thread_parser, _next_batch_start); +} + +#endif // SIMDJSON_THREADS_ENABLED + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} +simdjson_inline simdjson_result::simdjson_result( + ppc64::ondemand::document_stream &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} + +} + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H +/* end file simdjson/generic/ondemand/document_stream-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/field-inl.h for ppc64: #include "simdjson/generic/ondemand/field-inl.h" */ +/* begin file simdjson/generic/ondemand/field-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +// clang 6 doesn't think the default constructor can be noexcept, so we make it explicit +simdjson_inline field::field() noexcept : std::pair() {} + +simdjson_inline field::field(raw_json_string key, ondemand::value &&value) noexcept + : std::pair(key, std::forward(value)) +{ +} + +simdjson_inline simdjson_result field::start(value_iterator &parent_iter) noexcept { + raw_json_string key; + SIMDJSON_TRY( parent_iter.field_key().get(key) ); + SIMDJSON_TRY( parent_iter.field_value() ); + return field::start(parent_iter, key); +} + +simdjson_inline simdjson_result field::start(const value_iterator &parent_iter, raw_json_string key) noexcept { + return field(key, parent_iter.child()); +} + +simdjson_inline simdjson_warn_unused simdjson_result field::unescaped_key(bool allow_replacement) noexcept { + SIMDJSON_ASSUME(first.buf != nullptr); // We would like to call .alive() but Visual Studio won't let us. + simdjson_result answer = first.unescape(second.iter.json_iter(), allow_replacement); + first.consume(); + return answer; +} + +simdjson_inline raw_json_string field::key() const noexcept { + SIMDJSON_ASSUME(first.buf != nullptr); // We would like to call .alive() by Visual Studio won't let us. + return first; +} + +simdjson_inline value &field::value() & noexcept { + return second; +} + +simdjson_inline value field::value() && noexcept { + return std::forward(*this).second; +} + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + ppc64::ondemand::field &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} + +simdjson_inline simdjson_result simdjson_result::key() noexcept { + if (error()) { return error(); } + return first.key(); +} +simdjson_inline simdjson_result simdjson_result::unescaped_key(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.unescaped_key(allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::value() noexcept { + if (error()) { return error(); } + return std::move(first.value()); +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H +/* end file simdjson/generic/ondemand/field-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/json_iterator-inl.h for ppc64: #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/json_iterator-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +simdjson_inline json_iterator::json_iterator(json_iterator &&other) noexcept + : token(std::forward(other.token)), + parser{other.parser}, + _string_buf_loc{other._string_buf_loc}, + error{other.error}, + _depth{other._depth}, + _root{other._root}, + _streaming{other._streaming} +{ + other.parser = nullptr; +} +simdjson_inline json_iterator &json_iterator::operator=(json_iterator &&other) noexcept { + token = other.token; + parser = other.parser; + _string_buf_loc = other._string_buf_loc; + error = other.error; + _depth = other._depth; + _root = other._root; + _streaming = other._streaming; + other.parser = nullptr; + return *this; +} + +simdjson_inline json_iterator::json_iterator(const uint8_t *buf, ondemand::parser *_parser) noexcept + : token(buf, &_parser->implementation->structural_indexes[0]), + parser{_parser}, + _string_buf_loc{parser->string_buf.get()}, + _depth{1}, + _root{parser->implementation->structural_indexes.get()}, + _streaming{false} + +{ + logger::log_headers(); +#if SIMDJSON_CHECK_EOF + assert_more_tokens(); +#endif +} + +inline void json_iterator::rewind() noexcept { + token.set_position( root_position() ); + logger::log_headers(); // We start again + _string_buf_loc = parser->string_buf.get(); + _depth = 1; +} + +inline bool json_iterator::balanced() const noexcept { + token_iterator ti(token); + int32_t count{0}; + ti.set_position( root_position() ); + while(ti.peek() <= peek_last()) { + switch (*ti.return_current_and_advance()) + { + case '[': case '{': + count++; + break; + case ']': case '}': + count--; + break; + default: + break; + } + } + return count == 0; +} + + +// GCC 7 warns when the first line of this function is inlined away into oblivion due to the caller +// relating depth and parent_depth, which is a desired effect. The warning does not show up if the +// skip_child() function is not marked inline). +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_warn_unused simdjson_inline error_code json_iterator::skip_child(depth_t parent_depth) noexcept { + if (depth() <= parent_depth) { return SUCCESS; } + switch (*return_current_and_advance()) { + // TODO consider whether matching braces is a requirement: if non-matching braces indicates + // *missing* braces, then future lookups are not in the object/arrays they think they are, + // violating the rule "validate enough structure that the user can be confident they are + // looking at the right values." + // PERF TODO we can eliminate the switch here with a lookup of how much to add to depth + + // For the first open array/object in a value, we've already incremented depth, so keep it the same + // We never stop at colon, but if we did, it wouldn't affect depth + case '[': case '{': case ':': + logger::log_start_value(*this, "skip"); + break; + // If there is a comma, we have just finished a value in an array/object, and need to get back in + case ',': + logger::log_value(*this, "skip"); + break; + // ] or } means we just finished a value and need to jump out of the array/object + case ']': case '}': + logger::log_end_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } +#if SIMDJSON_CHECK_EOF + // If there are no more tokens, the parent is incomplete. + if (at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "Missing [ or { at start"); } +#endif // SIMDJSON_CHECK_EOF + break; + case '"': + if(*peek() == ':') { + // We are at a key!!! + // This might happen if you just started an object and you skip it immediately. + // Performance note: it would be nice to get rid of this check as it is somewhat + // expensive. + // https://github.com/simdjson/simdjson/issues/1742 + logger::log_value(*this, "key"); + return_current_and_advance(); // eat up the ':' + break; // important!!! + } + simdjson_fallthrough; + // Anything else must be a scalar value + default: + // For the first scalar, we will have incremented depth already, so we decrement it here. + logger::log_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } + break; + } + + // Now that we've considered the first value, we only increment/decrement for arrays/objects + while (position() < end_position()) { + switch (*return_current_and_advance()) { + case '[': case '{': + logger::log_start_value(*this, "skip"); + _depth++; + break; + // TODO consider whether matching braces is a requirement: if non-matching braces indicates + // *missing* braces, then future lookups are not in the object/arrays they think they are, + // violating the rule "validate enough structure that the user can be confident they are + // looking at the right values." + // PERF TODO we can eliminate the switch here with a lookup of how much to add to depth + case ']': case '}': + logger::log_end_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } + break; + default: + logger::log_value(*this, "skip", ""); + break; + } + } + + return report_error(TAPE_ERROR, "not enough close braces"); +} + +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline bool json_iterator::at_root() const noexcept { + return position() == root_position(); +} + +simdjson_inline bool json_iterator::is_single_token() const noexcept { + return parser->implementation->n_structural_indexes == 1; +} + +simdjson_inline bool json_iterator::streaming() const noexcept { + return _streaming; +} + +simdjson_inline token_position json_iterator::root_position() const noexcept { + return _root; +} + +simdjson_inline void json_iterator::assert_at_document_depth() const noexcept { + SIMDJSON_ASSUME( _depth == 1 ); +} + +simdjson_inline void json_iterator::assert_at_root() const noexcept { + SIMDJSON_ASSUME( _depth == 1 ); +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + // Under Visual Studio, the next SIMDJSON_ASSUME fails with: the argument + // has side effects that will be discarded. + SIMDJSON_ASSUME( token.position() == _root ); +#endif +} + +simdjson_inline void json_iterator::assert_more_tokens(uint32_t required_tokens) const noexcept { + assert_valid_position(token._position + required_tokens - 1); +} + +simdjson_inline void json_iterator::assert_valid_position(token_position position) const noexcept { +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + SIMDJSON_ASSUME( position >= &parser->implementation->structural_indexes[0] ); + SIMDJSON_ASSUME( position < &parser->implementation->structural_indexes[parser->implementation->n_structural_indexes] ); +#endif +} + +simdjson_inline bool json_iterator::at_end() const noexcept { + return position() == end_position(); +} +simdjson_inline token_position json_iterator::end_position() const noexcept { + uint32_t n_structural_indexes{parser->implementation->n_structural_indexes}; + return &parser->implementation->structural_indexes[n_structural_indexes]; +} + +inline std::string json_iterator::to_string() const noexcept { + if( !is_alive() ) { return "dead json_iterator instance"; } + const char * current_structural = reinterpret_cast(token.peek()); + return std::string("json_iterator [ depth : ") + std::to_string(_depth) + + std::string(", structural : '") + std::string(current_structural,1) + + std::string("', offset : ") + std::to_string(token.current_offset()) + + std::string("', error : ") + error_message(error) + + std::string(" ]"); +} + +inline simdjson_result json_iterator::current_location() const noexcept { + if (!is_alive()) { // Unrecoverable error + if (!at_root()) { + return reinterpret_cast(token.peek(-1)); + } else { + return reinterpret_cast(token.peek()); + } + } + if (at_end()) { + return OUT_OF_BOUNDS; + } + return reinterpret_cast(token.peek()); +} + +simdjson_inline bool json_iterator::is_alive() const noexcept { + return parser; +} + +simdjson_inline void json_iterator::abandon() noexcept { + parser = nullptr; + _depth = 0; +} + +simdjson_inline const uint8_t *json_iterator::return_current_and_advance() noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(); +#endif // SIMDJSON_CHECK_EOF + return token.return_current_and_advance(); +} + +simdjson_inline const uint8_t *json_iterator::unsafe_pointer() const noexcept { + // deliberately done without safety guard: + return token.peek(); +} + +simdjson_inline const uint8_t *json_iterator::peek(int32_t delta) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(delta+1); +#endif // SIMDJSON_CHECK_EOF + return token.peek(delta); +} + +simdjson_inline uint32_t json_iterator::peek_length(int32_t delta) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(delta+1); +#endif // #if SIMDJSON_CHECK_EOF + return token.peek_length(delta); +} + +simdjson_inline const uint8_t *json_iterator::peek(token_position position) const noexcept { + // todo: currently we require end-of-string buffering, but the following + // assert_valid_position should be turned on if/when we lift that condition. + // assert_valid_position(position); + // This is almost surely related to SIMDJSON_CHECK_EOF but given that SIMDJSON_CHECK_EOF + // is ON by default, we have no choice but to disable it for real with a comment. + return token.peek(position); +} + +simdjson_inline uint32_t json_iterator::peek_length(token_position position) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_valid_position(position); +#endif // SIMDJSON_CHECK_EOF + return token.peek_length(position); +} + +simdjson_inline token_position json_iterator::last_position() const noexcept { + // The following line fails under some compilers... + // SIMDJSON_ASSUME(parser->implementation->n_structural_indexes > 0); + // since it has side-effects. + uint32_t n_structural_indexes{parser->implementation->n_structural_indexes}; + SIMDJSON_ASSUME(n_structural_indexes > 0); + return &parser->implementation->structural_indexes[n_structural_indexes - 1]; +} +simdjson_inline const uint8_t *json_iterator::peek_last() const noexcept { + return token.peek(last_position()); +} + +simdjson_inline void json_iterator::ascend_to(depth_t parent_depth) noexcept { + SIMDJSON_ASSUME(parent_depth >= 0 && parent_depth < INT32_MAX - 1); + SIMDJSON_ASSUME(_depth == parent_depth + 1); + _depth = parent_depth; +} + +simdjson_inline void json_iterator::descend_to(depth_t child_depth) noexcept { + SIMDJSON_ASSUME(child_depth >= 1 && child_depth < INT32_MAX); + SIMDJSON_ASSUME(_depth == child_depth - 1); + _depth = child_depth; +} + +simdjson_inline depth_t json_iterator::depth() const noexcept { + return _depth; +} + +simdjson_inline uint8_t *&json_iterator::string_buf_loc() noexcept { + return _string_buf_loc; +} + +simdjson_inline error_code json_iterator::report_error(error_code _error, const char *message) noexcept { + SIMDJSON_ASSUME(_error != SUCCESS && _error != UNINITIALIZED && _error != INCORRECT_TYPE && _error != NO_SUCH_FIELD); + logger::log_error(*this, message); + error = _error; + return error; +} + +simdjson_inline token_position json_iterator::position() const noexcept { + return token.position(); +} + +simdjson_inline simdjson_result json_iterator::unescape(raw_json_string in, bool allow_replacement) noexcept { + return parser->unescape(in, _string_buf_loc, allow_replacement); +} + +simdjson_inline simdjson_result json_iterator::unescape_wobbly(raw_json_string in) noexcept { + return parser->unescape_wobbly(in, _string_buf_loc); +} + +simdjson_inline void json_iterator::reenter_child(token_position position, depth_t child_depth) noexcept { + SIMDJSON_ASSUME(child_depth >= 1 && child_depth < INT32_MAX); + SIMDJSON_ASSUME(_depth == child_depth - 1); +#if SIMDJSON_DEVELOPMENT_CHECKS +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + SIMDJSON_ASSUME(size_t(child_depth) < parser->max_depth()); + SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]); +#endif +#endif + token.set_position(position); + _depth = child_depth; +} + +simdjson_inline error_code json_iterator::consume_character(char c) noexcept { + if (*peek() == c) { + return_current_and_advance(); + return SUCCESS; + } + return TAPE_ERROR; +} + +#if SIMDJSON_DEVELOPMENT_CHECKS + +simdjson_inline token_position json_iterator::start_position(depth_t depth) const noexcept { + SIMDJSON_ASSUME(size_t(depth) < parser->max_depth()); + return size_t(depth) < parser->max_depth() ? parser->start_positions[depth] : 0; +} + +simdjson_inline void json_iterator::set_start_position(depth_t depth, token_position position) noexcept { + SIMDJSON_ASSUME(size_t(depth) < parser->max_depth()); + if(size_t(depth) < parser->max_depth()) { parser->start_positions[depth] = position; } +} + +#endif + + +simdjson_inline error_code json_iterator::optional_error(error_code _error, const char *message) noexcept { + SIMDJSON_ASSUME(_error == INCORRECT_TYPE || _error == NO_SUCH_FIELD); + logger::log_error(*this, message); + return _error; +} + + +simdjson_warn_unused simdjson_inline bool json_iterator::copy_to_buffer(const uint8_t *json, uint32_t max_len, uint8_t *tmpbuf, size_t N) noexcept { + // This function is not expected to be called in performance-sensitive settings. + // Let us guard against silly cases: + if((N < max_len) || (N == 0)) { return false; } + // Copy to the buffer. + std::memcpy(tmpbuf, json, max_len); + if(N > max_len) { // We pad whatever remains with ' '. + std::memset(tmpbuf + max_len, ' ', N - max_len); + } + return true; +} + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(ppc64::ondemand::json_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/json_iterator-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/json_type-inl.h for ppc64: #include "simdjson/generic/ondemand/json_type-inl.h" */ +/* begin file simdjson/generic/ondemand/json_type-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +inline std::ostream& operator<<(std::ostream& out, json_type type) noexcept { + switch (type) { + case json_type::array: out << "array"; break; + case json_type::object: out << "object"; break; + case json_type::number: out << "number"; break; + case json_type::string: out << "string"; break; + case json_type::boolean: out << "boolean"; break; + case json_type::null: out << "null"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson_result &type) noexcept(false) { + return out << type.value(); +} +#endif + + + +simdjson_inline number_type number::get_number_type() const noexcept { + return type; +} + +simdjson_inline bool number::is_uint64() const noexcept { + return get_number_type() == number_type::unsigned_integer; +} + +simdjson_inline uint64_t number::get_uint64() const noexcept { + return payload.unsigned_integer; +} + +simdjson_inline number::operator uint64_t() const noexcept { + return get_uint64(); +} + + +simdjson_inline bool number::is_int64() const noexcept { + return get_number_type() == number_type::signed_integer; +} + +simdjson_inline int64_t number::get_int64() const noexcept { + return payload.signed_integer; +} + +simdjson_inline number::operator int64_t() const noexcept { + return get_int64(); +} + +simdjson_inline bool number::is_double() const noexcept { + return get_number_type() == number_type::floating_point_number; +} + +simdjson_inline double number::get_double() const noexcept { + return payload.floating_point_number; +} + +simdjson_inline number::operator double() const noexcept { + return get_double(); +} + +simdjson_inline double number::as_double() const noexcept { + if(is_double()) { + return payload.floating_point_number; + } + if(is_int64()) { + return double(payload.signed_integer); + } + return double(payload.unsigned_integer); +} + +simdjson_inline void number::append_s64(int64_t value) noexcept { + payload.signed_integer = value; + type = number_type::signed_integer; +} + +simdjson_inline void number::append_u64(uint64_t value) noexcept { + payload.unsigned_integer = value; + type = number_type::unsigned_integer; +} + +simdjson_inline void number::append_double(double value) noexcept { + payload.floating_point_number = value; + type = number_type::floating_point_number; +} + +simdjson_inline void number::skip_double() noexcept { + type = number_type::floating_point_number; +} + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(ppc64::ondemand::json_type &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H +/* end file simdjson/generic/ondemand/json_type-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/logger-inl.h for ppc64: #include "simdjson/generic/ondemand/logger-inl.h" */ +/* begin file simdjson/generic/ondemand/logger-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include + +namespace simdjson { +namespace ppc64 { +namespace ondemand { +namespace logger { + +static constexpr const char * DASHES = "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"; +static constexpr const int LOG_EVENT_LEN = 20; +static constexpr const int LOG_BUFFER_LEN = 30; +static constexpr const int LOG_SMALL_BUFFER_LEN = 10; +static int log_depth = 0; // Not threadsafe. Log only. + +// Helper to turn unprintable or newline characters into spaces +static inline char printable_char(char c) { + if (c >= 0x20) { + return c; + } else { + return ' '; + } +} + +template +static inline std::string string_format(const std::string& format, const Args&... args) +{ + SIMDJSON_PUSH_DISABLE_ALL_WARNINGS + int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; + auto size = static_cast(size_s); + if (size <= 0) return std::string(); + std::unique_ptr buf(new char[size]); + std::snprintf(buf.get(), size, format.c_str(), args...); + SIMDJSON_POP_DISABLE_WARNINGS + return std::string(buf.get(), buf.get() + size - 1); +} + +static inline log_level get_log_level_from_env() +{ + SIMDJSON_PUSH_DISABLE_WARNINGS + SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe + char *lvl = getenv("SIMDJSON_LOG_LEVEL"); + SIMDJSON_POP_DISABLE_WARNINGS + if (lvl && simdjson_strcasecmp(lvl, "ERROR") == 0) { return log_level::error; } + return log_level::info; +} + +static inline log_level log_threshold() +{ + static log_level threshold = get_log_level_from_env(); + return threshold; +} + +static inline bool should_log(log_level level) +{ + return level >= log_threshold(); +} + +inline void log_event(const json_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_line(iter, "", type, detail, delta, depth_delta, log_level::info); +} + +inline void log_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail) noexcept { + log_line(iter, index, depth, "", type, detail, log_level::info); +} +inline void log_value(const json_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_line(iter, "", type, detail, delta, depth_delta, log_level::info); +} + +inline void log_start_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail) noexcept { + log_line(iter, index, depth, "+", type, detail, log_level::info); + if (LOG_ENABLED) { log_depth++; } +} +inline void log_start_value(const json_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_line(iter, "+", type, "", delta, depth_delta, log_level::info); + if (LOG_ENABLED) { log_depth++; } +} + +inline void log_end_value(const json_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + if (LOG_ENABLED) { log_depth--; } + log_line(iter, "-", type, "", delta, depth_delta, log_level::info); +} + +inline void log_error(const json_iterator &iter, const char *error, const char *detail, int delta, int depth_delta) noexcept { + log_line(iter, "ERROR: ", error, detail, delta, depth_delta, log_level::error); +} +inline void log_error(const json_iterator &iter, token_position index, depth_t depth, const char *error, const char *detail) noexcept { + log_line(iter, index, depth, "ERROR: ", error, detail, log_level::error); +} + +inline void log_event(const value_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_event(iter.json_iter(), type, detail, delta, depth_delta); +} + +inline void log_value(const value_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_value(iter.json_iter(), type, detail, delta, depth_delta); +} + +inline void log_start_value(const value_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_start_value(iter.json_iter(), type, delta, depth_delta); +} + +inline void log_end_value(const value_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_end_value(iter.json_iter(), type, delta, depth_delta); +} + +inline void log_error(const value_iterator &iter, const char *error, const char *detail, int delta, int depth_delta) noexcept { + log_error(iter.json_iter(), error, detail, delta, depth_delta); +} + +inline void log_headers() noexcept { + if (LOG_ENABLED) { + if (simdjson_unlikely(should_log(log_level::info))) { + // Technically a static variable is not thread-safe, but if you are using threads and logging... well... + static bool displayed_hint{false}; + log_depth = 0; + printf("\n"); + if (!displayed_hint) { + // We only print this helpful header once. + printf("# Logging provides the depth and position of the iterator user-visible steps:\n"); + printf("# +array says 'this is where we were when we discovered the start array'\n"); + printf( + "# -array says 'this is where we were when we ended the array'\n"); + printf("# skip says 'this is a structural or value I am skipping'\n"); + printf("# +/-skip says 'this is a start/end array or object I am skipping'\n"); + printf("#\n"); + printf("# The indentation of the terms (array, string,...) indicates the depth,\n"); + printf("# in addition to the depth being displayed.\n"); + printf("#\n"); + printf("# Every token in the document has a single depth determined by the tokens before it,\n"); + printf("# and is not affected by what the token actually is.\n"); + printf("#\n"); + printf("# Not all structural elements are presented as tokens in the logs.\n"); + printf("#\n"); + printf("# We never give control to the user within an empty array or an empty object.\n"); + printf("#\n"); + printf("# Inside an array, having a depth greater than the array's depth means that\n"); + printf("# we are pointing inside a value.\n"); + printf("# Having a depth equal to the array means that we are pointing right before a value.\n"); + printf("# Having a depth smaller than the array means that we have moved beyond the array.\n"); + displayed_hint = true; + } + printf("\n"); + printf("| %-*s ", LOG_EVENT_LEN, "Event"); + printf("| %-*s ", LOG_BUFFER_LEN, "Buffer"); + printf("| %-*s ", LOG_SMALL_BUFFER_LEN, "Next"); + // printf("| %-*s ", 5, "Next#"); + printf("| %-*s ", 5, "Depth"); + printf("| Detail "); + printf("|\n"); + + printf("|%.*s", LOG_EVENT_LEN + 2, DASHES); + printf("|%.*s", LOG_BUFFER_LEN + 2, DASHES); + printf("|%.*s", LOG_SMALL_BUFFER_LEN + 2, DASHES); + // printf("|%.*s", 5+2, DASHES); + printf("|%.*s", 5 + 2, DASHES); + printf("|--------"); + printf("|\n"); + fflush(stdout); + } + } +} + +template +inline void log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, log_level level, Args&&... args) noexcept { + log_line(iter, iter.position()+delta, depth_t(iter.depth()+depth_delta), title_prefix, title, detail, level, std::forward(args)...); +} + +template +inline void log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, log_level level, Args&&... args) noexcept { + if (LOG_ENABLED) { + if (simdjson_unlikely(should_log(level))) { + const int indent = depth * 2; + const auto buf = iter.token.buf; + auto msg = string_format(title, std::forward(args)...); + printf("| %*s%s%-*s ", indent, "", title_prefix, + LOG_EVENT_LEN - indent - int(strlen(title_prefix)), msg.c_str()); + { + // Print the current structural. + printf("| "); + // Before we begin, the index might point right before the document. + // This could be unsafe, see https://github.com/simdjson/simdjson/discussions/1938 + if (index < iter._root) { + printf("%*s", LOG_BUFFER_LEN, ""); + } else { + auto current_structural = &buf[*index]; + for (int i = 0; i < LOG_BUFFER_LEN; i++) { + printf("%c", printable_char(current_structural[i])); + } + } + printf(" "); + } + { + // Print the next structural. + printf("| "); + auto next_structural = &buf[*(index + 1)]; + for (int i = 0; i < LOG_SMALL_BUFFER_LEN; i++) { + printf("%c", printable_char(next_structural[i])); + } + printf(" "); + } + // printf("| %5u ", *(index+1)); + printf("| %5i ", depth); + printf("| %6.*s ", int(detail.size()), detail.data()); + printf("|\n"); + fflush(stdout); + } + } +} + +} // namespace logger +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H +/* end file simdjson/generic/ondemand/logger-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/object-inl.h for ppc64: #include "simdjson/generic/ondemand/object-inl.h" */ +/* begin file simdjson/generic/ondemand/object-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +simdjson_inline simdjson_result object::find_field_unordered(const std::string_view key) & noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::find_field_unordered(const std::string_view key) && noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::operator[](const std::string_view key) & noexcept { + return find_field_unordered(key); +} +simdjson_inline simdjson_result object::operator[](const std::string_view key) && noexcept { + return std::forward(*this).find_field_unordered(key); +} +simdjson_inline simdjson_result object::find_field(const std::string_view key) & noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::find_field(const std::string_view key) && noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} + +simdjson_inline simdjson_result object::start(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.start_object().error() ); + return object(iter); +} +simdjson_inline simdjson_result object::start_root(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.start_root_object().error() ); + return object(iter); +} +simdjson_inline error_code object::consume() noexcept { + if(iter.is_at_key()) { + /** + * whenever you are pointing at a key, calling skip_child() is + * unsafe because you will hit a string and you will assume that + * it is string value, and this mistake will lead you to make bad + * depth computation. + */ + /** + * We want to 'consume' the key. We could really + * just do _json_iter->return_current_and_advance(); at this + * point, but, for clarity, we will use the high-level API to + * eat the key. We assume that the compiler optimizes away + * most of the work. + */ + simdjson_unused raw_json_string actual_key; + auto error = iter.field_key().get(actual_key); + if (error) { iter.abandon(); return error; }; + // Let us move to the value while we are at it. + if ((error = iter.field_value())) { iter.abandon(); return error; } + } + auto error_skip = iter.json_iter().skip_child(iter.depth()-1); + if(error_skip) { iter.abandon(); } + return error_skip; +} + +simdjson_inline simdjson_result object::raw_json() noexcept { + const uint8_t * starting_point{iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + const uint8_t * final_point{iter._json_iter->peek()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +simdjson_inline simdjson_result object::started(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.started_object().error() ); + return object(iter); +} + +simdjson_inline object object::resume(const value_iterator &iter) noexcept { + return iter; +} + +simdjson_inline object::object(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} + +simdjson_inline simdjson_result object::begin() noexcept { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + return object_iterator(iter); +} +simdjson_inline simdjson_result object::end() noexcept { + return object_iterator(iter); +} + +inline simdjson_result object::at_pointer(std::string_view json_pointer) noexcept { + if (json_pointer[0] != '/') { return INVALID_JSON_POINTER; } + json_pointer = json_pointer.substr(1); + size_t slash = json_pointer.find('/'); + std::string_view key = json_pointer.substr(0, slash); + // Grab the child with the given key + simdjson_result child; + + // If there is an escape character in the key, unescape it and then get the child. + size_t escape = key.find('~'); + if (escape != std::string_view::npos) { + // Unescape the key + std::string unescaped(key); + do { + switch (unescaped[escape+1]) { + case '0': + unescaped.replace(escape, 2, "~"); + break; + case '1': + unescaped.replace(escape, 2, "/"); + break; + default: + return INVALID_JSON_POINTER; // "Unexpected ~ escape character in JSON pointer"); + } + escape = unescaped.find('~', escape+1); + } while (escape != std::string::npos); + child = find_field(unescaped); // Take note find_field does not unescape keys when matching + } else { + child = find_field(key); + } + if(child.error()) { + return child; // we do not continue if there was an error + } + // If there is a /, we have to recurse and look up more of the path + if (slash != std::string_view::npos) { + child = child.at_pointer(json_pointer.substr(slash)); + } + return child; +} + +simdjson_inline simdjson_result object::count_fields() & noexcept { + size_t count{0}; + // Important: we do not consume any of the values. + for(simdjson_unused auto v : *this) { count++; } + // The above loop will always succeed, but we want to report errors. + if(iter.error()) { return iter.error(); } + // We need to move back at the start because we expect users to iterate through + // the object after counting the number of elements. + iter.reset_object(); + return count; +} + +simdjson_inline simdjson_result object::is_empty() & noexcept { + bool is_not_empty; + auto error = iter.reset_object().get(is_not_empty); + if(error) { return error; } + return !is_not_empty; +} + +simdjson_inline simdjson_result object::reset() & noexcept { + return iter.reset_object(); +} + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(ppc64::ondemand::object &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +simdjson_inline simdjson_result simdjson_result::begin() noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() noexcept { + if (error()) { return error(); } + return first.end(); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first).find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first)[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first).find_field(key); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + +inline simdjson_result simdjson_result::reset() noexcept { + if (error()) { return error(); } + return first.reset(); +} + +inline simdjson_result simdjson_result::is_empty() noexcept { + if (error()) { return error(); } + return first.is_empty(); +} + +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H +/* end file simdjson/generic/ondemand/object-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/object_iterator-inl.h for ppc64: #include "simdjson/generic/ondemand/object_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/object_iterator-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +// +// object_iterator +// + +simdjson_inline object_iterator::object_iterator(const value_iterator &_iter) noexcept + : iter{_iter} +{} + +simdjson_inline simdjson_result object_iterator::operator*() noexcept { + error_code error = iter.error(); + if (error) { iter.abandon(); return error; } + auto result = field::start(iter); + // TODO this is a safety rail ... users should exit loops as soon as they receive an error. + // Nonetheless, let's see if performance is OK with this if statement--the compiler may give it to us for free. + if (result.error()) { iter.abandon(); } + return result; +} +simdjson_inline bool object_iterator::operator==(const object_iterator &other) const noexcept { + return !(*this != other); +} +simdjson_inline bool object_iterator::operator!=(const object_iterator &) const noexcept { + return iter.is_open(); +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline object_iterator &object_iterator::operator++() noexcept { + // TODO this is a safety rail ... users should exit loops as soon as they receive an error. + // Nonetheless, let's see if performance is OK with this if statement--the compiler may give it to us for free. + if (!iter.is_open()) { return *this; } // Iterator will be released if there is an error + + simdjson_unused error_code error; + if ((error = iter.skip_child() )) { return *this; } + + simdjson_unused bool has_value; + if ((error = iter.has_next_field().get(has_value) )) { return *this; }; + return *this; +} +SIMDJSON_POP_DISABLE_WARNINGS + +// +// ### Live States +// +// While iterating or looking up values, depth >= iter.depth. at_start may vary. Error is +// always SUCCESS: +// +// - Start: This is the state when the object is first found and the iterator is just past the {. +// In this state, at_start == true. +// - Next: After we hand a scalar value to the user, or an array/object which they then fully +// iterate over, the iterator is at the , or } before the next value. In this state, +// depth == iter.depth, at_start == false, and error == SUCCESS. +// - Unfinished Business: When we hand an array/object to the user which they do not fully +// iterate over, we need to finish that iteration by skipping child values until we reach the +// Next state. In this state, depth > iter.depth, at_start == false, and error == SUCCESS. +// +// ## Error States +// +// In error states, we will yield exactly one more value before stopping. iter.depth == depth +// and at_start is always false. We decrement after yielding the error, moving to the Finished +// state. +// +// - Chained Error: When the object iterator is part of an error chain--for example, in +// `for (auto tweet : doc["tweets"])`, where the tweet field may be missing or not be an +// object--we yield that error in the loop, exactly once. In this state, error != SUCCESS and +// iter.depth == depth, and at_start == false. We decrement depth when we yield the error. +// - Missing Comma Error: When the iterator ++ method discovers there is no comma between fields, +// we flag that as an error and treat it exactly the same as a Chained Error. In this state, +// error == TAPE_ERROR, iter.depth == depth, and at_start == false. +// +// Errors that occur while reading a field to give to the user (such as when the key is not a +// string or the field is missing a colon) are yielded immediately. Depth is then decremented, +// moving to the Finished state without transitioning through an Error state at all. +// +// ## Terminal State +// +// The terminal state has iter.depth < depth. at_start is always false. +// +// - Finished: When we have reached a }, we are finished. We signal this by decrementing depth. +// In this state, iter.depth < depth, at_start == false, and error == SUCCESS. +// + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + ppc64::ondemand::object_iterator &&value +) noexcept + : implementation_simdjson_result_base(std::forward(value)) +{ + first.iter.assert_is_valid(); +} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base({}, error) +{ +} + +simdjson_inline simdjson_result simdjson_result::operator*() noexcept { + if (error()) { return error(); } + return *first; +} +// If we're iterating and there is an error, return the error once. +simdjson_inline bool simdjson_result::operator==(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return !error(); } + return first == other.first; +} +// If we're iterating and there is an error, return the error once. +simdjson_inline bool simdjson_result::operator!=(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return error(); } + return first != other.first; +} +// Checks for ']' and ',' +simdjson_inline simdjson_result &simdjson_result::operator++() noexcept { + // Clear the error if there is one, so we don't yield it twice + if (error()) { second = SUCCESS; return *this; } + ++first; + return *this; +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/object_iterator-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/parser-inl.h for ppc64: #include "simdjson/generic/ondemand/parser-inl.h" */ +/* begin file simdjson/generic/ondemand/parser-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/padded_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/padded_string_view.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/dom/base.h" // for MINIMAL_DOCUMENT_CAPACITY */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document_stream.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +simdjson_inline parser::parser(size_t max_capacity) noexcept + : _max_capacity{max_capacity} { +} + +simdjson_warn_unused simdjson_inline error_code parser::allocate(size_t new_capacity, size_t new_max_depth) noexcept { + if (new_capacity > max_capacity()) { return CAPACITY; } + if (string_buf && new_capacity == capacity() && new_max_depth == max_depth()) { return SUCCESS; } + + // string_capacity copied from document::allocate + _capacity = 0; + size_t string_capacity = SIMDJSON_ROUNDUP_N(5 * new_capacity / 3 + SIMDJSON_PADDING, 64); + string_buf.reset(new (std::nothrow) uint8_t[string_capacity]); +#if SIMDJSON_DEVELOPMENT_CHECKS + start_positions.reset(new (std::nothrow) token_position[new_max_depth]); +#endif + if (implementation) { + SIMDJSON_TRY( implementation->set_capacity(new_capacity) ); + SIMDJSON_TRY( implementation->set_max_depth(new_max_depth) ); + } else { + SIMDJSON_TRY( simdjson::get_active_implementation()->create_dom_parser_implementation(new_capacity, new_max_depth, implementation) ); + } + _capacity = new_capacity; + _max_depth = new_max_depth; + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(padded_string_view json) & noexcept { + if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; } + + json.remove_utf8_bom(); + + // Allocate if needed + if (capacity() < json.length() || !string_buf) { + SIMDJSON_TRY( allocate(json.length(), max_depth()) ); + } + + // Run stage 1. + SIMDJSON_TRY( implementation->stage1(reinterpret_cast(json.data()), json.length(), stage1_mode::regular) ); + return document::start({ reinterpret_cast(json.data()), this }); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const char *json, size_t len, size_t allocated) & noexcept { + return iterate(padded_string_view(json, len, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const uint8_t *json, size_t len, size_t allocated) & noexcept { + return iterate(padded_string_view(json, len, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(std::string_view json, size_t allocated) & noexcept { + return iterate(padded_string_view(json, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(std::string &json) & noexcept { + if(json.capacity() - json.size() < SIMDJSON_PADDING) { + json.reserve(json.size() + SIMDJSON_PADDING); + } + return iterate(padded_string_view(json)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const std::string &json) & noexcept { + return iterate(padded_string_view(json)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const simdjson_result &result) & noexcept { + // We don't presently have a way to temporarily get a const T& from a simdjson_result without throwing an exception + SIMDJSON_TRY( result.error() ); + padded_string_view json = result.value_unsafe(); + return iterate(json); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const simdjson_result &result) & noexcept { + // We don't presently have a way to temporarily get a const T& from a simdjson_result without throwing an exception + SIMDJSON_TRY( result.error() ); + const padded_string &json = result.value_unsafe(); + return iterate(json); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate_raw(padded_string_view json) & noexcept { + if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; } + + json.remove_utf8_bom(); + + // Allocate if needed + if (capacity() < json.length()) { + SIMDJSON_TRY( allocate(json.length(), max_depth()) ); + } + + // Run stage 1. + SIMDJSON_TRY( implementation->stage1(reinterpret_cast(json.data()), json.length(), stage1_mode::regular) ); + return json_iterator(reinterpret_cast(json.data()), this); +} + +inline simdjson_result parser::iterate_many(const uint8_t *buf, size_t len, size_t batch_size, bool allow_comma_separated) noexcept { + if(batch_size < MINIMAL_BATCH_SIZE) { batch_size = MINIMAL_BATCH_SIZE; } + if((len >= 3) && (std::memcmp(buf, "\xEF\xBB\xBF", 3) == 0)) { + buf += 3; + len -= 3; + } + if(allow_comma_separated && batch_size < len) { batch_size = len; } + return document_stream(*this, buf, len, batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const char *buf, size_t len, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(reinterpret_cast(buf), len, batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const std::string &s, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(s.data(), s.length(), batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const padded_string &s, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(s.data(), s.length(), batch_size, allow_comma_separated); +} + +simdjson_inline size_t parser::capacity() const noexcept { + return _capacity; +} +simdjson_inline size_t parser::max_capacity() const noexcept { + return _max_capacity; +} +simdjson_inline size_t parser::max_depth() const noexcept { + return _max_depth; +} + +simdjson_inline void parser::set_max_capacity(size_t max_capacity) noexcept { + if(max_capacity < dom::MINIMAL_DOCUMENT_CAPACITY) { + _max_capacity = max_capacity; + } else { + _max_capacity = dom::MINIMAL_DOCUMENT_CAPACITY; + } +} + +simdjson_inline simdjson_warn_unused simdjson_result parser::unescape(raw_json_string in, uint8_t *&dst, bool allow_replacement) const noexcept { + uint8_t *end = implementation->parse_string(in.buf, dst, allow_replacement); + if (!end) { return STRING_ERROR; } + std::string_view result(reinterpret_cast(dst), end-dst); + dst = end; + return result; +} + +simdjson_inline simdjson_warn_unused simdjson_result parser::unescape_wobbly(raw_json_string in, uint8_t *&dst) const noexcept { + uint8_t *end = implementation->parse_wobbly_string(in.buf, dst); + if (!end) { return STRING_ERROR; } + std::string_view result(reinterpret_cast(dst), end-dst); + dst = end; + return result; +} + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(ppc64::ondemand::parser &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H +/* end file simdjson/generic/ondemand/parser-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/raw_json_string-inl.h for ppc64: #include "simdjson/generic/ondemand/raw_json_string-inl.h" */ +/* begin file simdjson/generic/ondemand/raw_json_string-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +namespace ppc64 { +namespace ondemand { + +simdjson_inline raw_json_string::raw_json_string(const uint8_t * _buf) noexcept : buf{_buf} {} + +simdjson_inline const char * raw_json_string::raw() const noexcept { return reinterpret_cast(buf); } + + +simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(std::string_view target) noexcept { + size_t pos{0}; + // if the content has no escape character, just scan through it quickly! + for(;pos < target.size() && target[pos] != '\\';pos++) {} + // slow path may begin. + bool escaping{false}; + for(;pos < target.size();pos++) { + if((target[pos] == '"') && !escaping) { + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + return true; +} + +simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(const char* target) noexcept { + size_t pos{0}; + // if the content has no escape character, just scan through it quickly! + for(;target[pos] && target[pos] != '\\';pos++) {} + // slow path may begin. + bool escaping{false}; + for(;target[pos];pos++) { + if((target[pos] == '"') && !escaping) { + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + return true; +} + + +simdjson_inline bool raw_json_string::unsafe_is_equal(size_t length, std::string_view target) const noexcept { + // If we are going to call memcmp, then we must know something about the length of the raw_json_string. + return (length >= target.size()) && (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size()); +} + +simdjson_inline bool raw_json_string::unsafe_is_equal(std::string_view target) const noexcept { + // Assumptions: does not contain unescaped quote characters, and + // the raw content is quote terminated within a valid JSON string. + if(target.size() <= SIMDJSON_PADDING) { + return (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size()); + } + const char * r{raw()}; + size_t pos{0}; + for(;pos < target.size();pos++) { + if(r[pos] != target[pos]) { return false; } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_inline bool raw_json_string::is_equal(std::string_view target) const noexcept { + const char * r{raw()}; + size_t pos{0}; + bool escaping{false}; + for(;pos < target.size();pos++) { + if(r[pos] != target[pos]) { return false; } + // if target is a compile-time constant and it is free from + // quotes, then the next part could get optimized away through + // inlining. + if((target[pos] == '"') && !escaping) { + // We have reached the end of the raw_json_string but + // the target is not done. + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + if(r[pos] != '"') { return false; } + return true; +} + + +simdjson_inline bool raw_json_string::unsafe_is_equal(const char * target) const noexcept { + // Assumptions: 'target' does not contain unescaped quote characters, is null terminated and + // the raw content is quote terminated within a valid JSON string. + const char * r{raw()}; + size_t pos{0}; + for(;target[pos];pos++) { + if(r[pos] != target[pos]) { return false; } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_inline bool raw_json_string::is_equal(const char* target) const noexcept { + // Assumptions: does not contain unescaped quote characters, and + // the raw content is quote terminated within a valid JSON string. + const char * r{raw()}; + size_t pos{0}; + bool escaping{false}; + for(;target[pos];pos++) { + if(r[pos] != target[pos]) { return false; } + // if target is a compile-time constant and it is free from + // quotes, then the next part could get optimized away through + // inlining. + if((target[pos] == '"') && !escaping) { + // We have reached the end of the raw_json_string but + // the target is not done. + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept { + return a.unsafe_is_equal(c); +} + +simdjson_unused simdjson_inline bool operator==(std::string_view c, const raw_json_string &a) noexcept { + return a == c; +} + +simdjson_unused simdjson_inline bool operator!=(const raw_json_string &a, std::string_view c) noexcept { + return !(a == c); +} + +simdjson_unused simdjson_inline bool operator!=(std::string_view c, const raw_json_string &a) noexcept { + return !(a == c); +} + + +simdjson_inline simdjson_warn_unused simdjson_result raw_json_string::unescape(json_iterator &iter, bool allow_replacement) const noexcept { + return iter.unescape(*this, allow_replacement); +} + +simdjson_inline simdjson_warn_unused simdjson_result raw_json_string::unescape_wobbly(json_iterator &iter) const noexcept { + return iter.unescape_wobbly(*this); +} + +simdjson_unused simdjson_inline std::ostream &operator<<(std::ostream &out, const raw_json_string &str) noexcept { + bool in_escape = false; + const char *s = str.raw(); + while (true) { + switch (*s) { + case '\\': in_escape = !in_escape; break; + case '"': if (in_escape) { in_escape = false; } else { return out; } break; + default: if (in_escape) { in_escape = false; } + } + out << *s; + s++; + } +} + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(ppc64::ondemand::raw_json_string &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +simdjson_inline simdjson_result simdjson_result::raw() const noexcept { + if (error()) { return error(); } + return first.raw(); +} +simdjson_inline simdjson_warn_unused simdjson_result simdjson_result::unescape(ppc64::ondemand::json_iterator &iter, bool allow_replacement) const noexcept { + if (error()) { return error(); } + return first.unescape(iter, allow_replacement); +} +simdjson_inline simdjson_warn_unused simdjson_result simdjson_result::unescape_wobbly(ppc64::ondemand::json_iterator &iter) const noexcept { + if (error()) { return error(); } + return first.unescape_wobbly(iter); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H +/* end file simdjson/generic/ondemand/raw_json_string-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/serialization-inl.h for ppc64: #include "simdjson/generic/ondemand/serialization-inl.h" */ +/* begin file simdjson/generic/ondemand/serialization-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/serialization.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +inline std::string_view trim(const std::string_view str) noexcept { + // We can almost surely do better by rolling our own find_first_not_of function. + size_t first = str.find_first_not_of(" \t\n\r"); + // If we have the empty string (just white space), then no trimming is possible, and + // we return the empty string_view. + if (std::string_view::npos == first) { return std::string_view(); } + size_t last = str.find_last_not_of(" \t\n\r"); + return str.substr(first, (last - first + 1)); +} + + +inline simdjson_result to_json_string(ppc64::ondemand::document& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(ppc64::ondemand::document_reference& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(ppc64::ondemand::value& x) noexcept { + /** + * If we somehow receive a value that has already been consumed, + * then the following code could be in trouble. E.g., we create + * an array as needed, but if an array was already created, then + * it could be bad. + */ + using namespace ppc64::ondemand; + ppc64::ondemand::json_type t; + auto error = x.type().get(t); + if(error != SUCCESS) { return error; } + switch (t) + { + case json_type::array: + { + ppc64::ondemand::array array; + error = x.get_array().get(array); + if(error) { return error; } + return to_json_string(array); + } + case json_type::object: + { + ppc64::ondemand::object object; + error = x.get_object().get(object); + if(error) { return error; } + return to_json_string(object); + } + default: + return trim(x.raw_json_token()); + } +} + +inline simdjson_result to_json_string(ppc64::ondemand::object& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(ppc64::ondemand::array& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} +} // namespace simdjson + +namespace simdjson { namespace ppc64 { namespace ondemand { + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::ppc64::ondemand::value x) { + std::string_view v; + auto error = simdjson::to_json_string(x).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::ppc64::ondemand::value x) { + std::string_view v; + auto error = simdjson::to_json_string(x).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::ppc64::ondemand::array value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::ppc64::ondemand::array value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::ppc64::ondemand::document& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::ppc64::ondemand::document_reference& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::ppc64::ondemand::document& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::ppc64::ondemand::object value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::ppc64::ondemand::object value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif +}}} // namespace simdjson::ppc64::ondemand + +#endif // SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H +/* end file simdjson/generic/ondemand/serialization-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/token_iterator-inl.h for ppc64: #include "simdjson/generic/ondemand/token_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/token_iterator-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +simdjson_inline token_iterator::token_iterator( + const uint8_t *_buf, + token_position position +) noexcept : buf{_buf}, _position{position} +{ +} + +simdjson_inline uint32_t token_iterator::current_offset() const noexcept { + return *(_position); +} + + +simdjson_inline const uint8_t *token_iterator::return_current_and_advance() noexcept { + return &buf[*(_position++)]; +} + +simdjson_inline const uint8_t *token_iterator::peek(token_position position) const noexcept { + return &buf[*position]; +} +simdjson_inline uint32_t token_iterator::peek_index(token_position position) const noexcept { + return *position; +} +simdjson_inline uint32_t token_iterator::peek_length(token_position position) const noexcept { + return *(position+1) - *position; +} + +simdjson_inline const uint8_t *token_iterator::peek(int32_t delta) const noexcept { + return &buf[*(_position+delta)]; +} +simdjson_inline uint32_t token_iterator::peek_index(int32_t delta) const noexcept { + return *(_position+delta); +} +simdjson_inline uint32_t token_iterator::peek_length(int32_t delta) const noexcept { + return *(_position+delta+1) - *(_position+delta); +} + +simdjson_inline token_position token_iterator::position() const noexcept { + return _position; +} +simdjson_inline void token_iterator::set_position(token_position target_position) noexcept { + _position = target_position; +} + +simdjson_inline bool token_iterator::operator==(const token_iterator &other) const noexcept { + return _position == other._position; +} +simdjson_inline bool token_iterator::operator!=(const token_iterator &other) const noexcept { + return _position != other._position; +} +simdjson_inline bool token_iterator::operator>(const token_iterator &other) const noexcept { + return _position > other._position; +} +simdjson_inline bool token_iterator::operator>=(const token_iterator &other) const noexcept { + return _position >= other._position; +} +simdjson_inline bool token_iterator::operator<(const token_iterator &other) const noexcept { + return _position < other._position; +} +simdjson_inline bool token_iterator::operator<=(const token_iterator &other) const noexcept { + return _position <= other._position; +} + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(ppc64::ondemand::token_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/token_iterator-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/value-inl.h for ppc64: #include "simdjson/generic/ondemand/value-inl.h" */ +/* begin file simdjson/generic/ondemand/value-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +simdjson_inline value::value(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} +simdjson_inline value value::start(const value_iterator &iter) noexcept { + return iter; +} +simdjson_inline value value::resume(const value_iterator &iter) noexcept { + return iter; +} + +simdjson_inline simdjson_result value::get_array() noexcept { + return array::start(iter); +} +simdjson_inline simdjson_result value::get_object() noexcept { + return object::start(iter); +} +simdjson_inline simdjson_result value::start_or_resume_object() noexcept { + if (iter.at_start()) { + return get_object(); + } else { + return object::resume(iter); + } +} + +simdjson_inline simdjson_result value::get_raw_json_string() noexcept { + return iter.get_raw_json_string(); +} +simdjson_inline simdjson_result value::get_string(bool allow_replacement) noexcept { + return iter.get_string(allow_replacement); +} +template +simdjson_inline error_code value::get_string(string_type& receiver, bool allow_replacement) noexcept { + return iter.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result value::get_wobbly_string() noexcept { + return iter.get_wobbly_string(); +} +simdjson_inline simdjson_result value::get_double() noexcept { + return iter.get_double(); +} +simdjson_inline simdjson_result value::get_double_in_string() noexcept { + return iter.get_double_in_string(); +} +simdjson_inline simdjson_result value::get_uint64() noexcept { + return iter.get_uint64(); +} +simdjson_inline simdjson_result value::get_uint64_in_string() noexcept { + return iter.get_uint64_in_string(); +} +simdjson_inline simdjson_result value::get_int64() noexcept { + return iter.get_int64(); +} +simdjson_inline simdjson_result value::get_int64_in_string() noexcept { + return iter.get_int64_in_string(); +} +simdjson_inline simdjson_result value::get_bool() noexcept { + return iter.get_bool(); +} +simdjson_inline simdjson_result value::is_null() noexcept { + return iter.is_null(); +} +template<> simdjson_inline simdjson_result value::get() noexcept { return get_array(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_object(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_number(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_double(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_uint64(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_int64(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_bool(); } + +template simdjson_inline error_code value::get(T &out) noexcept { + return get().get(out); +} + +#if SIMDJSON_EXCEPTIONS +simdjson_inline value::operator array() noexcept(false) { + return get_array(); +} +simdjson_inline value::operator object() noexcept(false) { + return get_object(); +} +simdjson_inline value::operator uint64_t() noexcept(false) { + return get_uint64(); +} +simdjson_inline value::operator int64_t() noexcept(false) { + return get_int64(); +} +simdjson_inline value::operator double() noexcept(false) { + return get_double(); +} +simdjson_inline value::operator std::string_view() noexcept(false) { + return get_string(false); +} +simdjson_inline value::operator raw_json_string() noexcept(false) { + return get_raw_json_string(); +} +simdjson_inline value::operator bool() noexcept(false) { + return get_bool(); +} +#endif + +simdjson_inline simdjson_result value::begin() & noexcept { + return get_array().begin(); +} +simdjson_inline simdjson_result value::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result value::count_elements() & noexcept { + simdjson_result answer; + auto a = get_array(); + answer = a.count_elements(); + // count_elements leaves you pointing inside the array, at the first element. + // We need to move back so that the user can create a new array (which requires that + // we point at '['). + iter.move_at_start(); + return answer; +} +simdjson_inline simdjson_result value::count_fields() & noexcept { + simdjson_result answer; + auto a = get_object(); + answer = a.count_fields(); + iter.move_at_start(); + return answer; +} +simdjson_inline simdjson_result value::at(size_t index) noexcept { + auto a = get_array(); + return a.at(index); +} + +simdjson_inline simdjson_result value::find_field(std::string_view key) noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result value::find_field(const char *key) noexcept { + return start_or_resume_object().find_field(key); +} + +simdjson_inline simdjson_result value::find_field_unordered(std::string_view key) noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result value::find_field_unordered(const char *key) noexcept { + return start_or_resume_object().find_field_unordered(key); +} + +simdjson_inline simdjson_result value::operator[](std::string_view key) noexcept { + return start_or_resume_object()[key]; +} +simdjson_inline simdjson_result value::operator[](const char *key) noexcept { + return start_or_resume_object()[key]; +} + +simdjson_inline simdjson_result value::type() noexcept { + return iter.type(); +} + +simdjson_inline simdjson_result value::is_scalar() noexcept { + json_type this_type; + auto error = type().get(this_type); + if(error) { return error; } + return ! ((this_type == json_type::array) || (this_type == json_type::object)); +} + +simdjson_inline bool value::is_negative() noexcept { + return iter.is_negative(); +} + +simdjson_inline simdjson_result value::is_integer() noexcept { + return iter.is_integer(); +} +simdjson_warn_unused simdjson_inline simdjson_result value::get_number_type() noexcept { + return iter.get_number_type(); +} +simdjson_warn_unused simdjson_inline simdjson_result value::get_number() noexcept { + return iter.get_number(); +} + +simdjson_inline std::string_view value::raw_json_token() noexcept { + return std::string_view(reinterpret_cast(iter.peek_start()), iter.peek_start_length()); +} + +simdjson_inline simdjson_result value::raw_json() noexcept { + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: { + ondemand::array array; + SIMDJSON_TRY(get_array().get(array)); + return array.raw_json(); + } + case json_type::object: { + ondemand::object object; + SIMDJSON_TRY(get_object().get(object)); + return object.raw_json(); + } + default: + return raw_json_token(); + } +} + +simdjson_inline simdjson_result value::current_location() noexcept { + return iter.json_iter().current_location(); +} + +simdjson_inline int32_t value::current_depth() const noexcept{ + return iter.json_iter().depth(); +} + +simdjson_inline simdjson_result value::at_pointer(std::string_view json_pointer) noexcept { + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: + return (*this).get_array().at_pointer(json_pointer); + case json_type::object: + return (*this).get_object().at_pointer(json_pointer); + default: + return INVALID_JSON_POINTER; + } +} + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + ppc64::ondemand::value &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + if (error()) { return error(); } + return {}; +} + +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) noexcept { + if (error()) { return error(); } + return first.find_field(key); +} + +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} + +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) noexcept { + if (error()) { return error(); } + return first[key]; +} + +simdjson_inline simdjson_result simdjson_result::get_array() noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} + +template simdjson_inline simdjson_result simdjson_result::get() noexcept { + if (error()) { return error(); } + return first.get(); +} +template simdjson_inline error_code simdjson_result::get(T &out) noexcept { + if (error()) { return error(); } + return first.get(out); +} + +template<> simdjson_inline simdjson_result simdjson_result::get() noexcept { + if (error()) { return error(); } + return std::move(first); +} +template<> simdjson_inline error_code simdjson_result::get(ppc64::ondemand::value &out) noexcept { + if (error()) { return error(); } + out = first; + return SUCCESS; +} + +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} +simdjson_inline simdjson_result simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator ppc64::ondemand::array() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator ppc64::ondemand::object() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator ppc64::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline simdjson_result simdjson_result::current_depth() const noexcept { + if (error()) { return error(); } + return first.current_depth(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H +/* end file simdjson/generic/ondemand/value-inl.h for ppc64 */ +/* including simdjson/generic/ondemand/value_iterator-inl.h for ppc64: #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/value_iterator-inl.h for ppc64 */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/atomparsing.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/numberparsing.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace ppc64 { +namespace ondemand { + +simdjson_inline value_iterator::value_iterator( + json_iterator *json_iter, + depth_t depth, + token_position start_position +) noexcept : _json_iter{json_iter}, _depth{depth}, _start_position{start_position} +{ +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_object() noexcept { + SIMDJSON_TRY( start_container('{', "Not an object", "object") ); + return started_object(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_root_object() noexcept { + SIMDJSON_TRY( start_container('{', "Not an object", "object") ); + return started_root_object(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_object() noexcept { + assert_at_container_start(); +#if SIMDJSON_DEVELOPMENT_CHECKS + _json_iter->set_start_position(_depth, start_position()); +#endif + if (*_json_iter->peek() == '}') { + logger::log_value(*_json_iter, "empty object"); + _json_iter->return_current_and_advance(); + end_container(); + return false; + } + return true; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::check_root_object() noexcept { + // When in streaming mode, we cannot expect peek_last() to be the last structural element of the + // current document. It only works in the normal mode where we have indexed a single document. + // Note that adding a check for 'streaming' is not expensive since we only have at most + // one root element. + if ( ! _json_iter->streaming() ) { + // The following lines do not fully protect against garbage content within the + // object: e.g., `{"a":2} foo }`. Users concerned with garbage content should + // call `at_end()` on the document instance at the end of the processing to + // ensure that the processing has finished at the end. + // + if (*_json_iter->peek_last() != '}') { + _json_iter->abandon(); + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing } at end"); + } + // If the last character is } *and* the first gibberish character is also '}' + // then on-demand could accidentally go over. So we need additional checks. + // https://github.com/simdjson/simdjson/issues/1834 + // Checking that the document is balanced requires a full scan which is potentially + // expensive, but it only happens in edge cases where the first padding character is + // a closing bracket. + if ((*_json_iter->peek(_json_iter->end_position()) == '}') && (!_json_iter->balanced())) { + _json_iter->abandon(); + // The exact error would require more work. It will typically be an unclosed object. + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "the document is unbalanced"); + } + } + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_root_object() noexcept { + auto error = check_root_object(); + if(error) { return error; } + return started_object(); +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::end_container() noexcept { +#if SIMDJSON_CHECK_EOF + if (depth() > 1 && at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing parent ] or }"); } + // if (depth() <= 1 && !at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing [ or { at start"); } +#endif // SIMDJSON_CHECK_EOF + _json_iter->ascend_to(depth()-1); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::has_next_field() noexcept { + assert_at_next(); + + // It's illegal to call this unless there are more tokens: anything that ends in } or ] is + // obligated to verify there are more tokens if they are not the top level. + switch (*_json_iter->return_current_and_advance()) { + case '}': + logger::log_end_value(*_json_iter, "object"); + SIMDJSON_TRY( end_container() ); + return false; + case ',': + return true; + default: + return report_error(TAPE_ERROR, "Missing comma between object fields"); + } +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::find_field_raw(const std::string_view key) noexcept { + error_code error; + bool has_value; + // + // Initially, the object can be in one of a few different places: + // + // 1. The start of the object, at the first field: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2, index 1) + // ``` + if (at_first_field()) { + has_value = true; + + // + // 2. When a previous search did not yield a value or the object is empty: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // { } + // ^ (depth 0, index 2) + // ``` + // + } else if (!is_open()) { +#if SIMDJSON_DEVELOPMENT_CHECKS + // If we're past the end of the object, we're being iterated out of order. + // Note: this isn't perfect detection. It's possible the user is inside some other object; if so, + // this object iterator will blithely scan that object for fields. + if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; } +#endif + return false; + + // 3. When a previous search found a field or an iterator yielded a value: + // + // ``` + // // When a field was not fully consumed (or not even touched at all) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2) + // // When a field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // When the last field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // ``` + // + } else { + if ((error = skip_child() )) { abandon(); return error; } + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } +#if SIMDJSON_DEVELOPMENT_CHECKS + if (_json_iter->start_position(_depth) != start_position()) { return OUT_OF_ORDER_ITERATION; } +#endif + } + while (has_value) { + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + if ((error = field_key().get(actual_key) )) { abandon(); return error; }; + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + if ((error = field_value() )) { abandon(); return error; } + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + //if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); // Skip the value entirely + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } + } + + // If the loop ended, we're out of fields to look at. + return false; +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::find_field_unordered_raw(const std::string_view key) noexcept { + /** + * When find_field_unordered_raw is called, we can either be pointing at the + * first key, pointing outside (at the closing brace) or if a key was matched + * we can be either pointing right afterthe ':' right before the value (that we need skip), + * or we may have consumed the value and we might be at a comma or at the + * final brace (ready for a call to has_next_field()). + */ + error_code error; + bool has_value; + + // First, we scan from that point to the end. + // If we don't find a match, we may loop back around, and scan from the beginning to that point. + token_position search_start = _json_iter->position(); + + // We want to know whether we need to go back to the beginning. + bool at_first = at_first_field(); + /////////////// + // Initially, the object can be in one of a few different places: + // + // 1. At the first key: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2, index 1) + // ``` + // + if (at_first) { + has_value = true; + + // 2. When a previous search did not yield a value or the object is empty: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // { } + // ^ (depth 0, index 2) + // ``` + // + } else if (!is_open()) { + +#if SIMDJSON_DEVELOPMENT_CHECKS + // If we're past the end of the object, we're being iterated out of order. + // Note: this isn't perfect detection. It's possible the user is inside some other object; if so, + // this object iterator will blithely scan that object for fields. + if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; } +#endif + SIMDJSON_TRY(reset_object().get(has_value)); + at_first = true; + // 3. When a previous search found a field or an iterator yielded a value: + // + // ``` + // // When a field was not fully consumed (or not even touched at all) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2) + // // When a field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // When the last field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // ``` + // + } else { + // If someone queried a key but they not did access the value, then we are left pointing + // at the ':' and we need to move forward through the value... If the value was + // processed then skip_child() does not move the iterator (but may adjust the depth). + if ((error = skip_child() )) { abandon(); return error; } + search_start = _json_iter->position(); + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } +#if SIMDJSON_DEVELOPMENT_CHECKS + if (_json_iter->start_position(_depth) != start_position()) { return OUT_OF_ORDER_ITERATION; } +#endif + } + + // After initial processing, we will be in one of two states: + // + // ``` + // // At the beginning of a field + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // At the end of the object + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // ``` + // + // Next, we find a match starting from the current position. + while (has_value) { + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); // We must be at the start of a field + + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + if ((error = field_key().get(actual_key) )) { abandon(); return error; }; + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + if ((error = field_value() )) { abandon(); return error; } + + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + // if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } + } + // Performance note: it maybe wasteful to rewind to the beginning when there might be + // no other query following. Indeed, it would require reskipping the whole object. + // Instead, you can just stay where you are. If there is a new query, there is always time + // to rewind. + if(at_first) { return false; } + + // If we reach the end without finding a match, search the rest of the fields starting at the + // beginning of the object. + // (We have already run through the object before, so we've already validated its structure. We + // don't check errors in this bit.) + SIMDJSON_TRY(reset_object().get(has_value)); + while (true) { + SIMDJSON_ASSUME(has_value); // we should reach search_start before ever reaching the end of the object + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); // We must be at the start of a field + + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + error = field_key().get(actual_key); SIMDJSON_ASSUME(!error); + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + error = field_value(); SIMDJSON_ASSUME(!error); + + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + // if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); + // If we reached the end of the key-value pair we started from, then we know + // that the key is not there so we return false. We are either right before + // the next comma or the final brace. + if(_json_iter->position() == search_start) { return false; } + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + error = has_next_field().get(has_value); SIMDJSON_ASSUME(!error); + // If we make the mistake of exiting here, then we could be left pointing at a key + // in the middle of an object. That's not an allowable state. + } + // If the loop ended, we're out of fields to look at. The program should + // never reach this point. + return false; +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::field_key() noexcept { + assert_at_next(); + + const uint8_t *key = _json_iter->return_current_and_advance(); + if (*(key++) != '"') { return report_error(TAPE_ERROR, "Object key is not a string"); } + return raw_json_string(key); +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::field_value() noexcept { + assert_at_next(); + + if (*_json_iter->return_current_and_advance() != ':') { return report_error(TAPE_ERROR, "Missing colon in object field"); } + _json_iter->descend_to(depth()+1); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_array() noexcept { + SIMDJSON_TRY( start_container('[', "Not an array", "array") ); + return started_array(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_root_array() noexcept { + SIMDJSON_TRY( start_container('[', "Not an array", "array") ); + return started_root_array(); +} + +inline std::string value_iterator::to_string() const noexcept { + auto answer = std::string("value_iterator [ depth : ") + std::to_string(_depth) + std::string(", "); + if(_json_iter != nullptr) { answer += _json_iter->to_string(); } + answer += std::string(" ]"); + return answer; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_array() noexcept { + assert_at_container_start(); + if (*_json_iter->peek() == ']') { + logger::log_value(*_json_iter, "empty array"); + _json_iter->return_current_and_advance(); + SIMDJSON_TRY( end_container() ); + return false; + } + _json_iter->descend_to(depth()+1); +#if SIMDJSON_DEVELOPMENT_CHECKS + _json_iter->set_start_position(_depth, start_position()); +#endif + return true; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::check_root_array() noexcept { + // When in streaming mode, we cannot expect peek_last() to be the last structural element of the + // current document. It only works in the normal mode where we have indexed a single document. + // Note that adding a check for 'streaming' is not expensive since we only have at most + // one root element. + if ( ! _json_iter->streaming() ) { + // The following lines do not fully protect against garbage content within the + // array: e.g., `[1, 2] foo]`. Users concerned with garbage content should + // also call `at_end()` on the document instance at the end of the processing to + // ensure that the processing has finished at the end. + // + if (*_json_iter->peek_last() != ']') { + _json_iter->abandon(); + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing ] at end"); + } + // If the last character is ] *and* the first gibberish character is also ']' + // then on-demand could accidentally go over. So we need additional checks. + // https://github.com/simdjson/simdjson/issues/1834 + // Checking that the document is balanced requires a full scan which is potentially + // expensive, but it only happens in edge cases where the first padding character is + // a closing bracket. + if ((*_json_iter->peek(_json_iter->end_position()) == ']') && (!_json_iter->balanced())) { + _json_iter->abandon(); + // The exact error would require more work. It will typically be an unclosed array. + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "the document is unbalanced"); + } + } + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_root_array() noexcept { + auto error = check_root_array(); + if (error) { return error; } + return started_array(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::has_next_element() noexcept { + assert_at_next(); + + logger::log_event(*this, "has_next_element"); + switch (*_json_iter->return_current_and_advance()) { + case ']': + logger::log_end_value(*_json_iter, "array"); + SIMDJSON_TRY( end_container() ); + return false; + case ',': + _json_iter->descend_to(depth()+1); + return true; + default: + return report_error(TAPE_ERROR, "Missing comma between array elements"); + } +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::parse_bool(const uint8_t *json) const noexcept { + auto not_true = atomparsing::str4ncmp(json, "true"); + auto not_false = atomparsing::str4ncmp(json, "fals") | (json[4] ^ 'e'); + bool error = (not_true && not_false) || jsoncharutils::is_not_structural_or_whitespace(json[not_true ? 5 : 4]); + if (error) { return incorrect_type_error("Not a boolean"); } + return simdjson_result(!not_true); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::parse_null(const uint8_t *json) const noexcept { + bool is_null_string = !atomparsing::str4ncmp(json, "null") && jsoncharutils::is_structural_or_whitespace(json[4]); + // if we start with 'n', we must be a null + if(!is_null_string && json[0]=='n') { return incorrect_type_error("Not a null but starts with n"); } + return is_null_string; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_string(bool allow_replacement) noexcept { + return get_raw_json_string().unescape(json_iter(), allow_replacement); +} +template +simdjson_warn_unused simdjson_inline error_code value_iterator::get_string(string_type& receiver, bool allow_replacement) noexcept { + std::string_view content; + auto err = get_string(allow_replacement).get(content); + if (err) { return err; } + receiver = content; + return SUCCESS; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_wobbly_string() noexcept { + return get_raw_json_string().unescape_wobbly(json_iter()); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_raw_json_string() noexcept { + auto json = peek_scalar("string"); + if (*json != '"') { return incorrect_type_error("Not a string"); } + advance_scalar("string"); + return raw_json_string(json+1); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_uint64() noexcept { + auto result = numberparsing::parse_unsigned(peek_non_root_scalar("uint64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("uint64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_uint64_in_string() noexcept { + auto result = numberparsing::parse_unsigned_in_string(peek_non_root_scalar("uint64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("uint64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_int64() noexcept { + auto result = numberparsing::parse_integer(peek_non_root_scalar("int64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("int64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_int64_in_string() noexcept { + auto result = numberparsing::parse_integer_in_string(peek_non_root_scalar("int64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("int64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_double() noexcept { + auto result = numberparsing::parse_double(peek_non_root_scalar("double")); + if(result.error() == SUCCESS) { advance_non_root_scalar("double"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_double_in_string() noexcept { + auto result = numberparsing::parse_double_in_string(peek_non_root_scalar("double")); + if(result.error() == SUCCESS) { advance_non_root_scalar("double"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_bool() noexcept { + auto result = parse_bool(peek_non_root_scalar("bool")); + if(result.error() == SUCCESS) { advance_non_root_scalar("bool"); } + return result; +} +simdjson_inline simdjson_result value_iterator::is_null() noexcept { + bool is_null_value; + SIMDJSON_TRY(parse_null(peek_non_root_scalar("null")).get(is_null_value)); + if(is_null_value) { advance_non_root_scalar("null"); } + return is_null_value; +} +simdjson_inline bool value_iterator::is_negative() noexcept { + return numberparsing::is_negative(peek_non_root_scalar("numbersign")); +} +simdjson_inline bool value_iterator::is_root_negative() noexcept { + return numberparsing::is_negative(peek_root_scalar("numbersign")); +} +simdjson_inline simdjson_result value_iterator::is_integer() noexcept { + return numberparsing::is_integer(peek_non_root_scalar("integer")); +} +simdjson_inline simdjson_result value_iterator::get_number_type() noexcept { + return numberparsing::get_number_type(peek_non_root_scalar("integer")); +} +simdjson_inline simdjson_result value_iterator::get_number() noexcept { + number num; + error_code error = numberparsing::parse_number(peek_non_root_scalar("number"), num); + if(error) { return error; } + return num; +} + +simdjson_inline simdjson_result value_iterator::is_root_integer(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("is_root_integer"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + return false; // if there are more than 20 characters, it cannot be represented as an integer. + } + auto answer = numberparsing::is_integer(tmpbuf); + // If the parsing was a success, we must still check that it is + // a single scalar. Note that we parse first because of cases like '[]' where + // getting TRAILING_CONTENT is wrong. + if(check_trailing && (answer.error() == SUCCESS) && (!_json_iter->is_single_token())) { return TRAILING_CONTENT; } + return answer; +} + +simdjson_inline simdjson_result value_iterator::get_root_number_type(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("number"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto answer = numberparsing::get_number_type(tmpbuf); + if (check_trailing && (answer.error() == SUCCESS) && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + return answer; +} +simdjson_inline simdjson_result value_iterator::get_root_number(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("number"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + number num; + error_code error = numberparsing::parse_number(tmpbuf, num); + if(error) { return error; } + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("number"); + return num; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_string(bool check_trailing, bool allow_replacement) noexcept { + return get_root_raw_json_string(check_trailing).unescape(json_iter(), allow_replacement); +} +template +simdjson_warn_unused simdjson_inline error_code value_iterator::get_root_string(string_type& receiver, bool check_trailing, bool allow_replacement) noexcept { + std::string_view content; + auto err = get_root_string(check_trailing, allow_replacement).get(content); + if (err) { return err; } + receiver = content; + return SUCCESS; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_wobbly_string(bool check_trailing) noexcept { + return get_root_raw_json_string(check_trailing).unescape_wobbly(json_iter()); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_raw_json_string(bool check_trailing) noexcept { + auto json = peek_scalar("string"); + if (*json != '"') { return incorrect_type_error("Not a string"); } + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_scalar("string"); + return raw_json_string(json+1); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_uint64(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("uint64"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_unsigned(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("uint64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_uint64_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("uint64"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_unsigned_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("uint64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_int64(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("int64"); + uint8_t tmpbuf[20+1+1]; // -<19 digits> is the longest possible integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + + auto result = numberparsing::parse_integer(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("int64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_int64_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("int64"); + uint8_t tmpbuf[20+1+1]; // -<19 digits> is the longest possible integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + + auto result = numberparsing::parse_integer_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("int64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_double(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("double"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; // +1 for null termination. + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_double(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("double"); + } + return result; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_double_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("double"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; // +1 for null termination. + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_double_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("double"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_bool(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("bool"); + uint8_t tmpbuf[5+1+1]; // +1 for null termination + tmpbuf[5+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 5+1)) { return incorrect_type_error("Not a boolean"); } + auto result = parse_bool(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("bool"); + } + return result; +} +simdjson_inline simdjson_result value_iterator::is_root_null(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("null"); + bool result = (max_len >= 4 && !atomparsing::str4ncmp(json, "null") && + (max_len == 4 || jsoncharutils::is_structural_or_whitespace(json[4]))); + if(result) { // we have something that looks like a null. + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("null"); + } + return result; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::skip_child() noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth >= _depth ); + + return _json_iter->skip_child(depth()); +} + +simdjson_inline value_iterator value_iterator::child() const noexcept { + assert_at_child(); + return { _json_iter, depth()+1, _json_iter->token.position() }; +} + +// GCC 7 warns when the first line of this function is inlined away into oblivion due to the caller +// relating depth and iterator depth, which is a desired effect. It does not happen if is_open is +// marked non-inline. +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline bool value_iterator::is_open() const noexcept { + return _json_iter->depth() >= depth(); +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline bool value_iterator::at_end() const noexcept { + return _json_iter->at_end(); +} + +simdjson_inline bool value_iterator::at_start() const noexcept { + return _json_iter->token.position() == start_position(); +} + +simdjson_inline bool value_iterator::at_first_field() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + return _json_iter->token.position() == start_position() + 1; +} + +simdjson_inline void value_iterator::abandon() noexcept { + _json_iter->abandon(); +} + +simdjson_warn_unused simdjson_inline depth_t value_iterator::depth() const noexcept { + return _depth; +} +simdjson_warn_unused simdjson_inline error_code value_iterator::error() const noexcept { + return _json_iter->error; +} +simdjson_warn_unused simdjson_inline uint8_t *&value_iterator::string_buf_loc() noexcept { + return _json_iter->string_buf_loc(); +} +simdjson_warn_unused simdjson_inline const json_iterator &value_iterator::json_iter() const noexcept { + return *_json_iter; +} +simdjson_warn_unused simdjson_inline json_iterator &value_iterator::json_iter() noexcept { + return *_json_iter; +} + +simdjson_inline const uint8_t *value_iterator::peek_start() const noexcept { + return _json_iter->peek(start_position()); +} +simdjson_inline uint32_t value_iterator::peek_start_length() const noexcept { + return _json_iter->peek_length(start_position()); +} + +simdjson_inline const uint8_t *value_iterator::peek_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + if (!is_at_start()) { return peek_start(); } + + // Get the JSON and advance the cursor, decreasing depth to signify that we have retrieved the value. + assert_at_start(); + return _json_iter->peek(); +} + +simdjson_inline void value_iterator::advance_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + if (!is_at_start()) { return; } + + // Get the JSON and advance the cursor, decreasing depth to signify that we have retrieved the value. + assert_at_start(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} + +simdjson_inline error_code value_iterator::start_container(uint8_t start_char, const char *incorrect_type_message, const char *type) noexcept { + logger::log_start_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + const uint8_t *json; + if (!is_at_start()) { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + json = peek_start(); + if (*json != start_char) { return incorrect_type_error(incorrect_type_message); } + } else { + assert_at_start(); + /** + * We should be prudent. Let us peek. If it is not the right type, we + * return an error. Only once we have determined that we have the right + * type are we allowed to advance! + */ + json = _json_iter->peek(); + if (*json != start_char) { return incorrect_type_error(incorrect_type_message); } + _json_iter->return_current_and_advance(); + } + + + return SUCCESS; +} + + +simdjson_inline const uint8_t *value_iterator::peek_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return peek_start(); } + + assert_at_root(); + return _json_iter->peek(); +} +simdjson_inline const uint8_t *value_iterator::peek_non_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return peek_start(); } + + assert_at_non_root_start(); + return _json_iter->peek(); +} + +simdjson_inline void value_iterator::advance_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return; } + + assert_at_root(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} +simdjson_inline void value_iterator::advance_non_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return; } + + assert_at_non_root_start(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} + +simdjson_inline error_code value_iterator::incorrect_type_error(const char *message) const noexcept { + logger::log_error(*_json_iter, start_position(), depth(), message); + return INCORRECT_TYPE; +} + +simdjson_inline bool value_iterator::is_at_start() const noexcept { + return position() == start_position(); +} + +simdjson_inline bool value_iterator::is_at_key() const noexcept { + // Keys are at the same depth as the object. + // Note here that we could be safer and check that we are within an object, + // but we do not. + return _depth == _json_iter->_depth && *_json_iter->peek() == '"'; +} + +simdjson_inline bool value_iterator::is_at_iterator_start() const noexcept { + // We can legitimately be either at the first value ([1]), or after the array if it's empty ([]). + auto delta = position() - start_position(); + return delta == 1 || delta == 2; +} + +inline void value_iterator::assert_at_start() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position == _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_container_start() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position == _start_position + 1 ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_next() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +simdjson_inline void value_iterator::move_at_start() noexcept { + _json_iter->_depth = _depth; + _json_iter->token.set_position(_start_position); +} + +simdjson_inline void value_iterator::move_at_container_start() noexcept { + _json_iter->_depth = _depth; + _json_iter->token.set_position(_start_position + 1); +} + +simdjson_inline simdjson_result value_iterator::reset_array() noexcept { + if(error()) { return error(); } + move_at_container_start(); + return started_array(); +} + +simdjson_inline simdjson_result value_iterator::reset_object() noexcept { + if(error()) { return error(); } + move_at_container_start(); + return started_object(); +} + +inline void value_iterator::assert_at_child() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth + 1 ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_root() const noexcept { + assert_at_start(); + SIMDJSON_ASSUME( _depth == 1 ); +} + +inline void value_iterator::assert_at_non_root_start() const noexcept { + assert_at_start(); + SIMDJSON_ASSUME( _depth > 1 ); +} + +inline void value_iterator::assert_is_valid() const noexcept { + SIMDJSON_ASSUME( _json_iter != nullptr ); +} + +simdjson_inline bool value_iterator::is_valid() const noexcept { + return _json_iter != nullptr; +} + +simdjson_inline simdjson_result value_iterator::type() const noexcept { + switch (*peek_start()) { + case '{': + return json_type::object; + case '[': + return json_type::array; + case '"': + return json_type::string; + case 'n': + return json_type::null; + case 't': case 'f': + return json_type::boolean; + case '-': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return json_type::number; + default: + return TAPE_ERROR; + } +} + +simdjson_inline token_position value_iterator::start_position() const noexcept { + return _start_position; +} + +simdjson_inline token_position value_iterator::position() const noexcept { + return _json_iter->position(); +} + +simdjson_inline token_position value_iterator::end_position() const noexcept { + return _json_iter->end_position(); +} + +simdjson_inline token_position value_iterator::last_position() const noexcept { + return _json_iter->last_position(); +} + +simdjson_inline error_code value_iterator::report_error(error_code error, const char *message) noexcept { + return _json_iter->report_error(error, message); +} + +} // namespace ondemand +} // namespace ppc64 +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(ppc64::ondemand::value_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/value_iterator-inl.h for ppc64 */ +/* end file simdjson/generic/ondemand/amalgamated.h for ppc64 */ +/* including simdjson/ppc64/end.h: #include "simdjson/ppc64/end.h" */ +/* begin file simdjson/ppc64/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/ppc64/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#undef SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT +/* undefining SIMDJSON_IMPLEMENTATION from "ppc64" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/ppc64/end.h */ + +#endif // SIMDJSON_PPC64_ONDEMAND_H +/* end file simdjson/ppc64/ondemand.h */ +#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(westmere) +/* including simdjson/westmere/ondemand.h: #include "simdjson/westmere/ondemand.h" */ +/* begin file simdjson/westmere/ondemand.h */ +#ifndef SIMDJSON_WESTMERE_ONDEMAND_H +#define SIMDJSON_WESTMERE_ONDEMAND_H + +/* including simdjson/westmere/begin.h: #include "simdjson/westmere/begin.h" */ +/* begin file simdjson/westmere/begin.h */ +/* defining SIMDJSON_IMPLEMENTATION to "westmere" */ +#define SIMDJSON_IMPLEMENTATION westmere +/* including simdjson/westmere/base.h: #include "simdjson/westmere/base.h" */ +/* begin file simdjson/westmere/base.h */ +#ifndef SIMDJSON_WESTMERE_BASE_H +#define SIMDJSON_WESTMERE_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_WESTMERE +namespace simdjson { +/** + * Implementation for Westmere (Intel SSE4.2). + */ +namespace westmere { + +class implementation; + +namespace { +namespace simd { + +template struct simd8; +template struct simd8x64; + +} // namespace simd +} // unnamed namespace + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BASE_H +/* end file simdjson/westmere/base.h */ +/* including simdjson/westmere/intrinsics.h: #include "simdjson/westmere/intrinsics.h" */ +/* begin file simdjson/westmere/intrinsics.h */ +#ifndef SIMDJSON_WESTMERE_INTRINSICS_H +#define SIMDJSON_WESTMERE_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + */ +#include // for _mm_alignr_epi8 +#include // for _mm_clmulepi64_si128 +#endif + +static_assert(sizeof(__m128i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for westmere"); + +#endif // SIMDJSON_WESTMERE_INTRINSICS_H +/* end file simdjson/westmere/intrinsics.h */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_WESTMERE +SIMDJSON_TARGET_REGION("sse4.2,pclmul,popcnt") +#endif + +/* including simdjson/westmere/bitmanipulation.h: #include "simdjson/westmere/bitmanipulation.h" */ +/* begin file simdjson/westmere/bitmanipulation.h */ +#ifndef SIMDJSON_WESTMERE_BITMANIPULATION_H +#define SIMDJSON_WESTMERE_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num-1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// SIMDJSON_REGULAR_VISUAL_STUDIO +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BITMANIPULATION_H +/* end file simdjson/westmere/bitmanipulation.h */ +/* including simdjson/westmere/bitmask.h: #include "simdjson/westmere/bitmask.h" */ +/* begin file simdjson/westmere/bitmask.h */ +#ifndef SIMDJSON_WESTMERE_BITMASK_H +#define SIMDJSON_WESTMERE_BITMASK_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { + +// +// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered. +// +// For example, prefix_xor(00100100) == 00011100 +// +simdjson_inline uint64_t prefix_xor(const uint64_t bitmask) { + // There should be no such thing with a processing supporting avx2 + // but not clmul. + __m128i all_ones = _mm_set1_epi8('\xFF'); + __m128i result = _mm_clmulepi64_si128(_mm_set_epi64x(0ULL, bitmask), all_ones, 0); + return _mm_cvtsi128_si64(result); +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BITMASK_H +/* end file simdjson/westmere/bitmask.h */ +/* including simdjson/westmere/numberparsing_defs.h: #include "simdjson/westmere/numberparsing_defs.h" */ +/* begin file simdjson/westmere/numberparsing_defs.h */ +#ifndef SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H +#define SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H + +/* including simdjson/westmere/base.h: #include "simdjson/westmere/base.h" */ +/* begin file simdjson/westmere/base.h */ +#ifndef SIMDJSON_WESTMERE_BASE_H +#define SIMDJSON_WESTMERE_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +// The constructor may be executed on any host, so we take care not to use SIMDJSON_TARGET_WESTMERE +namespace simdjson { +/** + * Implementation for Westmere (Intel SSE4.2). + */ +namespace westmere { + +class implementation; + +namespace { +namespace simd { + +template struct simd8; +template struct simd8x64; + +} // namespace simd +} // unnamed namespace + +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BASE_H +/* end file simdjson/westmere/base.h */ +/* including simdjson/westmere/intrinsics.h: #include "simdjson/westmere/intrinsics.h" */ +/* begin file simdjson/westmere/intrinsics.h */ +#ifndef SIMDJSON_WESTMERE_INTRINSICS_H +#define SIMDJSON_WESTMERE_INTRINSICS_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if SIMDJSON_VISUAL_STUDIO +// under clang within visual studio, this will include +#include // visual studio or clang +#else +#include // elsewhere +#endif // SIMDJSON_VISUAL_STUDIO + + +#if SIMDJSON_CLANG_VISUAL_STUDIO +/** + * You are not supposed, normally, to include these + * headers directly. Instead you should either include intrin.h + * or x86intrin.h. However, when compiling with clang + * under Windows (i.e., when _MSC_VER is set), these headers + * only get included *if* the corresponding features are detected + * from macros: + */ +#include // for _mm_alignr_epi8 +#include // for _mm_clmulepi64_si128 +#endif + +static_assert(sizeof(__m128i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for westmere"); + +#endif // SIMDJSON_WESTMERE_INTRINSICS_H +/* end file simdjson/westmere/intrinsics.h */ + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/numberparsing_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace numberparsing { + +/** @private */ +static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) { + // this actually computes *16* values so we are being wasteful. + const __m128i ascii0 = _mm_set1_epi8('0'); + const __m128i mul_1_10 = + _mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1); + const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1); + const __m128i mul_1_10000 = + _mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1); + const __m128i input = _mm_sub_epi8( + _mm_loadu_si128(reinterpret_cast(chars)), ascii0); + const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10); + const __m128i t2 = _mm_madd_epi16(t1, mul_1_100); + const __m128i t3 = _mm_packus_epi32(t2, t2); + const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000); + return _mm_cvtsi128_si32( + t4); // only captures the sum of the first 8 digits, drop the rest +} + +/** @private */ +simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) { + internal::value128 answer; +#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS +#ifdef _M_ARM64 + // ARM64 has native support for 64-bit multiplications, no need to emultate + answer.high = __umulh(value1, value2); + answer.low = value1 * value2; +#else + answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 +#endif // _M_ARM64 +#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS + __uint128_t r = (static_cast<__uint128_t>(value1)) * value2; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#endif + return answer; +} + +} // namespace numberparsing +} // namespace westmere +} // namespace simdjson + +#define SIMDJSON_SWAR_NUMBER_PARSING 1 + +#endif // SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H +/* end file simdjson/westmere/numberparsing_defs.h */ +/* including simdjson/westmere/simd.h: #include "simdjson/westmere/simd.h" */ +/* begin file simdjson/westmere/simd.h */ +#ifndef SIMDJSON_WESTMERE_SIMD_H +#define SIMDJSON_WESTMERE_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace simd { + + template + struct base { + __m128i value; + + // Zero constructor + simdjson_inline base() : value{__m128i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m128i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m128i&() const { return this->value; } + simdjson_inline operator __m128i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm_or_si128(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm_and_si128(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm_xor_si128(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm_andnot_si128(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + template> + struct base8: base> { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m128i _value) : base>(_value) {} + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return _mm_cmpeq_epi8(lhs, rhs); } + + static const int SIZE = sizeof(base>::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return _mm_alignr_epi8(*this, prev_chunk, 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m128i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { return _mm_movemask_epi8(*this); } + simdjson_inline bool any() const { return !_mm_testz_si128(*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm_setzero_si128(); } + static simdjson_inline simd8 load(const T values[16]) { + return _mm_loadu_si128(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m128i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[16]) const { return _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), *this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 16 - count_ones(mask) bytes of the result are significant but 16 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + __m128i shufmask = _mm_set_epi64x(thintable_epi8[mask2], thintable_epi8[mask1]); + // we increment by 0x08 the second half of the mask + shufmask = + _mm_add_epi8(shufmask, _mm_set_epi32(0x08080808, 0x08080808, 0, 0)); + // this is the version "nearly pruned" + __m128i pruned = _mm_shuffle_epi8(*this, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + __m128i compactmask = + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop1 * 8)); + __m128i answer = _mm_shuffle_epi8(pruned, compactmask); + _mm_storeu_si128(reinterpret_cast<__m128i *>(output), answer); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epi8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return _mm_cmpgt_epi8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm_cmpgt_epi8(other, *this); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epu8(*this, other); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline simd8 operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline simd8 operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return *this == uint8_t(0); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + simdjson_inline bool is_ascii() const { return _mm_movemask_epi8(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { return _mm_testz_si128(*this, *this); } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return _mm_testz_si128(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline int get_bit() const { return _mm_movemask_epi8(_mm_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, "Westmere kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, const simd8 chunk2, const simd8 chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+16), simd8::load(ptr+32), simd8::load(ptr+48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + this->chunks[2].store(ptr+sizeof(simd8)*2); + this->chunks[3].store(ptr+sizeof(simd8)*3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | (this->chunks[2] | this->chunks[3]); + } + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + this->chunks[0].compress(uint16_t(mask), output); + this->chunks[1].compress(uint16_t(mask >> 16), output + 16 - count_ones(mask & 0xFFFF)); + this->chunks[2].compress(uint16_t(mask >> 32), output + 32 - count_ones(mask & 0xFFFFFFFF)); + this->chunks[3].compress(uint16_t(mask >> 48), output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); + return 64 - count_ones(mask); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r0 = uint32_t(this->chunks[0].to_bitmask() ); + uint64_t r1 = this->chunks[1].to_bitmask() ; + uint64_t r2 = this->chunks[2].to_bitmask() ; + uint64_t r3 = this->chunks[3].to_bitmask() ; + return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask, + this->chunks[2] == mask, + this->chunks[3] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64( + this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1], + this->chunks[2] == other.chunks[2], + this->chunks[3] == other.chunks[3] + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask, + this->chunks[2] <= mask, + this->chunks[3] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_SIMD_INPUT_H +/* end file simdjson/westmere/simd.h */ +/* including simdjson/westmere/stringparsing_defs.h: #include "simdjson/westmere/stringparsing_defs.h" */ +/* begin file simdjson/westmere/stringparsing_defs.h */ +#ifndef SIMDJSON_WESTMERE_STRINGPARSING_DEFS_H +#define SIMDJSON_WESTMERE_STRINGPARSING_DEFS_H + +/* including simdjson/westmere/bitmanipulation.h: #include "simdjson/westmere/bitmanipulation.h" */ +/* begin file simdjson/westmere/bitmanipulation.h */ +#ifndef SIMDJSON_WESTMERE_BITMANIPULATION_H +#define SIMDJSON_WESTMERE_BITMANIPULATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/intrinsics.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { + +// We sometimes call trailing_zero on inputs that are zero, +// but the algorithms do not end up using the returned value. +// Sadly, sanitizers are not smart enough to figure it out. +SIMDJSON_NO_SANITIZE_UNDEFINED +// This function can be used safely even if not all bytes have been +// initialized. +// See issue https://github.com/simdjson/simdjson/issues/1965 +SIMDJSON_NO_SANITIZE_MEMORY +simdjson_inline int trailing_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long ret; + // Search the mask data from least significant bit (LSB) + // to the most significant bit (MSB) for a set bit (1). + _BitScanForward64(&ret, input_num); + return (int)ret; +#else // SIMDJSON_REGULAR_VISUAL_STUDIO + return __builtin_ctzll(input_num); +#endif // SIMDJSON_REGULAR_VISUAL_STUDIO +} + +/* result might be undefined when input_num is zero */ +simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { + return input_num & (input_num-1); +} + +/* result might be undefined when input_num is zero */ +simdjson_inline int leading_zeroes(uint64_t input_num) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + if (_BitScanReverse64(&leading_zero, input_num)) + return (int)(63 - leading_zero); + else + return 64; +#else + return __builtin_clzll(input_num); +#endif// SIMDJSON_REGULAR_VISUAL_STUDIO +} + +#if SIMDJSON_REGULAR_VISUAL_STUDIO +simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { + // note: we do not support legacy 32-bit Windows in this kernel + return __popcnt64(input_num);// Visual Studio wants two underscores +} +#else +simdjson_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif + +simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, + uint64_t *result) { +#if SIMDJSON_REGULAR_VISUAL_STUDIO + return _addcarry_u64(0, value1, value2, + reinterpret_cast(result)); +#else + return __builtin_uaddll_overflow(value1, value2, + reinterpret_cast(result)); +#endif +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_BITMANIPULATION_H +/* end file simdjson/westmere/bitmanipulation.h */ +/* including simdjson/westmere/simd.h: #include "simdjson/westmere/simd.h" */ +/* begin file simdjson/westmere/simd.h */ +#ifndef SIMDJSON_WESTMERE_SIMD_H +#define SIMDJSON_WESTMERE_SIMD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/bitmanipulation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/simdprune_tables.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace { +namespace simd { + + template + struct base { + __m128i value; + + // Zero constructor + simdjson_inline base() : value{__m128i()} {} + + // Conversion from SIMD register + simdjson_inline base(const __m128i _value) : value(_value) {} + + // Conversion to SIMD register + simdjson_inline operator const __m128i&() const { return this->value; } + simdjson_inline operator __m128i&() { return this->value; } + + // Bit operations + simdjson_inline Child operator|(const Child other) const { return _mm_or_si128(*this, other); } + simdjson_inline Child operator&(const Child other) const { return _mm_and_si128(*this, other); } + simdjson_inline Child operator^(const Child other) const { return _mm_xor_si128(*this, other); } + simdjson_inline Child bit_andnot(const Child other) const { return _mm_andnot_si128(other, *this); } + simdjson_inline Child& operator|=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast | other; return *this_cast; } + simdjson_inline Child& operator&=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast & other; return *this_cast; } + simdjson_inline Child& operator^=(const Child other) { auto this_cast = static_cast(this); *this_cast = *this_cast ^ other; return *this_cast; } + }; + + template> + struct base8: base> { + typedef uint16_t bitmask_t; + typedef uint32_t bitmask2_t; + + simdjson_inline base8() : base>() {} + simdjson_inline base8(const __m128i _value) : base>(_value) {} + + friend simdjson_inline Mask operator==(const simd8 lhs, const simd8 rhs) { return _mm_cmpeq_epi8(lhs, rhs); } + + static const int SIZE = sizeof(base>::value); + + template + simdjson_inline simd8 prev(const simd8 prev_chunk) const { + return _mm_alignr_epi8(*this, prev_chunk, 16 - N); + } + }; + + // SIMD byte mask type (returned by things like eq and gt) + template<> + struct simd8: base8 { + static simdjson_inline simd8 splat(bool _value) { return _mm_set1_epi8(uint8_t(-(!!_value))); } + + simdjson_inline simd8() : base8() {} + simdjson_inline simd8(const __m128i _value) : base8(_value) {} + // Splat constructor + simdjson_inline simd8(bool _value) : base8(splat(_value)) {} + + simdjson_inline int to_bitmask() const { return _mm_movemask_epi8(*this); } + simdjson_inline bool any() const { return !_mm_testz_si128(*this, *this); } + simdjson_inline simd8 operator~() const { return *this ^ true; } + }; + + template + struct base8_numeric: base8 { + static simdjson_inline simd8 splat(T _value) { return _mm_set1_epi8(_value); } + static simdjson_inline simd8 zero() { return _mm_setzero_si128(); } + static simdjson_inline simd8 load(const T values[16]) { + return _mm_loadu_si128(reinterpret_cast(values)); + } + // Repeat 16 values as many times as necessary (usually for lookup tables) + static simdjson_inline simd8 repeat_16( + T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, + T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + simdjson_inline base8_numeric() : base8() {} + simdjson_inline base8_numeric(const __m128i _value) : base8(_value) {} + + // Store to array + simdjson_inline void store(T dst[16]) const { return _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), *this); } + + // Override to distinguish from bool version + simdjson_inline simd8 operator~() const { return *this ^ 0xFFu; } + + // Addition/subtraction are the same for signed and unsigned + simdjson_inline simd8 operator+(const simd8 other) const { return _mm_add_epi8(*this, other); } + simdjson_inline simd8 operator-(const simd8 other) const { return _mm_sub_epi8(*this, other); } + simdjson_inline simd8& operator+=(const simd8 other) { *this = *this + other; return *static_cast*>(this); } + simdjson_inline simd8& operator-=(const simd8 other) { *this = *this - other; return *static_cast*>(this); } + + // Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values) + template + simdjson_inline simd8 lookup_16(simd8 lookup_table) const { + return _mm_shuffle_epi8(lookup_table, *this); + } + + // Copies to 'output" all bytes corresponding to a 0 in the mask (interpreted as a bitset). + // Passing a 0 value for mask would be equivalent to writing out every byte to output. + // Only the first 16 - count_ones(mask) bytes of the result are significant but 16 bytes + // get written. + // Design consideration: it seems like a function with the + // signature simd8 compress(uint32_t mask) would be + // sensible, but the AVX ISA makes this kind of approach difficult. + template + simdjson_inline void compress(uint16_t mask, L * output) const { + using internal::thintable_epi8; + using internal::BitsSetTable256mul2; + using internal::pshufb_combine_table; + // this particular implementation was inspired by work done by @animetosho + // we do it in two steps, first 8 bytes and then second 8 bytes + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits + // next line just loads the 64-bit values thintable_epi8[mask1] and + // thintable_epi8[mask2] into a 128-bit register, using only + // two instructions on most compilers. + __m128i shufmask = _mm_set_epi64x(thintable_epi8[mask2], thintable_epi8[mask1]); + // we increment by 0x08 the second half of the mask + shufmask = + _mm_add_epi8(shufmask, _mm_set_epi32(0x08080808, 0x08080808, 0, 0)); + // this is the version "nearly pruned" + __m128i pruned = _mm_shuffle_epi8(*this, shufmask); + // we still need to put the two halves together. + // we compute the popcount of the first half: + int pop1 = BitsSetTable256mul2[mask1]; + // then load the corresponding mask, what it does is to write + // only the first pop1 bytes from the first 8 bytes, and then + // it fills in with the bytes from the second 8 bytes + some filling + // at the end. + __m128i compactmask = + _mm_loadu_si128(reinterpret_cast(pshufb_combine_table + pop1 * 8)); + __m128i answer = _mm_shuffle_epi8(pruned, compactmask); + _mm_storeu_si128(reinterpret_cast<__m128i *>(output), answer); + } + + template + simdjson_inline simd8 lookup_16( + L replace0, L replace1, L replace2, L replace3, + L replace4, L replace5, L replace6, L replace7, + L replace8, L replace9, L replace10, L replace11, + L replace12, L replace13, L replace14, L replace15) const { + return lookup_16(simd8::repeat_16( + replace0, replace1, replace2, replace3, + replace4, replace5, replace6, replace7, + replace8, replace9, replace10, replace11, + replace12, replace13, replace14, replace15 + )); + } + }; + + // Signed bytes + template<> + struct simd8 : base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(int8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const int8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7, + int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Order-sensitive comparisons + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epi8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epi8(*this, other); } + simdjson_inline simd8 operator>(const simd8 other) const { return _mm_cmpgt_epi8(*this, other); } + simdjson_inline simd8 operator<(const simd8 other) const { return _mm_cmpgt_epi8(other, *this); } + }; + + // Unsigned bytes + template<> + struct simd8: base8_numeric { + simdjson_inline simd8() : base8_numeric() {} + simdjson_inline simd8(const __m128i _value) : base8_numeric(_value) {} + // Splat constructor + simdjson_inline simd8(uint8_t _value) : simd8(splat(_value)) {} + // Array constructor + simdjson_inline simd8(const uint8_t* values) : simd8(load(values)) {} + // Member-by-member initialization + simdjson_inline simd8( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) : simd8(_mm_setr_epi8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + )) {} + // Repeat 16 values as many times as necessary (usually for lookup tables) + simdjson_inline static simd8 repeat_16( + uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7, + uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15 + ) { + return simd8( + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10,v11,v12,v13,v14,v15 + ); + } + + // Saturated math + simdjson_inline simd8 saturating_add(const simd8 other) const { return _mm_adds_epu8(*this, other); } + simdjson_inline simd8 saturating_sub(const simd8 other) const { return _mm_subs_epu8(*this, other); } + + // Order-specific operations + simdjson_inline simd8 max_val(const simd8 other) const { return _mm_max_epu8(*this, other); } + simdjson_inline simd8 min_val(const simd8 other) const { return _mm_min_epu8(*this, other); } + // Same as >, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 gt_bits(const simd8 other) const { return this->saturating_sub(other); } + // Same as <, but only guarantees true is nonzero (< guarantees true = -1) + simdjson_inline simd8 lt_bits(const simd8 other) const { return other.saturating_sub(*this); } + simdjson_inline simd8 operator<=(const simd8 other) const { return other.max_val(*this) == other; } + simdjson_inline simd8 operator>=(const simd8 other) const { return other.min_val(*this) == other; } + simdjson_inline simd8 operator>(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + simdjson_inline simd8 operator<(const simd8 other) const { return this->gt_bits(other).any_bits_set(); } + + // Bit-specific operations + simdjson_inline simd8 bits_not_set() const { return *this == uint8_t(0); } + simdjson_inline simd8 bits_not_set(simd8 bits) const { return (*this & bits).bits_not_set(); } + simdjson_inline simd8 any_bits_set() const { return ~this->bits_not_set(); } + simdjson_inline simd8 any_bits_set(simd8 bits) const { return ~this->bits_not_set(bits); } + simdjson_inline bool is_ascii() const { return _mm_movemask_epi8(*this) == 0; } + simdjson_inline bool bits_not_set_anywhere() const { return _mm_testz_si128(*this, *this); } + simdjson_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); } + simdjson_inline bool bits_not_set_anywhere(simd8 bits) const { return _mm_testz_si128(*this, bits); } + simdjson_inline bool any_bits_set_anywhere(simd8 bits) const { return !bits_not_set_anywhere(bits); } + template + simdjson_inline simd8 shr() const { return simd8(_mm_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); } + template + simdjson_inline simd8 shl() const { return simd8(_mm_slli_epi16(*this, N)) & uint8_t(0xFFu << N); } + // Get one of the bits and make a bitmask out of it. + // e.g. value.get_bit<7>() gets the high bit + template + simdjson_inline int get_bit() const { return _mm_movemask_epi8(_mm_slli_epi16(*this, 7-N)); } + }; + + template + struct simd8x64 { + static constexpr int NUM_CHUNKS = 64 / sizeof(simd8); + static_assert(NUM_CHUNKS == 4, "Westmere kernel should use four registers per 64-byte block."); + const simd8 chunks[NUM_CHUNKS]; + + simd8x64(const simd8x64& o) = delete; // no copy allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed + simd8x64() = delete; // no default constructor allowed + + simdjson_inline simd8x64(const simd8 chunk0, const simd8 chunk1, const simd8 chunk2, const simd8 chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {} + simdjson_inline simd8x64(const T ptr[64]) : chunks{simd8::load(ptr), simd8::load(ptr+16), simd8::load(ptr+32), simd8::load(ptr+48)} {} + + simdjson_inline void store(T ptr[64]) const { + this->chunks[0].store(ptr+sizeof(simd8)*0); + this->chunks[1].store(ptr+sizeof(simd8)*1); + this->chunks[2].store(ptr+sizeof(simd8)*2); + this->chunks[3].store(ptr+sizeof(simd8)*3); + } + + simdjson_inline simd8 reduce_or() const { + return (this->chunks[0] | this->chunks[1]) | (this->chunks[2] | this->chunks[3]); + } + + simdjson_inline uint64_t compress(uint64_t mask, T * output) const { + this->chunks[0].compress(uint16_t(mask), output); + this->chunks[1].compress(uint16_t(mask >> 16), output + 16 - count_ones(mask & 0xFFFF)); + this->chunks[2].compress(uint16_t(mask >> 32), output + 32 - count_ones(mask & 0xFFFFFFFF)); + this->chunks[3].compress(uint16_t(mask >> 48), output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); + return 64 - count_ones(mask); + } + + simdjson_inline uint64_t to_bitmask() const { + uint64_t r0 = uint32_t(this->chunks[0].to_bitmask() ); + uint64_t r1 = this->chunks[1].to_bitmask() ; + uint64_t r2 = this->chunks[2].to_bitmask() ; + uint64_t r3 = this->chunks[3].to_bitmask() ; + return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48); + } + + simdjson_inline uint64_t eq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] == mask, + this->chunks[1] == mask, + this->chunks[2] == mask, + this->chunks[3] == mask + ).to_bitmask(); + } + + simdjson_inline uint64_t eq(const simd8x64 &other) const { + return simd8x64( + this->chunks[0] == other.chunks[0], + this->chunks[1] == other.chunks[1], + this->chunks[2] == other.chunks[2], + this->chunks[3] == other.chunks[3] + ).to_bitmask(); + } + + simdjson_inline uint64_t lteq(const T m) const { + const simd8 mask = simd8::splat(m); + return simd8x64( + this->chunks[0] <= mask, + this->chunks[1] <= mask, + this->chunks[2] <= mask, + this->chunks[3] <= mask + ).to_bitmask(); + } + }; // struct simd8x64 + +} // namespace simd +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_SIMD_INPUT_H +/* end file simdjson/westmere/simd.h */ + +namespace simdjson { +namespace westmere { +namespace { + +using namespace simd; + +// Holds backslashes and quotes locations. +struct backslash_and_quote { +public: + static constexpr uint32_t BYTES_PROCESSED = 32; + simdjson_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst); + + simdjson_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; } + simdjson_inline bool has_backslash() { return bs_bits != 0; } + simdjson_inline int quote_index() { return trailing_zeroes(quote_bits); } + simdjson_inline int backslash_index() { return trailing_zeroes(bs_bits); } + + uint32_t bs_bits; + uint32_t quote_bits; +}; // struct backslash_and_quote + +simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { + // this can read up to 31 bytes beyond the buffer size, but we require + // SIMDJSON_PADDING of padding + static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes"); + simd8 v0(src); + simd8 v1(src + 16); + v0.store(dst); + v1.store(dst + 16); + uint64_t bs_and_quote = simd8x64(v0 == '\\', v1 == '\\', v0 == '"', v1 == '"').to_bitmask(); + return { + uint32_t(bs_and_quote), // bs_bits + uint32_t(bs_and_quote >> 32) // quote_bits + }; +} + +} // unnamed namespace +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_WESTMERE_STRINGPARSING_DEFS_H +/* end file simdjson/westmere/stringparsing_defs.h */ +/* end file simdjson/westmere/begin.h */ +/* including simdjson/generic/ondemand/amalgamated.h for westmere: #include "simdjson/generic/ondemand/amalgamated.h" */ +/* begin file simdjson/generic/ondemand/amalgamated.h for westmere */ +#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H) +#error simdjson/generic/ondemand/dependencies.h must be included before simdjson/generic/ondemand/amalgamated.h! +#endif + +// Stuff other things depend on +/* including simdjson/generic/ondemand/base.h for westmere: #include "simdjson/generic/ondemand/base.h" */ +/* begin file simdjson/generic/ondemand/base.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_BASE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_BASE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +/** + * A fast, simple, DOM-like interface that parses JSON as you use it. + * + * Designed for maximum speed and a lower memory profile. + */ +namespace ondemand { + +/** Represents the depth of a JSON value (number of nested arrays/objects). */ +using depth_t = int32_t; + +/** @copydoc simdjson::westmere::number_type */ +using number_type = simdjson::westmere::number_type; + +/** @private Position in the JSON buffer indexes */ +using token_position = const uint32_t *; + +class array; +class array_iterator; +class document; +class document_reference; +class document_stream; +class field; +class json_iterator; +enum class json_type; +struct number; +class object; +class object_iterator; +class parser; +class raw_json_string; +class token_iterator; +class value; +class value_iterator; + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_BASE_H +/* end file simdjson/generic/ondemand/base.h for westmere */ +/* including simdjson/generic/ondemand/value_iterator.h for westmere: #include "simdjson/generic/ondemand/value_iterator.h" */ +/* begin file simdjson/generic/ondemand/value_iterator.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +/** + * Iterates through a single JSON value at a particular depth. + * + * Does not keep track of the type of value: provides methods for objects, arrays and scalars and expects + * the caller to call the right ones. + * + * @private This is not intended for external use. + */ +class value_iterator { +protected: + /** The underlying JSON iterator */ + json_iterator *_json_iter{}; + /** The depth of this value */ + depth_t _depth{}; + /** + * The starting token index for this value + */ + token_position _start_position{}; + +public: + simdjson_inline value_iterator() noexcept = default; + + /** + * Denote that we're starting a document. + */ + simdjson_inline void start_document() noexcept; + + /** + * Skips a non-iterated or partially-iterated JSON value, whether it is a scalar, array or object. + * + * Optimized for scalars. + */ + simdjson_warn_unused simdjson_inline error_code skip_child() noexcept; + + /** + * Tell whether the iterator is at the EOF mark + */ + simdjson_inline bool at_end() const noexcept; + + /** + * Tell whether the iterator is at the start of the value + */ + simdjson_inline bool at_start() const noexcept; + + /** + * Tell whether the value is open--if the value has not been used, or the array/object is still open. + */ + simdjson_inline bool is_open() const noexcept; + + /** + * Tell whether the value is at an object's first field (just after the {). + */ + simdjson_inline bool at_first_field() const noexcept; + + /** + * Abandon all iteration. + */ + simdjson_inline void abandon() noexcept; + + /** + * Get the child value as a value_iterator. + */ + simdjson_inline value_iterator child_value() const noexcept; + + /** + * Get the depth of this value. + */ + simdjson_inline int32_t depth() const noexcept; + + /** + * Get the JSON type of this value. + * + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() const noexcept; + + /** + * @addtogroup object Object iteration + * + * Methods to iterate and find object fields. These methods generally *assume* the value is + * actually an object; the caller is responsible for keeping track of that fact. + * + * @{ + */ + + /** + * Start an object iteration. + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCORRECT_TYPE if there is no opening { + */ + simdjson_warn_unused simdjson_inline simdjson_result start_object() noexcept; + /** + * Start an object iteration from the root. + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCORRECT_TYPE if there is no opening { + * @error TAPE_ERROR if there is no matching } at end of document + */ + simdjson_warn_unused simdjson_inline simdjson_result start_root_object() noexcept; + /** + * Checks whether an object could be started from the root. May be called by start_root_object. + * + * @returns SUCCESS if it is possible to safely start an object from the root (document level). + * @error INCORRECT_TYPE if there is no opening { + * @error TAPE_ERROR if there is no matching } at end of document + */ + simdjson_warn_unused simdjson_inline error_code check_root_object() noexcept; + /** + * Start an object iteration after the user has already checked and moved past the {. + * + * Does not move the iterator unless the object is empty ({}). + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_object() noexcept; + /** + * Start an object iteration from the root, after the user has already checked and moved past the {. + * + * Does not move the iterator unless the object is empty ({}). + * + * @returns Whether the object had any fields (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_root_object() noexcept; + + /** + * Moves to the next field in an object. + * + * Looks for , and }. If } is found, the object is finished and the iterator advances past it. + * Otherwise, it advances to the next value. + * + * @return whether there is another field in the object. + * @error TAPE_ERROR If there is a comma missing between fields. + * @error TAPE_ERROR If there is a comma, but not enough tokens remaining to have a key, :, and value. + */ + simdjson_warn_unused simdjson_inline simdjson_result has_next_field() noexcept; + + /** + * Get the current field's key. + */ + simdjson_warn_unused simdjson_inline simdjson_result field_key() noexcept; + + /** + * Pass the : in the field and move to its value. + */ + simdjson_warn_unused simdjson_inline error_code field_value() noexcept; + + /** + * Find the next field with the given key. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline error_code find_field(const std::string_view key) noexcept; + + /** + * Find the next field with the given key, *without* unescaping. This assumes object order: it + * will not find the field if it was already passed when looking for some *other* field. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline simdjson_result find_field_raw(const std::string_view key) noexcept; + + /** + * Find the field with the given key without regard to order, and *without* unescaping. + * + * This is an unordered object lookup: if the field is not found initially, it will cycle around and scan from the beginning. + * + * Assumes you have called next_field() or otherwise matched the previous value. + * + * This means the iterator must be sitting at the next key: + * + * ``` + * { "a": 1, "b": 2 } + * ^ + * ``` + * + * Key is *raw JSON,* meaning it will be matched against the verbatim JSON without attempting to + * unescape it. This works well for typical ASCII and UTF-8 keys (almost all of them), but may + * fail to match some keys with escapes (\u, \n, etc.). + */ + simdjson_warn_unused simdjson_inline simdjson_result find_field_unordered_raw(const std::string_view key) noexcept; + + /** @} */ + + /** + * @addtogroup array Array iteration + * Methods to iterate over array elements. These methods generally *assume* the value is actually + * an object; the caller is responsible for keeping track of that fact. + * @{ + */ + + /** + * Check for an opening [ and start an array iteration. + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCORRECT_TYPE If there is no [. + */ + simdjson_warn_unused simdjson_inline simdjson_result start_array() noexcept; + /** + * Check for an opening [ and start an array iteration while at the root. + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCORRECT_TYPE If there is no [. + * @error TAPE_ERROR if there is no matching ] at end of document + */ + simdjson_warn_unused simdjson_inline simdjson_result start_root_array() noexcept; + /** + * Checks whether an array could be started from the root. May be called by start_root_array. + * + * @returns SUCCESS if it is possible to safely start an array from the root (document level). + * @error INCORRECT_TYPE If there is no [. + * @error TAPE_ERROR if there is no matching ] at end of document + */ + simdjson_warn_unused simdjson_inline error_code check_root_array() noexcept; + /** + * Start an array iteration, after the user has already checked and moved past the [. + * + * Does not move the iterator unless the array is empty ([]). + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_array() noexcept; + /** + * Start an array iteration from the root, after the user has already checked and moved past the [. + * + * Does not move the iterator unless the array is empty ([]). + * + * @returns Whether the array had any elements (returns false for empty). + * @error INCOMPLETE_ARRAY_OR_OBJECT If there are no more tokens (implying the *parent* + * array or object is incomplete). + */ + simdjson_warn_unused simdjson_inline simdjson_result started_root_array() noexcept; + + /** + * Moves to the next element in an array. + * + * Looks for , and ]. If ] is found, the array is finished and the iterator advances past it. + * Otherwise, it advances to the next value. + * + * @return Whether there is another element in the array. + * @error TAPE_ERROR If there is a comma missing between elements. + */ + simdjson_warn_unused simdjson_inline simdjson_result has_next_element() noexcept; + + /** + * Get a child value iterator. + */ + simdjson_warn_unused simdjson_inline value_iterator child() const noexcept; + + /** @} */ + + /** + * @defgroup scalar Scalar values + * @addtogroup scalar + * @{ + */ + + simdjson_warn_unused simdjson_inline simdjson_result get_string(bool allow_replacement) noexcept; + template + simdjson_warn_unused simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_int64() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_double() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_bool() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_null() noexcept; + simdjson_warn_unused simdjson_inline bool is_negative() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_integer() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + simdjson_warn_unused simdjson_inline simdjson_result get_root_string(bool check_trailing, bool allow_replacement) noexcept; + template + simdjson_warn_unused simdjson_inline error_code get_root_string(string_type& receiver, bool check_trailing, bool allow_replacement) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_wobbly_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_raw_json_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_uint64(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_uint64_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_int64(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_int64_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_double(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_double_in_string(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_bool(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline bool is_root_negative() noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_root_integer(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_number_type(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result get_root_number(bool check_trailing) noexcept; + simdjson_warn_unused simdjson_inline simdjson_result is_root_null(bool check_trailing) noexcept; + + simdjson_inline error_code error() const noexcept; + simdjson_inline uint8_t *&string_buf_loc() noexcept; + simdjson_inline const json_iterator &json_iter() const noexcept; + simdjson_inline json_iterator &json_iter() noexcept; + + simdjson_inline void assert_is_valid() const noexcept; + simdjson_inline bool is_valid() const noexcept; + + /** @} */ +protected: + /** + * Restarts an array iteration. + * @returns Whether the array has any elements (returns false for empty). + */ + simdjson_inline simdjson_result reset_array() noexcept; + /** + * Restarts an object iteration. + * @returns Whether the object has any fields (returns false for empty). + */ + simdjson_inline simdjson_result reset_object() noexcept; + /** + * move_at_start(): moves us so that we are pointing at the beginning of + * the container. It updates the index so that at_start() is true and it + * syncs the depth. The user can then create a new container instance. + * + * Usage: used with value::count_elements(). + **/ + simdjson_inline void move_at_start() noexcept; + + /** + * move_at_container_start(): moves us so that we are pointing at the beginning of + * the container so that assert_at_container_start() passes. + * + * Usage: used with reset_array() and reset_object(). + **/ + simdjson_inline void move_at_container_start() noexcept; + /* Useful for debugging and logging purposes. */ + inline std::string to_string() const noexcept; + simdjson_inline value_iterator(json_iterator *json_iter, depth_t depth, token_position start_index) noexcept; + + simdjson_inline simdjson_result parse_null(const uint8_t *json) const noexcept; + simdjson_inline simdjson_result parse_bool(const uint8_t *json) const noexcept; + simdjson_inline const uint8_t *peek_start() const noexcept; + simdjson_inline uint32_t peek_start_length() const noexcept; + + /** + * The general idea of the advance_... methods and the peek_* methods + * is that you first peek and check that you have desired type. If you do, + * and only if you do, then you advance. + * + * We used to unconditionally advance. But this made reasoning about our + * current state difficult. + * Suppose you always advance. Look at the 'value' matching the key + * "shadowable" in the following example... + * + * ({"globals":{"a":{"shadowable":[}}}}) + * + * If the user thinks it is a Boolean and asks for it, then we check the '[', + * decide it is not a Boolean, but still move into the next character ('}'). Now + * we are left pointing at '}' right after a '['. And we have not yet reported + * an error, only that we do not have a Boolean. + * + * If, instead, you just stand your ground until it is content that you know, then + * you will only even move beyond the '[' if the user tells you that you have an + * array. So you will be at the '}' character inside the array and, hopefully, you + * will then catch the error because an array cannot start with '}', but the code + * processing Boolean values does not know this. + * + * So the contract is: first call 'peek_...' and then call 'advance_...' only + * if you have determined that it is a type you can handle. + * + * Unfortunately, it makes the code more verbose, longer and maybe more error prone. + */ + + simdjson_inline void advance_scalar(const char *type) noexcept; + simdjson_inline void advance_root_scalar(const char *type) noexcept; + simdjson_inline void advance_non_root_scalar(const char *type) noexcept; + + simdjson_inline const uint8_t *peek_scalar(const char *type) noexcept; + simdjson_inline const uint8_t *peek_root_scalar(const char *type) noexcept; + simdjson_inline const uint8_t *peek_non_root_scalar(const char *type) noexcept; + + + simdjson_inline error_code start_container(uint8_t start_char, const char *incorrect_type_message, const char *type) noexcept; + simdjson_inline error_code end_container() noexcept; + + /** + * Advance to a place expecting a value (increasing depth). + * + * @return The current token (the one left behind). + * @error TAPE_ERROR If the document ended early. + */ + simdjson_inline simdjson_result advance_to_value() noexcept; + + simdjson_inline error_code incorrect_type_error(const char *message) const noexcept; + simdjson_inline error_code error_unless_more_tokens(uint32_t tokens=1) const noexcept; + + simdjson_inline bool is_at_start() const noexcept; + /** + * is_at_iterator_start() returns true on an array or object after it has just been + * created, whether the instance is empty or not. + * + * Usage: used by array::begin() in debug mode (SIMDJSON_DEVELOPMENT_CHECKS) + */ + simdjson_inline bool is_at_iterator_start() const noexcept; + + /** + * Assuming that we are within an object, this returns true if we + * are pointing at a key. + * + * Usage: the skip_child() method should never be used while we are pointing + * at a key inside an object. + */ + simdjson_inline bool is_at_key() const noexcept; + + inline void assert_at_start() const noexcept; + inline void assert_at_container_start() const noexcept; + inline void assert_at_root() const noexcept; + inline void assert_at_child() const noexcept; + inline void assert_at_next() const noexcept; + inline void assert_at_non_root_start() const noexcept; + + /** Get the starting position of this value */ + simdjson_inline token_position start_position() const noexcept; + + /** @copydoc error_code json_iterator::position() const noexcept; */ + simdjson_inline token_position position() const noexcept; + /** @copydoc error_code json_iterator::end_position() const noexcept; */ + simdjson_inline token_position last_position() const noexcept; + /** @copydoc error_code json_iterator::end_position() const noexcept; */ + simdjson_inline token_position end_position() const noexcept; + /** @copydoc error_code json_iterator::report_error(error_code error, const char *message) noexcept; */ + simdjson_inline error_code report_error(error_code error, const char *message) noexcept; + + friend class document; + friend class object; + friend class array; + friend class value; +}; // value_iterator + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::value_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_H +/* end file simdjson/generic/ondemand/value_iterator.h for westmere */ +/* including simdjson/generic/ondemand/value.h for westmere: #include "simdjson/generic/ondemand/value.h" */ +/* begin file simdjson/generic/ondemand/value.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +/** + * An ephemeral JSON value returned during iteration. It is only valid for as long as you do + * not access more data in the JSON document. + */ +class value { +public: + /** + * Create a new invalid value. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline value() noexcept = default; + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * You may use get_double(), get_bool(), get_uint64(), get_int64(), + * get_object(), get_array(), get_raw_json_string(), or get_string() instead. + * + * @returns A value of the given type, parsed from the JSON. + * @returns INCORRECT_TYPE If the JSON value is not the given type. + */ + template simdjson_inline simdjson_result get() noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * @param out This is set to a value of the given type, parsed from the JSON. If there is an error, this may not be initialized. + * @returns INCORRECT_TYPE If the JSON value is not an object. + * @returns SUCCESS If the parse succeeded and the out parameter was set to the value. + */ + template simdjson_inline error_code get(T &out) noexcept; + + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result get_array() noexcept; + + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @returns INCORRECT_TYPE If the JSON value is not an object. + */ + simdjson_inline simdjson_result get_object() noexcept; + + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A unsigned 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64() noexcept; + + /** + * Cast this JSON value (inside string) to a unsigned integer. + * + * @returns A unsigned 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64() noexcept; + + /** + * Cast this JSON value (inside string) to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64_in_string() noexcept; + + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double() noexcept; + + /** + * Cast this JSON value (inside string) to a double + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double_in_string() noexcept; + + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Equivalent to get(). + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + + /** + * Attempts to fill the provided std::string reference with the parsed value of the current string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory. + * We recommend you avoid allocating an std::string unless you need to. + * + * @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS. + */ + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + + /** + * Cast this JSON value to a "wobbly" string. + * + * The string is may not be a valid UTF-8 string. + * See https://simonsapin.github.io/wtf-8/ + * + * Important: a value should be consumed once. Calling get_wobbly_string() twice on the same value + * is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_wobbly_string() noexcept; + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_raw_json_string() noexcept; + + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @returns INCORRECT_TYPE if the JSON value is not true or false. + */ + simdjson_inline simdjson_result get_bool() noexcept; + + /** + * Checks if this JSON value is null. If and only if the value is + * null, then it is consumed (we advance). If we find a token that + * begins with 'n' but is not 'null', then an error is returned. + * + * @returns Whether the value is null. + * @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'. + */ + simdjson_inline simdjson_result is_null() noexcept; + +#if SIMDJSON_EXCEPTIONS + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an array. + */ + simdjson_inline operator array() noexcept(false); + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an object. + */ + simdjson_inline operator object() noexcept(false); + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline operator uint64_t() noexcept(false); + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer. + */ + simdjson_inline operator int64_t() noexcept(false); + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number. + */ + simdjson_inline operator double() noexcept(false); + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Equivalent to get(). + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator std::string_view() noexcept(false); + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator raw_json_string() noexcept(false); + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false. + */ + simdjson_inline operator bool() noexcept(false); +#endif + + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + * + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result begin() & noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() & noexcept; + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * Performance hint: You should only call count_elements() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method on the object instance. + * + * Performance hint: You should only call count_fields() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Get the value at the given index in the array. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) noexcept; + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) noexcept; + + /** + * Get the type of this JSON value. It does not validate or consume the value. + * E.g., you must still call "is_null()" to check that a value is null even if + * "type()" returns json_type::null. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + * + * @return The type of JSON value (json_type::array, json_type::object, json_type::string, + * json_type::number, json_type::boolean, or json_type::null). + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() noexcept; + + /** + * Checks whether the value is a scalar (string, number, null, Boolean). + * Returns false when there it is an array or object. + * + * @returns true if the type is string, number, null, Boolean + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result is_scalar() noexcept; + + /** + * Checks whether the value is a negative number. + * + * @returns true if the number if negative. + */ + simdjson_inline bool is_negative() noexcept; + /** + * Checks whether the value is an integer number. Note that + * this requires to partially parse the number string. If + * the value is determined to be an integer, it may still + * not parse properly as an integer in subsequent steps + * (e.g., it might overflow). + * + * Performance note: if you call this function systematically + * before parsing a number, you may have fallen for a performance + * anti-pattern. + * + * @returns true if the number if negative. + */ + simdjson_inline simdjson_result is_integer() noexcept; + /** + * Determine the number type (integer or floating-point number) as quickly + * as possible. This function does not fully validate the input. It is + * useful when you only need to classify the numbers, without parsing them. + * + * If you are planning to retrieve the value or you need full validation, + * consider using the get_number() method instead: it will fully parse + * and validate the input, and give you access to the type: + * get_number().get_number_type(). + * + * get_number_type() is number_type::unsigned_integer if we have + * an integer greater or equal to 9223372036854775808 + * get_number_type() is number_type::signed_integer if we have an + * integer that is less than 9223372036854775808 + * Otherwise, get_number_type() has value number_type::floating_point_number + * + * This function requires processing the number string, but it is expected + * to be faster than get_number().get_number_type() because it is does not + * parse the number value. + * + * @returns the type of the number + */ + simdjson_inline simdjson_result get_number_type() noexcept; + + /** + * Attempt to parse an ondemand::number. An ondemand::number may + * contain an integer value or a floating-point value, the simdjson + * library will autodetect the type. Thus it is a dynamically typed + * number. Before accessing the value, you must determine the detected + * type. + * + * number.get_number_type() is number_type::signed_integer if we have + * an integer in [-9223372036854775808,9223372036854775808) + * You can recover the value by calling number.get_int64() and you + * have that number.is_int64() is true. + * + * number.get_number_type() is number_type::unsigned_integer if we have + * an integer in [9223372036854775808,18446744073709551616) + * You can recover the value by calling number.get_uint64() and you + * have that number.is_uint64() is true. + * + * Otherwise, number.get_number_type() has value number_type::floating_point_number + * and we have a binary64 number. + * You can recover the value by calling number.get_double() and you + * have that number.is_double() is true. + * + * You must check the type before accessing the value: it is an error + * to call "get_int64()" when number.get_number_type() is not + * number_type::signed_integer and when number.is_int64() is false. + * + * Performance note: this is designed with performance in mind. When + * calling 'get_number()', you scan the number string only once, determining + * efficiently the type and storing it in an efficient manner. + */ + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + + /** + * Get the raw JSON for this token. + * + * The string_view will always point into the input buffer. + * + * The string_view will start at the beginning of the token, and include the entire token + * *as well as all spaces until the next token (or EOF).* This means, for example, that a + * string token always begins with a " and is always terminated by the final ", possibly + * followed by a number of spaces. + * + * The string_view is *not* null-terminated. However, if this is a scalar (string, number, + * boolean, or null), the character after the end of the string_view is guaranteed to be + * a non-space token. + * + * Tokens include: + * - { + * - [ + * - "a string (possibly with UTF-8 or backslashed characters like \\\")". + * - -1.2e-100 + * - true + * - false + * - null + * + * See also value::raw_json(). + */ + simdjson_inline std::string_view raw_json_token() noexcept; + + /** + * Get a string_view pointing at this value in the JSON document. + * If this element is an array or an object, it consumes the array or the object + * and returns a string_view instance corresponding to the + * array as represented in JSON. It points inside the original document. + * If this element is a scalar (string, number, Boolean, null), it returns what + * raw_json_token() would return. + */ + simdjson_inline simdjson_result raw_json() noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + simdjson_inline simdjson_result current_location() noexcept; + + /** + * Returns the current depth in the document if in bounds. + * + * E.g., + * 0 = finished with document + * 1 = document root value (could be [ or {, not yet known) + * 2 = , or } inside root array/object + * 3 = key or value inside root array/object. + */ + simdjson_inline int32_t current_depth() const noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. + * + * Calling at_pointer() on non-document instances (e.g., arrays and objects) is not + * standardized (by RFC 6901). We provide some experimental support for JSON pointers + * on non-document instances. Yet it is not the case when calling at_pointer on an array + * or an object instance: there is no rewind and no invalidation. + * + * You may only call at_pointer on an array after it has been created, but before it has + * been first accessed. When calling at_pointer on an array, the pointer is advanced to + * the location indicated by the JSON pointer (in case of success). It is no longer possible + * to call at_pointer on the same array. + * + * You may call at_pointer more than once on an object, but each time the pointer is advanced + * to be within the value matched by the key indicated by the JSON pointer query. Thus any preceding + * key (as well as the current key) can no longer be used with following JSON pointer calls. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + +protected: + /** + * Create a value. + */ + simdjson_inline value(const value_iterator &iter) noexcept; + + /** + * Skip this value, allowing iteration to continue. + */ + simdjson_inline void skip() noexcept; + + /** + * Start a value at the current position. + * + * (It should already be started; this is just a self-documentation method.) + */ + static simdjson_inline value start(const value_iterator &iter) noexcept; + + /** + * Resume a value. + */ + static simdjson_inline value resume(const value_iterator &iter) noexcept; + + /** + * Get the object, starting or resuming it as necessary + */ + simdjson_inline simdjson_result start_or_resume_object() noexcept; + + // simdjson_inline void log_value(const char *type) const noexcept; + // simdjson_inline void log_error(const char *message) const noexcept; + + value_iterator iter{}; + + friend class document; + friend class array_iterator; + friend class field; + friend class object; + friend struct simdjson_result; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::value &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result get_array() noexcept; + simdjson_inline simdjson_result get_object() noexcept; + + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + + template simdjson_inline simdjson_result get() noexcept; + + template simdjson_inline error_code get(T &out) noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator westmere::ondemand::array() noexcept(false); + simdjson_inline operator westmere::ondemand::object() noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator westmere::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) noexcept; + + /** + * Get the type of this JSON value. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + */ + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + + /** @copydoc simdjson_inline std::string_view value::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + + /** @copydoc simdjson_inline simdjson_result current_location() noexcept */ + simdjson_inline simdjson_result current_location() noexcept; + /** @copydoc simdjson_inline int32_t current_depth() const noexcept */ + simdjson_inline simdjson_result current_depth() const noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_H +/* end file simdjson/generic/ondemand/value.h for westmere */ +/* including simdjson/generic/ondemand/logger.h for westmere: #include "simdjson/generic/ondemand/logger.h" */ +/* begin file simdjson/generic/ondemand/logger.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_LOGGER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_LOGGER_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +// Logging should be free unless SIMDJSON_VERBOSE_LOGGING is set. Importantly, it is critical +// that the call to the log functions be side-effect free. Thus, for example, you should not +// create temporary std::string instances. +namespace logger { + +enum class log_level : int32_t { + info = 0, + error = 1 +}; + +#if SIMDJSON_VERBOSE_LOGGING + static constexpr const bool LOG_ENABLED = true; +#else + static constexpr const bool LOG_ENABLED = false; +#endif + +// We do not want these functions to be 'really inlined' since real inlining is +// for performance purposes and if you are using the loggers, you do not care about +// performance (or should not). +static inline void log_headers() noexcept; +// If args are provided, title will be treated as format string +template +static inline void log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +template +static inline void log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; +static inline void log_event(const json_iterator &iter, const char *type, std::string_view detail="", int delta=0, int depth_delta=0) noexcept; +static inline void log_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail="") noexcept; +static inline void log_value(const json_iterator &iter, const char *type, std::string_view detail="", int delta=-1, int depth_delta=0) noexcept; +static inline void log_start_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail="") noexcept; +static inline void log_start_value(const json_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_end_value(const json_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; + +static inline void log_error(const json_iterator &iter, token_position index, depth_t depth, const char *error, const char *detail="") noexcept; +static inline void log_error(const json_iterator &iter, const char *error, const char *detail="", int delta=-1, int depth_delta=0) noexcept; + +static inline void log_event(const value_iterator &iter, const char *type, std::string_view detail="", int delta=0, int depth_delta=0) noexcept; +static inline void log_value(const value_iterator &iter, const char *type, std::string_view detail="", int delta=-1, int depth_delta=0) noexcept; +static inline void log_start_value(const value_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_end_value(const value_iterator &iter, const char *type, int delta=-1, int depth_delta=0) noexcept; +static inline void log_error(const value_iterator &iter, const char *error, const char *detail="", int delta=-1, int depth_delta=0) noexcept; + +} // namespace logger +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_LOGGER_H +/* end file simdjson/generic/ondemand/logger.h for westmere */ +/* including simdjson/generic/ondemand/token_iterator.h for westmere: #include "simdjson/generic/ondemand/token_iterator.h" */ +/* begin file simdjson/generic/ondemand/token_iterator.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +/** + * Iterates through JSON tokens (`{` `}` `[` `]` `,` `:` `""` `123` `true` `false` `null`) + * detected by stage 1. + * + * @private This is not intended for external use. + */ +class token_iterator { +public: + /** + * Create a new invalid token_iterator. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline token_iterator() noexcept = default; + simdjson_inline token_iterator(token_iterator &&other) noexcept = default; + simdjson_inline token_iterator &operator=(token_iterator &&other) noexcept = default; + simdjson_inline token_iterator(const token_iterator &other) noexcept = default; + simdjson_inline token_iterator &operator=(const token_iterator &other) noexcept = default; + + /** + * Advance to the next token (returning the current one). + */ + simdjson_inline const uint8_t *return_current_and_advance() noexcept; + /** + * Reports the current offset in bytes from the start of the underlying buffer. + */ + simdjson_inline uint32_t current_offset() const noexcept; + /** + * Get the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(int32_t delta=0) const noexcept; + /** + * Get the maximum length of the JSON text for a given token. + * + * The length will include any whitespace at the end of the token. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_length(int32_t delta=0) const noexcept; + + /** + * Get the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token. + * + */ + simdjson_inline const uint8_t *peek(token_position position) const noexcept; + /** + * Get the maximum length of the JSON text for a given token. + * + * The length will include any whitespace at the end of the token. + * + * @param position The position of the token. + */ + simdjson_inline uint32_t peek_length(token_position position) const noexcept; + + /** + * Return the current index. + */ + simdjson_inline token_position position() const noexcept; + /** + * Reset to a previously saved index. + */ + simdjson_inline void set_position(token_position target_position) noexcept; + + // NOTE: we don't support a full C++ iterator interface, because we expect people to make + // different calls to advance the iterator based on *their own* state. + + simdjson_inline bool operator==(const token_iterator &other) const noexcept; + simdjson_inline bool operator!=(const token_iterator &other) const noexcept; + simdjson_inline bool operator>(const token_iterator &other) const noexcept; + simdjson_inline bool operator>=(const token_iterator &other) const noexcept; + simdjson_inline bool operator<(const token_iterator &other) const noexcept; + simdjson_inline bool operator<=(const token_iterator &other) const noexcept; + +protected: + simdjson_inline token_iterator(const uint8_t *buf, token_position position) noexcept; + + /** + * Get the index of the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = current token, + * 1 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_index(int32_t delta=0) const noexcept; + /** + * Get the index of the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token. + * + */ + simdjson_inline uint32_t peek_index(token_position position) const noexcept; + + const uint8_t *buf{}; + token_position _position{}; + + friend class json_iterator; + friend class value_iterator; + friend class object; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +}; + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::token_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H +/* end file simdjson/generic/ondemand/token_iterator.h for westmere */ +/* including simdjson/generic/ondemand/json_iterator.h for westmere: #include "simdjson/generic/ondemand/json_iterator.h" */ +/* begin file simdjson/generic/ondemand/json_iterator.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +/** + * Iterates through JSON tokens, keeping track of depth and string buffer. + * + * @private This is not intended for external use. + */ +class json_iterator { +protected: + token_iterator token{}; + ondemand::parser *parser{}; + /** + * Next free location in the string buffer. + * + * Used by raw_json_string::unescape() to have a place to unescape strings to. + */ + uint8_t *_string_buf_loc{}; + /** + * JSON error, if there is one. + * + * INCORRECT_TYPE and NO_SUCH_FIELD are *not* stored here, ever. + * + * PERF NOTE: we *hope* this will be elided into control flow, as it is only used (a) in the first + * iteration of the loop, or (b) for the final iteration after a missing comma is found in ++. If + * this is not elided, we should make sure it's at least not using up a register. Failing that, + * we should store it in document so there's only one of them. + */ + error_code error{SUCCESS}; + /** + * Depth of the current token in the JSON. + * + * - 0 = finished with document + * - 1 = document root value (could be [ or {, not yet known) + * - 2 = , or } inside root array/object + * - 3 = key or value inside root array/object. + */ + depth_t _depth{}; + /** + * Beginning of the document indexes. + * Normally we have root == parser->implementation->structural_indexes.get() + * but this may differ, especially in streaming mode (where we have several + * documents); + */ + token_position _root{}; + /** + * Normally, a json_iterator operates over a single document, but in + * some cases, we may have a stream of documents. This attribute is meant + * as meta-data: the json_iterator works the same irrespective of the + * value of this attribute. + */ + bool _streaming{false}; + +public: + simdjson_inline json_iterator() noexcept = default; + simdjson_inline json_iterator(json_iterator &&other) noexcept; + simdjson_inline json_iterator &operator=(json_iterator &&other) noexcept; + simdjson_inline explicit json_iterator(const json_iterator &other) noexcept = default; + simdjson_inline json_iterator &operator=(const json_iterator &other) noexcept = default; + /** + * Skips a JSON value, whether it is a scalar, array or object. + */ + simdjson_warn_unused simdjson_inline error_code skip_child(depth_t parent_depth) noexcept; + + /** + * Tell whether the iterator is still at the start + */ + simdjson_inline bool at_root() const noexcept; + + /** + * Tell whether we should be expected to run in streaming + * mode (iterating over many documents). It is pure metadata + * that does not affect how the iterator works. It is used by + * start_root_array() and start_root_object(). + */ + simdjson_inline bool streaming() const noexcept; + + /** + * Get the root value iterator + */ + simdjson_inline token_position root_position() const noexcept; + /** + * Assert that we are at the document depth (== 1) + */ + simdjson_inline void assert_at_document_depth() const noexcept; + /** + * Assert that we are at the root of the document + */ + simdjson_inline void assert_at_root() const noexcept; + + /** + * Tell whether the iterator is at the EOF mark + */ + simdjson_inline bool at_end() const noexcept; + + /** + * Tell whether the iterator is live (has not been moved). + */ + simdjson_inline bool is_alive() const noexcept; + + /** + * Abandon this iterator, setting depth to 0 (as if the document is finished). + */ + simdjson_inline void abandon() noexcept; + + /** + * Advance the current token without modifying depth. + */ + simdjson_inline const uint8_t *return_current_and_advance() noexcept; + + /** + * Returns true if there is a single token in the index (i.e., it is + * a JSON with a scalar value such as a single number). + * + * @return whether there is a single token + */ + simdjson_inline bool is_single_token() const noexcept; + + /** + * Assert that there are at least the given number of tokens left. + * + * Has no effect in release builds. + */ + simdjson_inline void assert_more_tokens(uint32_t required_tokens=1) const noexcept; + /** + * Assert that the given position addresses an actual token (is within bounds). + * + * Has no effect in release builds. + */ + simdjson_inline void assert_valid_position(token_position position) const noexcept; + /** + * Get the JSON text for a given token (relative). + * + * This is not null-terminated; it is a view into the JSON. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = next token, -1 = prev token. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(int32_t delta=0) const noexcept; + /** + * Get the maximum length of the JSON text for the current token (or relative). + * + * The length will include any whitespace at the end of the token. + * + * @param delta The relative position of the token to retrieve. e.g. 0 = next token, -1 = prev token. + */ + simdjson_inline uint32_t peek_length(int32_t delta=0) const noexcept; + /** + * Get a pointer to the current location in the input buffer. + * + * This is not null-terminated; it is a view into the JSON. + * + * You may be pointing outside of the input buffer: it is not generally + * safe to dereference this pointer. + */ + simdjson_inline const uint8_t *unsafe_pointer() const noexcept; + /** + * Get the JSON text for a given token. + * + * This is not null-terminated; it is a view into the JSON. + * + * @param position The position of the token to retrieve. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek(token_position position) const noexcept; + /** + * Get the maximum length of the JSON text for the current token (or relative). + * + * The length will include any whitespace at the end of the token. + * + * @param position The position of the token to retrieve. + */ + simdjson_inline uint32_t peek_length(token_position position) const noexcept; + /** + * Get the JSON text for the last token in the document. + * + * This is not null-terminated; it is a view into the JSON. + * + * TODO consider a string_view, assuming the length will get stripped out by the optimizer when + * it isn't used ... + */ + simdjson_inline const uint8_t *peek_last() const noexcept; + + /** + * Ascend one level. + * + * Validates that the depth - 1 == parent_depth. + * + * @param parent_depth the expected parent depth. + */ + simdjson_inline void ascend_to(depth_t parent_depth) noexcept; + + /** + * Descend one level. + * + * Validates that the new depth == child_depth. + * + * @param child_depth the expected child depth. + */ + simdjson_inline void descend_to(depth_t child_depth) noexcept; + simdjson_inline void descend_to(depth_t child_depth, int32_t delta) noexcept; + + /** + * Get current depth. + */ + simdjson_inline depth_t depth() const noexcept; + + /** + * Get current (writeable) location in the string buffer. + */ + simdjson_inline uint8_t *&string_buf_loc() noexcept; + + /** + * Report an unrecoverable error, preventing further iteration. + * + * @param error The error to report. Must not be SUCCESS, UNINITIALIZED, INCORRECT_TYPE, or NO_SUCH_FIELD. + * @param message An error message to report with the error. + */ + simdjson_inline error_code report_error(error_code error, const char *message) noexcept; + + /** + * Log error, but don't stop iteration. + * @param error The error to report. Must be INCORRECT_TYPE, or NO_SUCH_FIELD. + * @param message An error message to report with the error. + */ + simdjson_inline error_code optional_error(error_code error, const char *message) noexcept; + + /** + * Take an input in json containing max_len characters and attempt to copy it over to tmpbuf, a buffer with + * N bytes of capacity. It will return false if N is too small (smaller than max_len) of if it is zero. + * The buffer (tmpbuf) is padded with space characters. + */ + simdjson_warn_unused simdjson_inline bool copy_to_buffer(const uint8_t *json, uint32_t max_len, uint8_t *tmpbuf, size_t N) noexcept; + + simdjson_inline token_position position() const noexcept; + /** + * Write the raw_json_string to the string buffer and return a string_view. + * Each raw_json_string should be unescaped once, or else the string buffer might + * overflow. + */ + simdjson_inline simdjson_result unescape(raw_json_string in, bool allow_replacement) noexcept; + simdjson_inline simdjson_result unescape_wobbly(raw_json_string in) noexcept; + + simdjson_inline void reenter_child(token_position position, depth_t child_depth) noexcept; + + simdjson_inline error_code consume_character(char c) noexcept; +#if SIMDJSON_DEVELOPMENT_CHECKS + simdjson_inline token_position start_position(depth_t depth) const noexcept; + simdjson_inline void set_start_position(depth_t depth, token_position position) noexcept; +#endif + + /* Useful for debugging and logging purposes. */ + inline std::string to_string() const noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + inline simdjson_result current_location() const noexcept; + + /** + * Updates this json iterator so that it is back at the beginning of the document, + * as if it had just been created. + */ + inline void rewind() noexcept; + /** + * This checks whether the {,},[,] are balanced so that the document + * ends with proper zero depth. This requires scanning the whole document + * and it may be expensive. It is expected that it will be rarely called. + * It does not attempt to match { with } and [ with ]. + */ + inline bool balanced() const noexcept; +protected: + simdjson_inline json_iterator(const uint8_t *buf, ondemand::parser *parser) noexcept; + /// The last token before the end + simdjson_inline token_position last_position() const noexcept; + /// The token *at* the end. This points at gibberish and should only be used for comparison. + simdjson_inline token_position end_position() const noexcept; + /// The end of the buffer. + simdjson_inline token_position end() const noexcept; + + friend class document; + friend class document_stream; + friend class object; + friend class array; + friend class value; + friend class raw_json_string; + friend class parser; + friend class value_iterator; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, logger::log_level level, Args&&... args) noexcept; + template + friend simdjson_inline void logger::log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, logger::log_level level, Args&&... args) noexcept; +}; // json_iterator + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::json_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H +/* end file simdjson/generic/ondemand/json_iterator.h for westmere */ +/* including simdjson/generic/ondemand/json_type.h for westmere: #include "simdjson/generic/ondemand/json_type.h" */ +/* begin file simdjson/generic/ondemand/json_type.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/numberparsing.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +/** + * The type of a JSON value. + */ +enum class json_type { + // Start at 1 to catch uninitialized / default values more easily + array=1, ///< A JSON array ( [ 1, 2, 3 ... ] ) + object, ///< A JSON object ( { "a": 1, "b" 2, ... } ) + number, ///< A JSON number ( 1 or -2.3 or 4.5e6 ...) + string, ///< A JSON string ( "a" or "hello world\n" ...) + boolean, ///< A JSON boolean (true or false) + null ///< A JSON null (null) +}; + +/** + * A type representing a JSON number. + * The design of the struct is deliberately straight-forward. All + * functions return standard values with no error check. + */ +struct number { + + /** + * return the automatically determined type of + * the number: number_type::floating_point_number, + * number_type::signed_integer or number_type::unsigned_integer. + * + * enum class number_type { + * floating_point_number=1, /// a binary64 number + * signed_integer, /// a signed integer that fits in a 64-bit word using two's complement + * unsigned_integer /// a positive integer larger or equal to 1<<63 + * }; + */ + simdjson_inline ondemand::number_type get_number_type() const noexcept; + /** + * return true if the automatically determined type of + * the number is number_type::unsigned_integer. + */ + simdjson_inline bool is_uint64() const noexcept; + /** + * return the value as a uint64_t, only valid if is_uint64() is true. + */ + simdjson_inline uint64_t get_uint64() const noexcept; + simdjson_inline operator uint64_t() const noexcept; + + /** + * return true if the automatically determined type of + * the number is number_type::signed_integer. + */ + simdjson_inline bool is_int64() const noexcept; + /** + * return the value as a int64_t, only valid if is_int64() is true. + */ + simdjson_inline int64_t get_int64() const noexcept; + simdjson_inline operator int64_t() const noexcept; + + + /** + * return true if the automatically determined type of + * the number is number_type::floating_point_number. + */ + simdjson_inline bool is_double() const noexcept; + /** + * return the value as a double, only valid if is_double() is true. + */ + simdjson_inline double get_double() const noexcept; + simdjson_inline operator double() const noexcept; + + /** + * Convert the number to a double. Though it always succeed, the conversion + * may be lossy if the number cannot be represented exactly. + */ + simdjson_inline double as_double() const noexcept; + + +protected: + /** + * The next block of declaration is designed so that we can call the number parsing + * functions on a number type. They are protected and should never be used outside + * of the core simdjson library. + */ + friend class value_iterator; + template + friend error_code numberparsing::write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer); + template + friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer); + /** Store a signed 64-bit value to the number. */ + simdjson_inline void append_s64(int64_t value) noexcept; + /** Store an unsigned 64-bit value to the number. */ + simdjson_inline void append_u64(uint64_t value) noexcept; + /** Store a double value to the number. */ + simdjson_inline void append_double(double value) noexcept; + /** Specifies that the value is a double, but leave it undefined. */ + simdjson_inline void skip_double() noexcept; + /** + * End of friend declarations. + */ + + /** + * Our attributes are a union type (size = 64 bits) + * followed by a type indicator. + */ + union { + double floating_point_number; + int64_t signed_integer; + uint64_t unsigned_integer; + } payload{0}; + number_type type{number_type::signed_integer}; +}; + +/** + * Write the JSON type to the output stream + * + * @param out The output stream. + * @param type The json_type. + */ +inline std::ostream& operator<<(std::ostream& out, json_type type) noexcept; + +#if SIMDJSON_EXCEPTIONS +/** + * Send JSON type to an output stream. + * + * @param out The output stream. + * @param type The json_type. + * @throw simdjson_error if the result being printed has an error. If there is an error with the + * underlying output stream, that error will be propagated (simdjson_error will not be + * thrown). + */ +inline std::ostream& operator<<(std::ostream& out, simdjson_result &type) noexcept(false); +#endif + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::json_type &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H +/* end file simdjson/generic/ondemand/json_type.h for westmere */ +/* including simdjson/generic/ondemand/raw_json_string.h for westmere: #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* begin file simdjson/generic/ondemand/raw_json_string.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +/** + * A string escaped per JSON rules, terminated with quote ("). They are used to represent + * unescaped keys inside JSON documents. + * + * (In other words, a pointer to the beginning of a string, just after the start quote, inside a + * JSON file.) + * + * This class is deliberately simplistic and has little functionality. You can + * compare a raw_json_string instance with an unescaped C string, but + * that is nearly all you can do. + * + * The raw_json_string is unescaped. If you wish to write an unescaped version of it to your own + * buffer, you may do so using the parser.unescape(string, buff) method, using an ondemand::parser + * instance. Doing so requires you to have a sufficiently large buffer. + * + * The raw_json_string instances originate typically from field instance which in turn represent + * key-value pairs from object instances. From a field instance, you get the raw_json_string + * instance by calling key(). You can, if you want a more usable string_view instance, call + * the unescaped_key() method on the field instance. You may also create a raw_json_string from + * any other string value, with the value.get_raw_json_string() method. Again, you can get + * a more usable string_view instance by calling get_string(). + * + */ +class raw_json_string { +public: + /** + * Create a new invalid raw_json_string. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline raw_json_string() noexcept = default; + + /** + * Create a new invalid raw_json_string pointed at the given location in the JSON. + * + * The given location must be just *after* the beginning quote (") in the JSON file. + * + * It *must* be terminated by a ", and be a valid JSON string. + */ + simdjson_inline raw_json_string(const uint8_t * _buf) noexcept; + /** + * Get the raw pointer to the beginning of the string in the JSON (just after the "). + * + * It is possible for this function to return a null pointer if the instance + * has outlived its existence. + */ + simdjson_inline const char * raw() const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done) on target.size() characters, + * and if the raw_json_string instance has a quote character at byte index target.size(). + * We never read more than length + 1 bytes in the raw_json_string instance. + * If length is smaller than target.size(), this will return false. + * + * The std::string_view instance may contain any characters. However, the caller + * is responsible for setting length so that length bytes may be read in the + * raw_json_string. + * + * Performance: the comparison may be done using memcmp which may be efficient + * for long strings. + */ + simdjson_inline bool unsafe_is_equal(size_t length, std::string_view target) const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done). + * The std::string_view instance should not contain unescaped quote characters: + * the caller is responsible for this check. See is_free_from_unescaped_quote. + * + * Performance: the comparison is done byte-by-byte which might be inefficient for + * long strings. + * + * If target is a compile-time constant, and your compiler likes you, + * you should be able to do the following without performance penalty... + * + * static_assert(raw_json_string::is_free_from_unescaped_quote(target), ""); + * s.unsafe_is_equal(target); + */ + simdjson_inline bool unsafe_is_equal(std::string_view target) const noexcept; + + /** + * This compares the current instance to the C string target: returns true if + * they are byte-by-byte equal (no escaping is done). + * The provided C string should not contain an unescaped quote character: + * the caller is responsible for this check. See is_free_from_unescaped_quote. + * + * If target is a compile-time constant, and your compiler likes you, + * you should be able to do the following without performance penalty... + * + * static_assert(raw_json_string::is_free_from_unescaped_quote(target), ""); + * s.unsafe_is_equal(target); + */ + simdjson_inline bool unsafe_is_equal(const char* target) const noexcept; + + /** + * This compares the current instance to the std::string_view target: returns true if + * they are byte-by-byte equal (no escaping is done). + */ + simdjson_inline bool is_equal(std::string_view target) const noexcept; + + /** + * This compares the current instance to the C string target: returns true if + * they are byte-by-byte equal (no escaping is done). + */ + simdjson_inline bool is_equal(const char* target) const noexcept; + + /** + * Returns true if target is free from unescaped quote. If target is known at + * compile-time, we might expect the computation to happen at compile time with + * many compilers (not all!). + */ + static simdjson_inline bool is_free_from_unescaped_quote(std::string_view target) noexcept; + static simdjson_inline bool is_free_from_unescaped_quote(const char* target) noexcept; + +private: + + + /** + * This will set the inner pointer to zero, effectively making + * this instance unusable. + */ + simdjson_inline void consume() noexcept { buf = nullptr; } + + /** + * Checks whether the inner pointer is non-null and thus usable. + */ + simdjson_inline simdjson_warn_unused bool alive() const noexcept { return buf != nullptr; } + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. + * The result will be a valid UTF-8. + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid until the next parse() call on the parser. + * + * @param iter A json_iterator, which contains a buffer where the string will be written. + * @param allow_replacement Whether we allow replacement of invalid surrogate pairs. + */ + simdjson_inline simdjson_warn_unused simdjson_result unescape(json_iterator &iter, bool allow_replacement) const noexcept; + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. + * The result may not be a valid UTF-8. https://simonsapin.github.io/wtf-8/ + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid until the next parse() call on the parser. + * + * @param iter A json_iterator, which contains a buffer where the string will be written. + */ + simdjson_inline simdjson_warn_unused simdjson_result unescape_wobbly(json_iterator &iter) const noexcept; + const uint8_t * buf{}; + friend class object; + friend class field; + friend class parser; + friend struct simdjson_result; +}; + +simdjson_unused simdjson_inline std::ostream &operator<<(std::ostream &, const raw_json_string &) noexcept; + +/** + * Comparisons between raw_json_string and std::string_view instances are potentially unsafe: the user is responsible + * for providing a string with no unescaped quote. Note that unescaped quotes cannot be present in valid JSON strings. + */ +simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept; +simdjson_unused simdjson_inline bool operator==(std::string_view c, const raw_json_string &a) noexcept; +simdjson_unused simdjson_inline bool operator!=(const raw_json_string &a, std::string_view c) noexcept; +simdjson_unused simdjson_inline bool operator!=(std::string_view c, const raw_json_string &a) noexcept; + + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::raw_json_string &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline ~simdjson_result() noexcept = default; ///< @private + + simdjson_inline simdjson_result raw() const noexcept; + simdjson_inline simdjson_warn_unused simdjson_result unescape(westmere::ondemand::json_iterator &iter, bool allow_replacement) const noexcept; + simdjson_inline simdjson_warn_unused simdjson_result unescape_wobbly(westmere::ondemand::json_iterator &iter) const noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H +/* end file simdjson/generic/ondemand/raw_json_string.h for westmere */ +/* including simdjson/generic/ondemand/parser.h for westmere: #include "simdjson/generic/ondemand/parser.h" */ +/* begin file simdjson/generic/ondemand/parser.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_PARSER_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include + +namespace simdjson { +namespace westmere { +namespace ondemand { + +/** + * The default batch size for document_stream instances for this On Demand kernel. + * Note that different On Demand kernel may use a different DEFAULT_BATCH_SIZE value + * in the future. + */ +static constexpr size_t DEFAULT_BATCH_SIZE = 1000000; +/** + * Some adversary might try to set the batch size to 0 or 1, which might cause problems. + * We set a minimum of 32B since anything else is highly likely to be an error. In practice, + * most users will want a much larger batch size. + * + * All non-negative MINIMAL_BATCH_SIZE values should be 'safe' except that, obviously, no JSON + * document can ever span 0 or 1 byte and that very large values would create memory allocation issues. + */ +static constexpr size_t MINIMAL_BATCH_SIZE = 32; + +/** + * A JSON fragment iterator. + * + * This holds the actual iterator as well as the buffer for writing strings. + */ +class parser { +public: + /** + * Create a JSON parser. + * + * The new parser will have zero capacity. + */ + inline explicit parser(size_t max_capacity = SIMDJSON_MAXSIZE_BYTES) noexcept; + + inline parser(parser &&other) noexcept = default; + simdjson_inline parser(const parser &other) = delete; + simdjson_inline parser &operator=(const parser &other) = delete; + simdjson_inline parser &operator=(parser &&other) noexcept = default; + + /** Deallocate the JSON parser. */ + inline ~parser() noexcept = default; + + /** + * Start iterating an on-demand JSON document. + * + * ondemand::parser parser; + * document doc = parser.iterate(json); + * + * It is expected that the content is a valid UTF-8 file, containing a valid JSON document. + * Otherwise the iterate method may return an error. In particular, the whole input should be + * valid: we do not attempt to tolerate incorrect content either before or after a JSON + * document. If there is a UTF-8 BOM, the parser skips it. + * + * ### IMPORTANT: Validate what you use + * + * Calling iterate on an invalid JSON document may not immediately trigger an error. The call to + * iterate does not parse and validate the whole document. + * + * ### IMPORTANT: Buffer Lifetime + * + * Because parsing is done while you iterate, you *must* keep the JSON buffer around at least as + * long as the document iteration. + * + * ### IMPORTANT: Document Lifetime + * + * Only one iteration at a time can happen per parser, and the parser *must* be kept alive during + * iteration to ensure intermediate buffers can be accessed. Any document must be destroyed before + * you call parse() again or destroy the parser. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * @param json The JSON to parse. + * @param len The length of the JSON. + * @param capacity The number of bytes allocated in the JSON (must be at least len+SIMDJSON_PADDING). + * + * @return The document, or an error: + * - INSUFFICIENT_PADDING if the input has less than SIMDJSON_PADDING extra bytes. + * - MEMALLOC if realloc_if_needed the parser does not have enough capacity, and memory + * allocation fails. + * - EMPTY if the document is all whitespace. + * - UTF8_ERROR if the document is not valid UTF-8. + * - UNESCAPED_CHARS if a string contains control characters that must be escaped + * - UNCLOSED_STRING if there is an unclosed string in the document. + */ + simdjson_warn_unused simdjson_result iterate(padded_string_view json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const char *json, size_t len, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const uint8_t *json, size_t len, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(std::string_view json, size_t capacity) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const std::string &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(std::string &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const simdjson_result &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(const simdjson_result &json) & noexcept; + /** @overload simdjson_result iterate(padded_string_view json) & noexcept */ + simdjson_warn_unused simdjson_result iterate(padded_string &&json) & noexcept = delete; + + /** + * @private + * + * Start iterating an on-demand JSON document. + * + * ondemand::parser parser; + * json_iterator doc = parser.iterate(json); + * + * ### IMPORTANT: Buffer Lifetime + * + * Because parsing is done while you iterate, you *must* keep the JSON buffer around at least as + * long as the document iteration. + * + * ### IMPORTANT: Document Lifetime + * + * Only one iteration at a time can happen per parser, and the parser *must* be kept alive during + * iteration to ensure intermediate buffers can be accessed. Any document must be destroyed before + * you call parse() again or destroy the parser. + * + * The ondemand::document instance holds the iterator. The document must remain in scope + * while you are accessing instances of ondemand::value, ondemand::object, ondemand::array. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * @param json The JSON to parse. + * + * @return The iterator, or an error: + * - INSUFFICIENT_PADDING if the input has less than SIMDJSON_PADDING extra bytes. + * - MEMALLOC if realloc_if_needed the parser does not have enough capacity, and memory + * allocation fails. + * - EMPTY if the document is all whitespace. + * - UTF8_ERROR if the document is not valid UTF-8. + * - UNESCAPED_CHARS if a string contains control characters that must be escaped + * - UNCLOSED_STRING if there is an unclosed string in the document. + */ + simdjson_warn_unused simdjson_result iterate_raw(padded_string_view json) & noexcept; + + + /** + * Parse a buffer containing many JSON documents. + * + * auto json = R"({ "foo": 1 } { "foo": 2 } { "foo": 3 } )"_padded; + * ondemand::parser parser; + * ondemand::document_stream docs = parser.iterate_many(json); + * for (auto & doc : docs) { + * std::cout << doc["foo"] << std::endl; + * } + * // Prints 1 2 3 + * + * No copy of the input buffer is made. + * + * The function is lazy: it may be that no more than one JSON document at a time is parsed. + * + * The caller is responsabile to ensure that the input string data remains unchanged and is + * not deleted during the loop. + * + * ### Format + * + * The buffer must contain a series of one or more JSON documents, concatenated into a single + * buffer, separated by ASCII whitespace. It effectively parses until it has a fully valid document, + * then starts parsing the next document at that point. (It does this with more parallelism and + * lookahead than you might think, though.) + * + * documents that consist of an object or array may omit the whitespace between them, concatenating + * with no separator. Documents that consist of a single primitive (i.e. documents that are not + * arrays or objects) MUST be separated with ASCII whitespace. + * + * The characters inside a JSON document, and between JSON documents, must be valid Unicode (UTF-8). + * If there is a UTF-8 BOM, the parser skips it. + * + * The documents must not exceed batch_size bytes (by default 1MB) or they will fail to parse. + * Setting batch_size to excessively large or excessively small values may impact negatively the + * performance. + * + * ### REQUIRED: Buffer Padding + * + * The buffer must have at least SIMDJSON_PADDING extra allocated bytes. It does not matter what + * those bytes are initialized to, as long as they are allocated. These bytes will be read: if you + * using a sanitizer that verifies that no uninitialized byte is read, then you should initialize the + * SIMDJSON_PADDING bytes to avoid runtime warnings. + * + * ### Threads + * + * When compiled with SIMDJSON_THREADS_ENABLED, this method will use a single thread under the + * hood to do some lookahead. + * + * ### Parser Capacity + * + * If the parser's current capacity is less than batch_size, it will allocate enough capacity + * to handle it (up to max_capacity). + * + * @param buf The concatenated JSON to parse. + * @param len The length of the concatenated JSON. + * @param batch_size The batch size to use. MUST be larger than the largest document. The sweet + * spot is cache-related: small enough to fit in cache, yet big enough to + * parse as many documents as possible in one tight loop. + * Defaults to 10MB, which has been a reasonable sweet spot in our tests. + * @param allow_comma_separated (defaults on false) This allows a mode where the documents are + * separated by commas instead of whitespace. It comes with a performance + * penalty because the entire document is indexed at once (and the document must be + * less than 4 GB), and there is no multithreading. In this mode, the batch_size parameter + * is effectively ignored, as it is set to at least the document size. + * @return The stream, or an error. An empty input will yield 0 documents rather than an EMPTY error. Errors: + * - MEMALLOC if the parser does not have enough capacity and memory allocation fails + * - CAPACITY if the parser does not have enough capacity and batch_size > max_capacity. + * - other json errors if parsing fails. You should not rely on these errors to always the same for the + * same document: they may vary under runtime dispatch (so they may vary depending on your system and hardware). + */ + inline simdjson_result iterate_many(const uint8_t *buf, size_t len, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const char *buf, size_t len, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const std::string &s, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + inline simdjson_result iterate_many(const std::string &&s, size_t batch_size, bool allow_comma_separated = false) = delete;// unsafe + /** @overload parse_many(const uint8_t *buf, size_t len, size_t batch_size) */ + inline simdjson_result iterate_many(const padded_string &s, size_t batch_size = DEFAULT_BATCH_SIZE, bool allow_comma_separated = false) noexcept; + inline simdjson_result iterate_many(const padded_string &&s, size_t batch_size, bool allow_comma_separated = false) = delete;// unsafe + + /** @private We do not want to allow implicit conversion from C string to std::string. */ + simdjson_result iterate_many(const char *buf, size_t batch_size = DEFAULT_BATCH_SIZE) noexcept = delete; + + /** The capacity of this parser (the largest document it can process). */ + simdjson_inline size_t capacity() const noexcept; + /** The maximum capacity of this parser (the largest document it is allowed to process). */ + simdjson_inline size_t max_capacity() const noexcept; + simdjson_inline void set_max_capacity(size_t max_capacity) noexcept; + /** + * The maximum depth of this parser (the most deeply nested objects and arrays it can process). + * This parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true. + * The document's instance current_depth() method should be used to monitor the parsing + * depth and limit it if desired. + */ + simdjson_inline size_t max_depth() const noexcept; + + /** + * Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length + * and `max_depth` depth. + * + * The max_depth parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true. + * The document's instance current_depth() method should be used to monitor the parsing + * depth and limit it if desired. + * + * @param capacity The new capacity. + * @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH. + * @return The error, if there is one. + */ + simdjson_warn_unused error_code allocate(size_t capacity, size_t max_depth=DEFAULT_MAX_DEPTH) noexcept; + + #ifdef SIMDJSON_THREADS_ENABLED + /** + * The parser instance can use threads when they are available to speed up some + * operations. It is enabled by default. Changing this attribute will change the + * behavior of the parser for future operations. + */ + bool threaded{true}; + #endif + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. to a user-provided buffer. + * The result must be valid UTF-8. + * The provided pointer is advanced to the end of the string by reference, and a string_view instance + * is returned. You can ensure that your buffer is large enough by allocating a block of memory at least + * as large as the input JSON plus SIMDJSON_PADDING and then unescape all strings to this one buffer. + * + * This unescape function is a low-level function. If you want a more user-friendly approach, you should + * avoid raw_json_string instances (e.g., by calling unescaped_key() instead of key() or get_string() + * instead of get_raw_json_string()). + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid as long as the bytes in dst. + * + * @param raw_json_string input + * @param dst A pointer to a buffer at least large enough to write this string as well as + * an additional SIMDJSON_PADDING bytes. + * @param allow_replacement Whether we allow a replacement if the input string contains unmatched surrogate pairs. + * @return A string_view pointing at the unescaped string in dst + * @error STRING_ERROR if escapes are incorrect. + */ + simdjson_inline simdjson_result unescape(raw_json_string in, uint8_t *&dst, bool allow_replacement = false) const noexcept; + + /** + * Unescape this JSON string, replacing \\ with \, \n with newline, etc. to a user-provided buffer. + * The result may not be valid UTF-8. See https://simonsapin.github.io/wtf-8/ + * The provided pointer is advanced to the end of the string by reference, and a string_view instance + * is returned. You can ensure that your buffer is large enough by allocating a block of memory at least + * as large as the input JSON plus SIMDJSON_PADDING and then unescape all strings to this one buffer. + * + * This unescape function is a low-level function. If you want a more user-friendly approach, you should + * avoid raw_json_string instances (e.g., by calling unescaped_key() instead of key() or get_string() + * instead of get_raw_json_string()). + * + * ## IMPORTANT: string_view lifetime + * + * The string_view is only valid as long as the bytes in dst. + * + * @param raw_json_string input + * @param dst A pointer to a buffer at least large enough to write this string as well as + * an additional SIMDJSON_PADDING bytes. + * @return A string_view pointing at the unescaped string in dst + * @error STRING_ERROR if escapes are incorrect. + */ + simdjson_inline simdjson_result unescape_wobbly(raw_json_string in, uint8_t *&dst) const noexcept; + +private: + /** @private [for benchmarking access] The implementation to use */ + std::unique_ptr implementation{}; + size_t _capacity{0}; + size_t _max_capacity; + size_t _max_depth{DEFAULT_MAX_DEPTH}; + std::unique_ptr string_buf{}; +#if SIMDJSON_DEVELOPMENT_CHECKS + std::unique_ptr start_positions{}; +#endif + + friend class json_iterator; + friend class document_stream; +}; + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::parser &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_PARSER_H +/* end file simdjson/generic/ondemand/parser.h for westmere */ + +// All other declarations +/* including simdjson/generic/ondemand/array.h for westmere: #include "simdjson/generic/ondemand/array.h" */ +/* begin file simdjson/generic/ondemand/array.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +/** + * A forward-only JSON array. + */ +class array { +public: + /** + * Create a new invalid array. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline array() noexcept = default; + + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result begin() noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() noexcept; + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an array is empty, it is more performant to use + * the is_empty() method. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the beginning of the array and checks whether the + * array is empty. + * The runtime complexity is constant time. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + simdjson_inline simdjson_result is_empty() & noexcept; + /** + * Reset the iterator so that we are pointing back at the + * beginning of the array. You should still consume values only once even if you + * can iterate through the array more than once. If you unescape a string + * within the array more than once, you have unsafe code. Note that rewinding + * an array means that you may need to reparse it anew: it is not a free + * operation. + * + * @returns true if the array contains some elements (not empty) + */ + inline simdjson_result reset() & noexcept; + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard, interpreting the current node + * as the root of its own JSON document. + * + * ondemand::parser parser; + * auto json = R"([ { "foo": { "a": [ 10, 20, 30 ] }} ])"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/0/foo/a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. Yet it is not the case when calling at_pointer on an array + * instance: there is no rewind and no invalidation. + * + * You may only call at_pointer on an array after it has been created, but before it has + * been first accessed. When calling at_pointer on an array, the pointer is advanced to + * the location indicated by the JSON pointer (in case of success). It is no longer possible + * to call at_pointer on the same array. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching. + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + /** + * Consumes the array and returns a string_view instance corresponding to the + * array as represented in JSON. It points inside the original document. + */ + simdjson_inline simdjson_result raw_json() noexcept; + + /** + * Get the value at the given index. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) noexcept; +protected: + /** + * Go to the end of the array, no matter where you are right now. + */ + simdjson_inline error_code consume() noexcept; + + /** + * Begin array iteration. + * + * @param iter The iterator. Must be where the initial [ is expected. Will be *moved* into the + * resulting array. + * @error INCORRECT_TYPE if the iterator is not at [. + */ + static simdjson_inline simdjson_result start(value_iterator &iter) noexcept; + /** + * Begin array iteration from the root. + * + * @param iter The iterator. Must be where the initial [ is expected. Will be *moved* into the + * resulting array. + * @error INCORRECT_TYPE if the iterator is not at [. + * @error TAPE_ERROR if there is no closing ] at the end of the document. + */ + static simdjson_inline simdjson_result start_root(value_iterator &iter) noexcept; + /** + * Begin array iteration. + * + * This version of the method should be called after the initial [ has been verified, and is + * intended for use by switch statements that check the type of a value. + * + * @param iter The iterator. Must be after the initial [. Will be *moved* into the resulting array. + */ + static simdjson_inline simdjson_result started(value_iterator &iter) noexcept; + + /** + * Create an array at the given Internal array creation. Call array::start() or array::started() instead of this. + * + * @param iter The iterator. Must either be at the start of the first element with iter.is_alive() + * == true, or past the [] with is_alive() == false if the array is empty. Will be *moved* + * into the resulting array. + */ + simdjson_inline array(const value_iterator &iter) noexcept; + + /** + * Iterator marking current position. + * + * iter.is_alive() == false indicates iteration is complete. + */ + value_iterator iter{}; + + friend class value; + friend class document; + friend struct simdjson_result; + friend struct simdjson_result; + friend class array_iterator; +}; + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::array &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + inline simdjson_result count_elements() & noexcept; + inline simdjson_result is_empty() & noexcept; + inline simdjson_result reset() & noexcept; + simdjson_inline simdjson_result at(size_t index) noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_H +/* end file simdjson/generic/ondemand/array.h for westmere */ +/* including simdjson/generic/ondemand/array_iterator.h for westmere: #include "simdjson/generic/ondemand/array_iterator.h" */ +/* begin file simdjson/generic/ondemand/array_iterator.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + + +namespace simdjson { +namespace westmere { +namespace ondemand { + +/** + * A forward-only JSON array. + * + * This is an input_iterator, meaning: + * - It is forward-only + * - * must be called exactly once per element. + * - ++ must be called exactly once in between each * (*, ++, *, ++, * ...) + */ +class array_iterator { +public: + /** Create a new, invalid array iterator. */ + simdjson_inline array_iterator() noexcept = default; + + // + // Iterator interface + // + + /** + * Get the current element. + * + * Part of the std::iterator interface. + */ + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + /** + * Check if we are at the end of the JSON. + * + * Part of the std::iterator interface. + * + * @return true if there are no more elements in the JSON array. + */ + simdjson_inline bool operator==(const array_iterator &) const noexcept; + /** + * Check if there are more elements in the JSON array. + * + * Part of the std::iterator interface. + * + * @return true if there are more elements in the JSON array. + */ + simdjson_inline bool operator!=(const array_iterator &) const noexcept; + /** + * Move to the next element. + * + * Part of the std::iterator interface. + */ + simdjson_inline array_iterator &operator++() noexcept; + +private: + value_iterator iter{}; + + simdjson_inline array_iterator(const value_iterator &iter) noexcept; + + friend class array; + friend class value; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::array_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + // + // Iterator interface + // + + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + simdjson_inline bool operator==(const simdjson_result &) const noexcept; + simdjson_inline bool operator!=(const simdjson_result &) const noexcept; + simdjson_inline simdjson_result &operator++() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H +/* end file simdjson/generic/ondemand/array_iterator.h for westmere */ +/* including simdjson/generic/ondemand/document.h for westmere: #include "simdjson/generic/ondemand/document.h" */ +/* begin file simdjson/generic/ondemand/document.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +/** + * A JSON document. It holds a json_iterator instance. + * + * Used by tokens to get text, and string buffer location. + * + * You must keep the document around during iteration. + */ +class document { +public: + /** + * Create a new invalid document. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline document() noexcept = default; + simdjson_inline document(const document &other) noexcept = delete; // pass your documents by reference, not by copy + simdjson_inline document(document &&other) noexcept = default; + simdjson_inline document &operator=(const document &other) noexcept = delete; + simdjson_inline document &operator=(document &&other) noexcept = default; + + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @returns INCORRECT_TYPE If the JSON value is not an array. + */ + simdjson_inline simdjson_result get_array() & noexcept; + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @returns INCORRECT_TYPE If the JSON value is not an object. + */ + simdjson_inline simdjson_result get_object() & noexcept; + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64() noexcept; + /** + * Cast this JSON value (inside string) to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64() noexcept; + /** + * Cast this JSON value (inside string) to a signed integer. + * + * @returns A signed 64-bit integer. + * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. + */ + simdjson_inline simdjson_result get_int64_in_string() noexcept; + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double() noexcept; + + /** + * Cast this JSON value (inside string) to a double. + * + * @returns A double. + * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number. + */ + simdjson_inline simdjson_result get_double_in_string() noexcept; + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: Calling get_string() twice on the same document is an error. + * + * @param Whether to allow a replacement character for unmatched surrogate pairs. + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + /** + * Attempts to fill the provided std::string reference with the parsed value of the current string. + * + * The string is guaranteed to be valid UTF-8. + * + * Important: a value should be consumed once. Calling get_string() twice on the same value + * is an error. + * + * Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory. + * We recommend you avoid allocating an std::string unless you need to. + * + * @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS. + */ + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + /** + * Cast this JSON value to a string. + * + * The string is not guaranteed to be valid UTF-8. See https://simonsapin.github.io/wtf-8/ + * + * Important: Calling get_wobbly_string() twice on the same document is an error. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_wobbly_string() noexcept; + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @returns INCORRECT_TYPE if the JSON value is not a string. + */ + simdjson_inline simdjson_result get_raw_json_string() noexcept; + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @returns INCORRECT_TYPE if the JSON value is not true or false. + */ + simdjson_inline simdjson_result get_bool() noexcept; + /** + * Cast this JSON value to a value when the document is an object or an array. + * + * You must not have begun iterating through the object or array. When + * SIMDJSON_DEVELOPMENT_CHECKS is set to 1 (which is the case when building in Debug mode + * by default), and you have already begun iterating, + * you will get an OUT_OF_ORDER_ITERATION error. If you have begun iterating, you can use + * rewind() to reset the document to its initial state before calling this method. + * + * @returns A value if a JSON array or object cannot be found. + * @returns SCALAR_DOCUMENT_AS_VALUE error is the document is a scalar (see is_scalar() function). + */ + simdjson_inline simdjson_result get_value() noexcept; + + /** + * Checks if this JSON value is null. If and only if the value is + * null, then it is consumed (we advance). If we find a token that + * begins with 'n' but is not 'null', then an error is returned. + * + * @returns Whether the value is null. + * @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'. + */ + simdjson_inline simdjson_result is_null() noexcept; + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool + * + * You may use get_double(), get_bool(), get_uint64(), get_int64(), + * get_object(), get_array(), get_raw_json_string(), or get_string() instead. + * + * @returns A value of the given type, parsed from the JSON. + * @returns INCORRECT_TYPE If the JSON value is not the given type. + */ + template simdjson_inline simdjson_result get() & noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + /** @overload template simdjson_result get() & noexcept */ + template simdjson_inline simdjson_result get() && noexcept { + // Unless the simdjson library provides an inline implementation, calling this method should + // immediately fail. + static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. " + "The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, " + "int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), " + " get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template."); + } + + /** + * Get this value as the given type. + * + * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool, value + * + * Be mindful that the document instance must remain in scope while you are accessing object, array and value instances. + * + * @param out This is set to a value of the given type, parsed from the JSON. If there is an error, this may not be initialized. + * @returns INCORRECT_TYPE If the JSON value is not an object. + * @returns SUCCESS If the parse succeeded and the out parameter was set to the value. + */ + template simdjson_inline error_code get(T &out) & noexcept; + /** @overload template error_code get(T &out) & noexcept */ + template simdjson_inline error_code get(T &out) && noexcept; + +#if SIMDJSON_EXCEPTIONS + /** + * Cast this JSON value to an array. + * + * @returns An object that can be used to iterate the array. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an array. + */ + simdjson_inline operator array() & noexcept(false); + /** + * Cast this JSON value to an object. + * + * @returns An object that can be used to look up or iterate fields. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an object. + */ + simdjson_inline operator object() & noexcept(false); + /** + * Cast this JSON value to an unsigned integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer. + */ + simdjson_inline operator uint64_t() noexcept(false); + /** + * Cast this JSON value to a signed integer. + * + * @returns A signed 64-bit integer. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer. + */ + simdjson_inline operator int64_t() noexcept(false); + /** + * Cast this JSON value to a double. + * + * @returns A double. + * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number. + */ + simdjson_inline operator double() noexcept(false); + /** + * Cast this JSON value to a string. + * + * The string is guaranteed to be valid UTF-8. + * + * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next + * time it parses a document or when it is destroyed. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator std::string_view() noexcept(false); + /** + * Cast this JSON value to a raw_json_string. + * + * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n). + * + * @returns A pointer to the raw JSON for the given string. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. + */ + simdjson_inline operator raw_json_string() noexcept(false); + /** + * Cast this JSON value to a bool. + * + * @returns A bool value. + * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false. + */ + simdjson_inline operator bool() noexcept(false); + /** + * Cast this JSON value to a value when the document is an object or an array. + * + * You must not have begun iterating through the object or array. When + * SIMDJSON_DEVELOPMENT_CHECKS is defined, and you have already begun iterating, + * you will get an OUT_OF_ORDER_ITERATION error. If you have begun iterating, you can use + * rewind() to reset the document to its initial state before calling this method. + * + * @returns A value value if a JSON array or object cannot be found. + * @exception SCALAR_DOCUMENT_AS_VALUE error is the document is a scalar (see is_scalar() function). + */ + simdjson_inline operator value() noexcept(false); +#endif + /** + * This method scans the array and counts the number of elements. + * The count_elements method should always be called before you have begun + * iterating through the array: it is expected that you are pointing at + * the beginning of the array. + * The runtime complexity is linear in the size of the array. After + * calling this function, if successful, the array is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + simdjson_inline simdjson_result count_elements() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Get the value at the given index in the array. This function has linear-time complexity. + * This function should only be called once on an array instance since the array iterator is not reset between each call. + * + * @return The value at the given index, or: + * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length + */ + simdjson_inline simdjson_result at(size_t index) & noexcept; + /** + * Begin array iteration. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result begin() & noexcept; + /** + * Sentinel representing the end of the array. + * + * Part of the std::iterable interface. + */ + simdjson_inline simdjson_result end() & noexcept; + + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. E.g., the array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to + * a key a single time. Doing object["mykey"].to_string()and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. E.g., the array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a key + * a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + + /** + * Get the type of this JSON value. It does not validate or consume the value. + * E.g., you must still call "is_null()" to check that a value is null even if + * "type()" returns json_type::null. + * + * NOTE: If you're only expecting a value to be one type (a typical case), it's generally + * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just + * let it throw an exception). + * + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result type() noexcept; + + /** + * Checks whether the document is a scalar (string, number, null, Boolean). + * Returns false when there it is an array or object. + * + * @returns true if the type is string, number, null, Boolean + * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse". + */ + simdjson_inline simdjson_result is_scalar() noexcept; + + /** + * Checks whether the document is a negative number. + * + * @returns true if the number if negative. + */ + simdjson_inline bool is_negative() noexcept; + /** + * Checks whether the document is an integer number. Note that + * this requires to partially parse the number string. If + * the value is determined to be an integer, it may still + * not parse properly as an integer in subsequent steps + * (e.g., it might overflow). + * + * @returns true if the number if negative. + */ + simdjson_inline simdjson_result is_integer() noexcept; + /** + * Determine the number type (integer or floating-point number) as quickly + * as possible. This function does not fully validate the input. It is + * useful when you only need to classify the numbers, without parsing them. + * + * If you are planning to retrieve the value or you need full validation, + * consider using the get_number() method instead: it will fully parse + * and validate the input, and give you access to the type: + * get_number().get_number_type(). + * + * get_number_type() is number_type::unsigned_integer if we have + * an integer greater or equal to 9223372036854775808 + * get_number_type() is number_type::signed_integer if we have an + * integer that is less than 9223372036854775808 + * Otherwise, get_number_type() has value number_type::floating_point_number + * + * This function requires processing the number string, but it is expected + * to be faster than get_number().get_number_type() because it is does not + * parse the number value. + * + * @returns the type of the number + */ + simdjson_inline simdjson_result get_number_type() noexcept; + + /** + * Attempt to parse an ondemand::number. An ondemand::number may + * contain an integer value or a floating-point value, the simdjson + * library will autodetect the type. Thus it is a dynamically typed + * number. Before accessing the value, you must determine the detected + * type. + * + * number.get_number_type() is number_type::signed_integer if we have + * an integer in [-9223372036854775808,9223372036854775808) + * You can recover the value by calling number.get_int64() and you + * have that number.is_int64() is true. + * + * number.get_number_type() is number_type::unsigned_integer if we have + * an integer in [9223372036854775808,18446744073709551616) + * You can recover the value by calling number.get_uint64() and you + * have that number.is_uint64() is true. + * + * Otherwise, number.get_number_type() has value number_type::floating_point_number + * and we have a binary64 number. + * You can recover the value by calling number.get_double() and you + * have that number.is_double() is true. + * + * You must check the type before accessing the value: it is an error + * to call "get_int64()" when number.get_number_type() is not + * number_type::signed_integer and when number.is_int64() is false. + */ + simdjson_warn_unused simdjson_inline simdjson_result get_number() noexcept; + + /** + * Get the raw JSON for this token. + * + * The string_view will always point into the input buffer. + * + * The string_view will start at the beginning of the token, and include the entire token + * *as well as all spaces until the next token (or EOF).* This means, for example, that a + * string token always begins with a " and is always terminated by the final ", possibly + * followed by a number of spaces. + * + * The string_view is *not* null-terminated. If this is a scalar (string, number, + * boolean, or null), the character after the end of the string_view may be the padded buffer. + * + * Tokens include: + * - { + * - [ + * - "a string (possibly with UTF-8 or backslashed characters like \\\")". + * - -1.2e-100 + * - true + * - false + * - null + */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + /** + * Reset the iterator inside the document instance so we are pointing back at the + * beginning of the document, as if it had just been created. It invalidates all + * values, objects and arrays that you have created so far (including unescaped strings). + */ + inline void rewind() noexcept; + /** + * Returns debugging information. + */ + inline std::string to_debug_string() noexcept; + /** + * Some unrecoverable error conditions may render the document instance unusable. + * The is_alive() method returns true when the document is still suitable. + */ + inline bool is_alive() noexcept; + + /** + * Returns the current location in the document if in bounds. + */ + inline simdjson_result current_location() const noexcept; + + /** + * Returns true if this document has been fully parsed. + * If you have consumed the whole document and at_end() returns + * false, then there may be trailing content. + */ + inline bool at_end() const noexcept; + + /** + * Returns the current depth in the document if in bounds. + * + * E.g., + * 0 = finished with document + * 1 = document root value (could be [ or {, not yet known) + * 2 = , or } inside root array/object + * 3 = key or value inside root array/object. + */ + simdjson_inline int32_t current_depth() const noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() automatically calls rewind between each call. Thus + * all values, objects and arrays that you have created so far (including unescaped strings) + * are invalidated. After calling at_pointer, you need to consume the result: string values + * should be stored in your own variables, arrays should be decoded and stored in your own array-like + * structures and so forth. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + * - SCALAR_DOCUMENT_AS_VALUE if the json_pointer is empty and the document is not a scalar (see is_scalar() function). + */ + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + /** + * Consumes the document and returns a string_view instance corresponding to the + * document as represented in JSON. It points inside the original byte array containing + * the JSON document. + */ + simdjson_inline simdjson_result raw_json() noexcept; +protected: + /** + * Consumes the document. + */ + simdjson_inline error_code consume() noexcept; + + simdjson_inline document(ondemand::json_iterator &&iter) noexcept; + simdjson_inline const uint8_t *text(uint32_t idx) const noexcept; + + simdjson_inline value_iterator resume_value_iterator() noexcept; + simdjson_inline value_iterator get_root_value_iterator() noexcept; + simdjson_inline simdjson_result start_or_resume_object() noexcept; + static simdjson_inline document start(ondemand::json_iterator &&iter) noexcept; + + // + // Fields + // + json_iterator iter{}; ///< Current position in the document + static constexpr depth_t DOCUMENT_DEPTH = 0; ///< document depth is always 0 + + friend class array_iterator; + friend class value; + friend class ondemand::parser; + friend class object; + friend class array; + friend class field; + friend class token; + friend class document_stream; + friend class document_reference; +}; + + +/** + * A document_reference is a thin wrapper around a document reference instance. + */ +class document_reference { +public: + simdjson_inline document_reference() noexcept; + simdjson_inline document_reference(document &d) noexcept; + simdjson_inline document_reference(const document_reference &other) noexcept = default; + simdjson_inline document_reference& operator=(const document_reference &other) noexcept = default; + simdjson_inline void rewind() noexcept; + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + + simdjson_inline simdjson_result is_null() noexcept; + simdjson_inline simdjson_result raw_json() noexcept; + simdjson_inline operator document&() const noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator array() & noexcept(false); + simdjson_inline operator object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline int32_t current_depth() const noexcept; + simdjson_inline bool is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + simdjson_inline simdjson_result raw_json_token() noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +private: + document *doc{nullptr}; +}; +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::document &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline error_code rewind() noexcept; + + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + + template simdjson_inline simdjson_result get() & noexcept; + template simdjson_inline simdjson_result get() && noexcept; + + template simdjson_inline error_code get(T &out) & noexcept; + template simdjson_inline error_code get(T &out) && noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator westmere::ondemand::array() & noexcept(false); + simdjson_inline operator westmere::ondemand::object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator westmere::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator westmere::ondemand::value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline int32_t current_depth() const noexcept; + simdjson_inline bool at_end() const noexcept; + simdjson_inline bool is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + /** @copydoc simdjson_inline std::string_view document::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + + +} // namespace simdjson + + + +namespace simdjson { + +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::document_reference value, error_code error) noexcept; + simdjson_inline simdjson_result() noexcept = default; + simdjson_inline error_code rewind() noexcept; + + simdjson_inline simdjson_result get_array() & noexcept; + simdjson_inline simdjson_result get_object() & noexcept; + simdjson_inline simdjson_result get_uint64() noexcept; + simdjson_inline simdjson_result get_uint64_in_string() noexcept; + simdjson_inline simdjson_result get_int64() noexcept; + simdjson_inline simdjson_result get_int64_in_string() noexcept; + simdjson_inline simdjson_result get_double() noexcept; + simdjson_inline simdjson_result get_double_in_string() noexcept; + simdjson_inline simdjson_result get_string(bool allow_replacement = false) noexcept; + template + simdjson_inline error_code get_string(string_type& receiver, bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result get_wobbly_string() noexcept; + simdjson_inline simdjson_result get_raw_json_string() noexcept; + simdjson_inline simdjson_result get_bool() noexcept; + simdjson_inline simdjson_result get_value() noexcept; + simdjson_inline simdjson_result is_null() noexcept; + +#if SIMDJSON_EXCEPTIONS + simdjson_inline operator westmere::ondemand::array() & noexcept(false); + simdjson_inline operator westmere::ondemand::object() & noexcept(false); + simdjson_inline operator uint64_t() noexcept(false); + simdjson_inline operator int64_t() noexcept(false); + simdjson_inline operator double() noexcept(false); + simdjson_inline operator std::string_view() noexcept(false); + simdjson_inline operator westmere::ondemand::raw_json_string() noexcept(false); + simdjson_inline operator bool() noexcept(false); + simdjson_inline operator westmere::ondemand::value() noexcept(false); +#endif + simdjson_inline simdjson_result count_elements() & noexcept; + simdjson_inline simdjson_result count_fields() & noexcept; + simdjson_inline simdjson_result at(size_t index) & noexcept; + simdjson_inline simdjson_result begin() & noexcept; + simdjson_inline simdjson_result end() & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(const char *key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](const char *key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(const char *key) & noexcept; + simdjson_inline simdjson_result type() noexcept; + simdjson_inline simdjson_result is_scalar() noexcept; + simdjson_inline simdjson_result current_location() noexcept; + simdjson_inline simdjson_result current_depth() const noexcept; + simdjson_inline simdjson_result is_negative() noexcept; + simdjson_inline simdjson_result is_integer() noexcept; + simdjson_inline simdjson_result get_number_type() noexcept; + simdjson_inline simdjson_result get_number() noexcept; + /** @copydoc simdjson_inline std::string_view document_reference::raw_json_token() const noexcept */ + simdjson_inline simdjson_result raw_json_token() noexcept; + + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; +}; + + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H +/* end file simdjson/generic/ondemand/document.h for westmere */ +/* including simdjson/generic/ondemand/document_stream.h for westmere: #include "simdjson/generic/ondemand/document_stream.h" */ +/* begin file simdjson/generic/ondemand/document_stream.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#ifdef SIMDJSON_THREADS_ENABLED +#include +#include +#include +#endif + +namespace simdjson { +namespace westmere { +namespace ondemand { + +#ifdef SIMDJSON_THREADS_ENABLED +/** @private Custom worker class **/ +struct stage1_worker { + stage1_worker() noexcept = default; + stage1_worker(const stage1_worker&) = delete; + stage1_worker(stage1_worker&&) = delete; + stage1_worker operator=(const stage1_worker&) = delete; + ~stage1_worker(); + /** + * We only start the thread when it is needed, not at object construction, this may throw. + * You should only call this once. + **/ + void start_thread(); + /** + * Start a stage 1 job. You should first call 'run', then 'finish'. + * You must call start_thread once before. + */ + void run(document_stream * ds, parser * stage1, size_t next_batch_start); + /** Wait for the run to finish (blocking). You should first call 'run', then 'finish'. **/ + void finish(); + +private: + + /** + * Normally, we would never stop the thread. But we do in the destructor. + * This function is only safe assuming that you are not waiting for results. You + * should have called run, then finish, and be done. + **/ + void stop_thread(); + + std::thread thread{}; + /** These three variables define the work done by the thread. **/ + ondemand::parser * stage1_thread_parser{}; + size_t _next_batch_start{}; + document_stream * owner{}; + /** + * We have two state variables. This could be streamlined to one variable in the future but + * we use two for clarity. + */ + bool has_work{false}; + bool can_work{true}; + + /** + * We lock using a mutex. + */ + std::mutex locking_mutex{}; + std::condition_variable cond_var{}; + + friend class document_stream; +}; +#endif // SIMDJSON_THREADS_ENABLED + +/** + * A forward-only stream of documents. + * + * Produced by parser::iterate_many. + * + */ +class document_stream { +public: + /** + * Construct an uninitialized document_stream. + * + * ```c++ + * document_stream docs; + * auto error = parser.iterate_many(json).get(docs); + * ``` + */ + simdjson_inline document_stream() noexcept; + /** Move one document_stream to another. */ + simdjson_inline document_stream(document_stream &&other) noexcept = default; + /** Move one document_stream to another. */ + simdjson_inline document_stream &operator=(document_stream &&other) noexcept = default; + + simdjson_inline ~document_stream() noexcept; + + /** + * Returns the input size in bytes. + */ + inline size_t size_in_bytes() const noexcept; + + /** + * After iterating through the stream, this method + * returns the number of bytes that were not parsed at the end + * of the stream. If truncated_bytes() differs from zero, + * then the input was truncated maybe because incomplete JSON + * documents were found at the end of the stream. You + * may need to process the bytes in the interval [size_in_bytes()-truncated_bytes(), size_in_bytes()). + * + * You should only call truncated_bytes() after streaming through all + * documents, like so: + * + * document_stream stream = parser.iterate_many(json,window); + * for(auto & doc : stream) { + * // do something with doc + * } + * size_t truncated = stream.truncated_bytes(); + * + */ + inline size_t truncated_bytes() const noexcept; + + class iterator { + public: + using value_type = simdjson_result; + using reference = value_type; + + using difference_type = std::ptrdiff_t; + + using iterator_category = std::input_iterator_tag; + + /** + * Default constructor. + */ + simdjson_inline iterator() noexcept; + /** + * Get the current document (or error). + */ + simdjson_inline simdjson_result operator*() noexcept; + /** + * Advance to the next document (prefix). + */ + inline iterator& operator++() noexcept; + /** + * Check if we're at the end yet. + * @param other the end iterator to compare to. + */ + simdjson_inline bool operator!=(const iterator &other) const noexcept; + /** + * @private + * + * Gives the current index in the input document in bytes. + * + * document_stream stream = parser.parse_many(json,window); + * for(auto i = stream.begin(); i != stream.end(); ++i) { + * auto doc = *i; + * size_t index = i.current_index(); + * } + * + * This function (current_index()) is experimental and the usage + * may change in future versions of simdjson: we find the API somewhat + * awkward and we would like to offer something friendlier. + */ + simdjson_inline size_t current_index() const noexcept; + + /** + * @private + * + * Gives a view of the current document at the current position. + * + * document_stream stream = parser.iterate_many(json,window); + * for(auto i = stream.begin(); i != stream.end(); ++i) { + * std::string_view v = i.source(); + * } + * + * The returned string_view instance is simply a map to the (unparsed) + * source string: it may thus include white-space characters and all manner + * of padding. + * + * This function (source()) is experimental and the usage + * may change in future versions of simdjson: we find the API somewhat + * awkward and we would like to offer something friendlier. + * + */ + simdjson_inline std::string_view source() const noexcept; + + /** + * Returns error of the stream (if any). + */ + inline error_code error() const noexcept; + + private: + simdjson_inline iterator(document_stream *s, bool finished) noexcept; + /** The document_stream we're iterating through. */ + document_stream* stream; + /** Whether we're finished or not. */ + bool finished; + + friend class document; + friend class document_stream; + friend class json_iterator; + }; + + /** + * Start iterating the documents in the stream. + */ + simdjson_inline iterator begin() noexcept; + /** + * The end of the stream, for iterator comparison purposes. + */ + simdjson_inline iterator end() noexcept; + +private: + + document_stream &operator=(const document_stream &) = delete; // Disallow copying + document_stream(const document_stream &other) = delete; // Disallow copying + + /** + * Construct a document_stream. Does not allocate or parse anything until the iterator is + * used. + * + * @param parser is a reference to the parser instance used to generate this document_stream + * @param buf is the raw byte buffer we need to process + * @param len is the length of the raw byte buffer in bytes + * @param batch_size is the size of the windows (must be strictly greater or equal to the largest JSON document) + */ + simdjson_inline document_stream( + ondemand::parser &parser, + const uint8_t *buf, + size_t len, + size_t batch_size, + bool allow_comma_separated + ) noexcept; + + /** + * Parse the first document in the buffer. Used by begin(), to handle allocation and + * initialization. + */ + inline void start() noexcept; + + /** + * Parse the next document found in the buffer previously given to document_stream. + * + * The content should be a valid JSON document encoded as UTF-8. If there is a + * UTF-8 BOM, the parser skips it. + * + * You do NOT need to pre-allocate a parser. This function takes care of + * pre-allocating a capacity defined by the batch_size defined when creating the + * document_stream object. + * + * The function returns simdjson::EMPTY if there is no more data to be parsed. + * + * The function returns simdjson::SUCCESS (as integer = 0) in case of success + * and indicates that the buffer has successfully been parsed to the end. + * Every document it contained has been parsed without error. + * + * The function returns an error code from simdjson/simdjson.h in case of failure + * such as simdjson::CAPACITY, simdjson::MEMALLOC, simdjson::DEPTH_ERROR and so forth; + * the simdjson::error_message function converts these error codes into a string). + * + * You can also check validity by calling parser.is_valid(). The same parser can + * and should be reused for the other documents in the buffer. + */ + inline void next() noexcept; + + /** Move the json_iterator of the document to the location of the next document in the stream. */ + inline void next_document() noexcept; + + /** Get the next document index. */ + inline size_t next_batch_start() const noexcept; + + /** Pass the next batch through stage 1 with the given parser. */ + inline error_code run_stage1(ondemand::parser &p, size_t batch_start) noexcept; + + // Fields + ondemand::parser *parser; + const uint8_t *buf; + size_t len; + size_t batch_size; + bool allow_comma_separated; + /** + * We are going to use just one document instance. The document owns + * the json_iterator. It implies that we only ever pass a reference + * to the document to the users. + */ + document doc{}; + /** The error (or lack thereof) from the current document. */ + error_code error; + size_t batch_start{0}; + size_t doc_index{}; + + #ifdef SIMDJSON_THREADS_ENABLED + /** Indicates whether we use threads. Note that this needs to be a constant during the execution of the parsing. */ + bool use_thread; + + inline void load_from_stage1_thread() noexcept; + + /** Start a thread to run stage 1 on the next batch. */ + inline void start_stage1_thread() noexcept; + + /** Wait for the stage 1 thread to finish and capture the results. */ + inline void finish_stage1_thread() noexcept; + + /** The error returned from the stage 1 thread. */ + error_code stage1_thread_error{UNINITIALIZED}; + /** The thread used to run stage 1 against the next batch in the background. */ + std::unique_ptr worker{new(std::nothrow) stage1_worker()}; + /** + * The parser used to run stage 1 in the background. Will be swapped + * with the regular parser when finished. + */ + ondemand::parser stage1_thread_parser{}; + + friend struct stage1_worker; + #endif // SIMDJSON_THREADS_ENABLED + + friend class parser; + friend class document; + friend class json_iterator; + friend struct simdjson_result; + friend struct internal::simdjson_result_base; +}; // document_stream + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::document_stream &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H +/* end file simdjson/generic/ondemand/document_stream.h for westmere */ +/* including simdjson/generic/ondemand/field.h for westmere: #include "simdjson/generic/ondemand/field.h" */ +/* begin file simdjson/generic/ondemand/field.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_FIELD_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_FIELD_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +/** + * A JSON field (key/value pair) in an object. + * + * Returned from object iteration. + * + * Extends from std::pair so you can use C++ algorithms that rely on pairs. + */ +class field : public std::pair { +public: + /** + * Create a new invalid field. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline field() noexcept; + + /** + * Get the key as a string_view (for higher speed, consider raw_key). + * We deliberately use a more cumbersome name (unescaped_key) to force users + * to think twice about using it. + * + * This consumes the key: once you have called unescaped_key(), you cannot + * call it again nor can you call key(). + */ + simdjson_inline simdjson_warn_unused simdjson_result unescaped_key(bool allow_replacement) noexcept; + /** + * Get the key as a raw_json_string. Can be used for direct comparison with + * an unescaped C string: e.g., key() == "test". + */ + simdjson_inline raw_json_string key() const noexcept; + /** + * Get the field value. + */ + simdjson_inline ondemand::value &value() & noexcept; + /** + * @overload ondemand::value &ondemand::value() & noexcept + */ + simdjson_inline ondemand::value value() && noexcept; + +protected: + simdjson_inline field(raw_json_string key, ondemand::value &&value) noexcept; + static simdjson_inline simdjson_result start(value_iterator &parent_iter) noexcept; + static simdjson_inline simdjson_result start(const value_iterator &parent_iter, raw_json_string key) noexcept; + friend struct simdjson_result; + friend class object_iterator; +}; + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::field &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result unescaped_key(bool allow_replacement = false) noexcept; + simdjson_inline simdjson_result key() noexcept; + simdjson_inline simdjson_result value() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_FIELD_H +/* end file simdjson/generic/ondemand/field.h for westmere */ +/* including simdjson/generic/ondemand/object.h for westmere: #include "simdjson/generic/ondemand/object.h" */ +/* begin file simdjson/generic/ondemand/object.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +/** + * A forward-only JSON object field iterator. + */ +class object { +public: + /** + * Create a new invalid object. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline object() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + /** + * Look up a field by name on an object (order-sensitive). + * + * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the + * JSON `{ "x": 1, "y": 2, "z": 3 }`: + * + * ```c++ + * simdjson::ondemand::parser parser; + * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded); + * double z = obj.find_field("z"); + * double y = obj.find_field("y"); + * double x = obj.find_field("x"); + * ``` + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys. + * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`. + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. The value instance you get + * from `content["bids"]` becomes invalid when you call `content["asks"]`. The array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a + * key a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() + * is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field(std::string_view key) && noexcept; + + /** + * Look up a field by name on an object, without regard to key order. + * + * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies + * and often appears negligible. It starts out normally, starting out at the last field; but if + * the field is not found, it scans from the beginning of the object to see if it missed it. That + * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object + * in question is large. The fact that the extra code is there also bumps the executable size. + * + * It is the default, however, because it would be highly surprising (and hard to debug) if the + * default behavior failed to look up a field just because it was in the wrong order--and many + * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. + * + * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the + * field wasn't there when they aren't). + * + * If you have multiple fields with a matching key ({"x": 1, "x": 1}) be mindful + * that only one field is returned. + * + * You must consume the fields on an object one at a time. A request for a new key + * invalidates previous field values: it makes them unsafe. The value instance you get + * from `content["bids"]` becomes invalid when you call `content["asks"]`. The array + * given by content["bids"].get_array() should not be accessed after you have called + * content["asks"].get_array(). You can detect such mistakes by first compiling and running + * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an + * OUT_OF_ORDER_ITERATION error is generated. + * + * You are expected to access keys only once. You should access the value corresponding to a key + * a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string() is an error. + * + * @param key The key to look up. + * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object. + */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result find_field_unordered(std::string_view key) && noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + /** @overload simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; */ + simdjson_inline simdjson_result operator[](std::string_view key) && noexcept; + + /** + * Get the value associated with the given JSON pointer. We use the RFC 6901 + * https://tools.ietf.org/html/rfc6901 standard, interpreting the current node + * as the root of its own JSON document. + * + * ondemand::parser parser; + * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("/foo/a/1") == 20 + * + * It is allowed for a key to be the empty string: + * + * ondemand::parser parser; + * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded; + * auto doc = parser.iterate(json); + * doc.at_pointer("//a/1") == 20 + * + * Note that at_pointer() called on the document automatically calls the document's rewind + * method between each call. It invalidates all previously accessed arrays, objects and values + * that have not been consumed. Yet it is not the case when calling at_pointer on an object + * instance: there is no rewind and no invalidation. + * + * You may call at_pointer more than once on an object, but each time the pointer is advanced + * to be within the value matched by the key indicated by the JSON pointer query. Thus any preceding + * key (as well as the current key) can no longer be used with following JSON pointer calls. + * + * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching. + * + * @return The value associated with the given JSON pointer, or: + * - NO_SUCH_FIELD if a field does not exist in an object + * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length + * - INCORRECT_TYPE if a non-integer is used to access an array + * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed + */ + inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + + /** + * Reset the iterator so that we are pointing back at the + * beginning of the object. You should still consume values only once even if you + * can iterate through the object more than once. If you unescape a string within + * the object more than once, you have unsafe code. Note that rewinding an object + * means that you may need to reparse it anew: it is not a free operation. + * + * @returns true if the object contains some elements (not empty) + */ + inline simdjson_result reset() & noexcept; + /** + * This method scans the beginning of the object and checks whether the + * object is empty. + * The runtime complexity is constant time. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + */ + inline simdjson_result is_empty() & noexcept; + /** + * This method scans the object and counts the number of key-value pairs. + * The count_fields method should always be called before you have begun + * iterating through the object: it is expected that you are pointing at + * the beginning of the object. + * The runtime complexity is linear in the size of the object. After + * calling this function, if successful, the object is 'rewinded' at its + * beginning as if it had never been accessed. If the JSON is malformed (e.g., + * there is a missing comma), then an error is returned and it is no longer + * safe to continue. + * + * To check that an object is empty, it is more performant to use + * the is_empty() method. + * + * Performance hint: You should only call count_fields() as a last + * resort as it may require scanning the document twice or more. + */ + simdjson_inline simdjson_result count_fields() & noexcept; + /** + * Consumes the object and returns a string_view instance corresponding to the + * object as represented in JSON. It points inside the original byte array containing + * the JSON document. + */ + simdjson_inline simdjson_result raw_json() noexcept; + +protected: + /** + * Go to the end of the object, no matter where you are right now. + */ + simdjson_inline error_code consume() noexcept; + static simdjson_inline simdjson_result start(value_iterator &iter) noexcept; + static simdjson_inline simdjson_result start_root(value_iterator &iter) noexcept; + static simdjson_inline simdjson_result started(value_iterator &iter) noexcept; + static simdjson_inline object resume(const value_iterator &iter) noexcept; + simdjson_inline object(const value_iterator &iter) noexcept; + + simdjson_warn_unused simdjson_inline error_code find_field_raw(const std::string_view key) noexcept; + + value_iterator iter{}; + + friend class value; + friend class document; + friend struct simdjson_result; +}; + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::object &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + simdjson_inline simdjson_result begin() noexcept; + simdjson_inline simdjson_result end() noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field(std::string_view key) && noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) & noexcept; + simdjson_inline simdjson_result find_field_unordered(std::string_view key) && noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) & noexcept; + simdjson_inline simdjson_result operator[](std::string_view key) && noexcept; + simdjson_inline simdjson_result at_pointer(std::string_view json_pointer) noexcept; + inline simdjson_result reset() noexcept; + inline simdjson_result is_empty() noexcept; + inline simdjson_result count_fields() & noexcept; + inline simdjson_result raw_json() noexcept; + +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_H +/* end file simdjson/generic/ondemand/object.h for westmere */ +/* including simdjson/generic/ondemand/object_iterator.h for westmere: #include "simdjson/generic/ondemand/object_iterator.h" */ +/* begin file simdjson/generic/ondemand/object_iterator.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +class object_iterator { +public: + /** + * Create a new invalid object_iterator. + * + * Exists so you can declare a variable and later assign to it before use. + */ + simdjson_inline object_iterator() noexcept = default; + + // + // Iterator interface + // + + // Reads key and value, yielding them to the user. + // MUST ONLY BE CALLED ONCE PER ITERATION. + simdjson_inline simdjson_result operator*() noexcept; + // Assumes it's being compared with the end. true if depth < iter->depth. + simdjson_inline bool operator==(const object_iterator &) const noexcept; + // Assumes it's being compared with the end. true if depth >= iter->depth. + simdjson_inline bool operator!=(const object_iterator &) const noexcept; + // Checks for ']' and ',' + simdjson_inline object_iterator &operator++() noexcept; + +private: + /** + * The underlying JSON iterator. + * + * PERF NOTE: expected to be elided in favor of the parent document: this is set when the object + * is first used, and never changes afterwards. + */ + value_iterator iter{}; + + simdjson_inline object_iterator(const value_iterator &iter) noexcept; + friend struct simdjson_result; + friend class object; +}; + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +template<> +struct simdjson_result : public westmere::implementation_simdjson_result_base { +public: + simdjson_inline simdjson_result(westmere::ondemand::object_iterator &&value) noexcept; ///< @private + simdjson_inline simdjson_result(error_code error) noexcept; ///< @private + simdjson_inline simdjson_result() noexcept = default; + + // + // Iterator interface + // + + // Reads key and value, yielding them to the user. + simdjson_inline simdjson_result operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION. + // Assumes it's being compared with the end. true if depth < iter->depth. + simdjson_inline bool operator==(const simdjson_result &) const noexcept; + // Assumes it's being compared with the end. true if depth >= iter->depth. + simdjson_inline bool operator!=(const simdjson_result &) const noexcept; + // Checks for ']' and ',' + simdjson_inline simdjson_result &operator++() noexcept; +}; + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H +/* end file simdjson/generic/ondemand/object_iterator.h for westmere */ +/* including simdjson/generic/ondemand/serialization.h for westmere: #include "simdjson/generic/ondemand/serialization.h" */ +/* begin file simdjson/generic/ondemand/serialization.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +/** + * Create a string-view instance out of a document instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(westmere::ondemand::document& x) noexcept; +/** + * Create a string-view instance out of a value instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. The value must + * not have been accessed previously. It does not + * validate the content. + */ +inline simdjson_result to_json_string(westmere::ondemand::value& x) noexcept; +/** + * Create a string-view instance out of an object instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(westmere::ondemand::object& x) noexcept; +/** + * Create a string-view instance out of an array instance. The string-view instance + * contains JSON text that is suitable to be parsed as JSON again. It does not + * validate the content. + */ +inline simdjson_result to_json_string(westmere::ondemand::array& x) noexcept; +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +inline simdjson_result to_json_string(simdjson_result x); +} // namespace simdjson + +/** + * We want to support argument-dependent lookup (ADL). + * Hence we should define operator<< in the namespace + * where the argument (here value, object, etc.) resides. + * Credit: @madhur4127 + * See https://github.com/simdjson/simdjson/issues/1768 + */ +namespace simdjson { namespace westmere { namespace ondemand { + +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The element. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::westmere::ondemand::value x); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The array. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::westmere::ondemand::array value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The array. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::westmere::ondemand::document& value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x); +#endif +inline std::ostream& operator<<(std::ostream& out, simdjson::westmere::ondemand::document_reference& value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x); +#endif +/** + * Print JSON to an output stream. It does not + * validate the content. + * + * @param out The output stream. + * @param value The object. + * @throw if there is an error with the underlying output stream. simdjson itself will not throw. + */ +inline std::ostream& operator<<(std::ostream& out, simdjson::westmere::ondemand::object value); +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x); +#endif +}}} // namespace simdjson::westmere::ondemand + +#endif // SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H +/* end file simdjson/generic/ondemand/serialization.h for westmere */ + +// Inline definitions +/* including simdjson/generic/ondemand/array-inl.h for westmere: #include "simdjson/generic/ondemand/array-inl.h" */ +/* begin file simdjson/generic/ondemand/array-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +// +// ### Live States +// +// While iterating or looking up values, depth >= iter->depth. at_start may vary. Error is +// always SUCCESS: +// +// - Start: This is the state when the array is first found and the iterator is just past the `{`. +// In this state, at_start == true. +// - Next: After we hand a scalar value to the user, or an array/object which they then fully +// iterate over, the iterator is at the `,` before the next value (or `]`). In this state, +// depth == iter->depth, at_start == false, and error == SUCCESS. +// - Unfinished Business: When we hand an array/object to the user which they do not fully +// iterate over, we need to finish that iteration by skipping child values until we reach the +// Next state. In this state, depth > iter->depth, at_start == false, and error == SUCCESS. +// +// ## Error States +// +// In error states, we will yield exactly one more value before stopping. iter->depth == depth +// and at_start is always false. We decrement after yielding the error, moving to the Finished +// state. +// +// - Chained Error: When the array iterator is part of an error chain--for example, in +// `for (auto tweet : doc["tweets"])`, where the tweet element may be missing or not be an +// array--we yield that error in the loop, exactly once. In this state, error != SUCCESS and +// iter->depth == depth, and at_start == false. We decrement depth when we yield the error. +// - Missing Comma Error: When the iterator ++ method discovers there is no comma between elements, +// we flag that as an error and treat it exactly the same as a Chained Error. In this state, +// error == TAPE_ERROR, iter->depth == depth, and at_start == false. +// +// ## Terminal State +// +// The terminal state has iter->depth < depth. at_start is always false. +// +// - Finished: When we have reached a `]` or have reported an error, we are finished. We signal this +// by decrementing depth. In this state, iter->depth < depth, at_start == false, and +// error == SUCCESS. +// + +simdjson_inline array::array(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} + +simdjson_inline simdjson_result array::start(value_iterator &iter) noexcept { + // We don't need to know if the array is empty to start iteration, but we do want to know if there + // is an error--thus `simdjson_unused`. + simdjson_unused bool has_value; + SIMDJSON_TRY( iter.start_array().get(has_value) ); + return array(iter); +} +simdjson_inline simdjson_result array::start_root(value_iterator &iter) noexcept { + simdjson_unused bool has_value; + SIMDJSON_TRY( iter.start_root_array().get(has_value) ); + return array(iter); +} +simdjson_inline simdjson_result array::started(value_iterator &iter) noexcept { + bool has_value; + SIMDJSON_TRY(iter.started_array().get(has_value)); + return array(iter); +} + +simdjson_inline simdjson_result array::begin() noexcept { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + return array_iterator(iter); +} +simdjson_inline simdjson_result array::end() noexcept { + return array_iterator(iter); +} +simdjson_inline error_code array::consume() noexcept { + auto error = iter.json_iter().skip_child(iter.depth()-1); + if(error) { iter.abandon(); } + return error; +} + +simdjson_inline simdjson_result array::raw_json() noexcept { + const uint8_t * starting_point{iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + // After 'consume()', we could be left pointing just beyond the document, but that + // is ok because we are not going to dereference the final pointer position, we just + // use it to compute the length in bytes. + const uint8_t * final_point{iter._json_iter->unsafe_pointer()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline simdjson_result array::count_elements() & noexcept { + size_t count{0}; + // Important: we do not consume any of the values. + for(simdjson_unused auto v : *this) { count++; } + // The above loop will always succeed, but we want to report errors. + if(iter.error()) { return iter.error(); } + // We need to move back at the start because we expect users to iterate through + // the array after counting the number of elements. + iter.reset_array(); + return count; +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline simdjson_result array::is_empty() & noexcept { + bool is_not_empty; + auto error = iter.reset_array().get(is_not_empty); + if(error) { return error; } + return !is_not_empty; +} + +inline simdjson_result array::reset() & noexcept { + return iter.reset_array(); +} + +inline simdjson_result array::at_pointer(std::string_view json_pointer) noexcept { + if (json_pointer[0] != '/') { return INVALID_JSON_POINTER; } + json_pointer = json_pointer.substr(1); + // - 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; } + + // Read the array index + size_t array_index = 0; + size_t i; + for (i = 0; i < json_pointer.length() && json_pointer[i] != '/'; i++) { + uint8_t digit = uint8_t(json_pointer[i] - '0'); + // Check for non-digit in array index. If it's there, we're trying to get a field in an object + if (digit > 9) { return INCORRECT_TYPE; } + array_index = array_index*10 + digit; + } + + // 0 followed by other digits is invalid + if (i > 1 && json_pointer[0] == '0') { return INVALID_JSON_POINTER; } // "JSON pointer array index has other characters after 0" + + // Empty string is invalid; so is a "/" with no digits before it + if (i == 0) { return INVALID_JSON_POINTER; } // "Empty string in JSON pointer array index" + // Get the child + auto child = at(array_index); + // If there is an error, it ends here + if(child.error()) { + return child; + } + + // If there is a /, we're not done yet, call recursively. + if (i < json_pointer.length()) { + child = child.at_pointer(json_pointer.substr(i)); + } + return child; +} + +simdjson_inline simdjson_result array::at(size_t index) noexcept { + size_t i = 0; + for (auto value : *this) { + if (i == index) { return value; } + i++; + } + return INDEX_OUT_OF_BOUNDS; +} + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + westmere::ondemand::array &&value +) noexcept + : implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept + : implementation_simdjson_result_base(error) +{ +} + +simdjson_inline simdjson_result simdjson_result::begin() noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() noexcept { + if (error()) { return error(); } + return first.end(); +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::is_empty() & noexcept { + if (error()) { return error(); } + return first.is_empty(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H +/* end file simdjson/generic/ondemand/array-inl.h for westmere */ +/* including simdjson/generic/ondemand/array_iterator-inl.h for westmere: #include "simdjson/generic/ondemand/array_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/array_iterator-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +simdjson_inline array_iterator::array_iterator(const value_iterator &_iter) noexcept + : iter{_iter} +{} + +simdjson_inline simdjson_result array_iterator::operator*() noexcept { + if (iter.error()) { iter.abandon(); return iter.error(); } + return value(iter.child()); +} +simdjson_inline bool array_iterator::operator==(const array_iterator &other) const noexcept { + return !(*this != other); +} +simdjson_inline bool array_iterator::operator!=(const array_iterator &) const noexcept { + return iter.is_open(); +} +simdjson_inline array_iterator &array_iterator::operator++() noexcept { + error_code error; + // PERF NOTE this is a safety rail ... users should exit loops as soon as they receive an error, so we'll never get here. + // However, it does not seem to make a perf difference, so we add it out of an abundance of caution. + if (( error = iter.error() )) { return *this; } + if (( error = iter.skip_child() )) { return *this; } + if (( error = iter.has_next_element().error() )) { return *this; } + return *this; +} + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + westmere::ondemand::array_iterator &&value +) noexcept + : westmere::implementation_simdjson_result_base(std::forward(value)) +{ + first.iter.assert_is_valid(); +} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : westmere::implementation_simdjson_result_base({}, error) +{ +} + +simdjson_inline simdjson_result simdjson_result::operator*() noexcept { + if (error()) { return error(); } + return *first; +} +simdjson_inline bool simdjson_result::operator==(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return !error(); } + return first == other.first; +} +simdjson_inline bool simdjson_result::operator!=(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return error(); } + return first != other.first; +} +simdjson_inline simdjson_result &simdjson_result::operator++() noexcept { + // Clear the error if there is one, so we don't yield it twice + if (error()) { second = SUCCESS; return *this; } + ++(first); + return *this; +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/array_iterator-inl.h for westmere */ +/* including simdjson/generic/ondemand/document-inl.h for westmere: #include "simdjson/generic/ondemand/document-inl.h" */ +/* begin file simdjson/generic/ondemand/document-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +simdjson_inline document::document(ondemand::json_iterator &&_iter) noexcept + : iter{std::forward(_iter)} +{ + logger::log_start_value(iter, "document"); +} + +simdjson_inline document document::start(json_iterator &&iter) noexcept { + return document(std::forward(iter)); +} + +inline void document::rewind() noexcept { + iter.rewind(); +} + +inline std::string document::to_debug_string() noexcept { + return iter.to_string(); +} + +inline simdjson_result document::current_location() const noexcept { + return iter.current_location(); +} + +inline int32_t document::current_depth() const noexcept { + return iter.depth(); +} + +inline bool document::at_end() const noexcept { + return iter.at_end(); +} + + +inline bool document::is_alive() noexcept { + return iter.is_alive(); +} +simdjson_inline value_iterator document::resume_value_iterator() noexcept { + return value_iterator(&iter, 1, iter.root_position()); +} +simdjson_inline value_iterator document::get_root_value_iterator() noexcept { + return resume_value_iterator(); +} +simdjson_inline simdjson_result document::start_or_resume_object() noexcept { + if (iter.at_root()) { + return get_object(); + } else { + return object::resume(resume_value_iterator()); + } +} +simdjson_inline simdjson_result document::get_value() noexcept { + // Make sure we start any arrays or objects before returning, so that start_root_() + // gets called. + + // It is the convention throughout the code that the macro `SIMDJSON_DEVELOPMENT_CHECKS` determines whether + // we check for OUT_OF_ORDER_ITERATION. Proper on::demand code should never trigger this error. +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.at_root()) { return OUT_OF_ORDER_ITERATION; } +#endif + // assert_at_root() serves two purposes: in Debug mode, whether or not + // SIMDJSON_DEVELOPMENT_CHECKS is set or not, it checks that we are at the root of + // the document (this will typically be redundant). In release mode, it generates + // SIMDJSON_ASSUME statements to allow the compiler to make assumptions. + iter.assert_at_root(); + switch (*iter.peek()) { + case '[': { + // The following lines check that the document ends with ]. + auto value_iterator = get_root_value_iterator(); + auto error = value_iterator.check_root_array(); + if(error) { return error; } + return value(get_root_value_iterator()); + } + case '{': { + // The following lines would check that the document ends with }. + auto value_iterator = get_root_value_iterator(); + auto error = value_iterator.check_root_object(); + if(error) { return error; } + return value(get_root_value_iterator()); + } + default: + // Unfortunately, scalar documents are a special case in simdjson and they cannot + // be safely converted to value instances. + return SCALAR_DOCUMENT_AS_VALUE; + } +} +simdjson_inline simdjson_result document::get_array() & noexcept { + auto value = get_root_value_iterator(); + return array::start_root(value); +} +simdjson_inline simdjson_result document::get_object() & noexcept { + auto value = get_root_value_iterator(); + return object::start_root(value); +} + +/** + * We decided that calling 'get_double()' on the JSON document '1.233 blabla' should + * give an error, so we check for trailing content. We want to disallow trailing + * content. + * Thus, in several implementations below, we pass a 'true' parameter value to + * a get_root_value_iterator() method: this indicates that we disallow trailing content. + */ + +simdjson_inline simdjson_result document::get_uint64() noexcept { + return get_root_value_iterator().get_root_uint64(true); +} +simdjson_inline simdjson_result document::get_uint64_in_string() noexcept { + return get_root_value_iterator().get_root_uint64_in_string(true); +} +simdjson_inline simdjson_result document::get_int64() noexcept { + return get_root_value_iterator().get_root_int64(true); +} +simdjson_inline simdjson_result document::get_int64_in_string() noexcept { + return get_root_value_iterator().get_root_int64_in_string(true); +} +simdjson_inline simdjson_result document::get_double() noexcept { + return get_root_value_iterator().get_root_double(true); +} +simdjson_inline simdjson_result document::get_double_in_string() noexcept { + return get_root_value_iterator().get_root_double_in_string(true); +} +simdjson_inline simdjson_result document::get_string(bool allow_replacement) noexcept { + return get_root_value_iterator().get_root_string(true, allow_replacement); +} +template +simdjson_inline error_code document::get_string(string_type& receiver, bool allow_replacement) noexcept { + return get_root_value_iterator().get_root_string(receiver, true, allow_replacement); +} +simdjson_inline simdjson_result document::get_wobbly_string() noexcept { + return get_root_value_iterator().get_root_wobbly_string(true); +} +simdjson_inline simdjson_result document::get_raw_json_string() noexcept { + return get_root_value_iterator().get_root_raw_json_string(true); +} +simdjson_inline simdjson_result document::get_bool() noexcept { + return get_root_value_iterator().get_root_bool(true); +} +simdjson_inline simdjson_result document::is_null() noexcept { + return get_root_value_iterator().is_root_null(true); +} + +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_array(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_object(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_double(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_uint64(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_int64(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_bool(); } +template<> simdjson_inline simdjson_result document::get() & noexcept { return get_value(); } + +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_double(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_uint64(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_int64(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return std::forward(*this).get_bool(); } +template<> simdjson_inline simdjson_result document::get() && noexcept { return get_value(); } + +template simdjson_inline error_code document::get(T &out) & noexcept { + return get().get(out); +} +template simdjson_inline error_code document::get(T &out) && noexcept { + return std::forward(*this).get().get(out); +} + +#if SIMDJSON_EXCEPTIONS +simdjson_inline document::operator array() & noexcept(false) { return get_array(); } +simdjson_inline document::operator object() & noexcept(false) { return get_object(); } +simdjson_inline document::operator uint64_t() noexcept(false) { return get_uint64(); } +simdjson_inline document::operator int64_t() noexcept(false) { return get_int64(); } +simdjson_inline document::operator double() noexcept(false) { return get_double(); } +simdjson_inline document::operator std::string_view() noexcept(false) { return get_string(false); } +simdjson_inline document::operator raw_json_string() noexcept(false) { return get_raw_json_string(); } +simdjson_inline document::operator bool() noexcept(false) { return get_bool(); } +simdjson_inline document::operator value() noexcept(false) { return get_value(); } + +#endif +simdjson_inline simdjson_result document::count_elements() & noexcept { + auto a = get_array(); + simdjson_result answer = a.count_elements(); + /* If there was an array, we are now left pointing at its first element. */ + if(answer.error() == SUCCESS) { rewind(); } + return answer; +} +simdjson_inline simdjson_result document::count_fields() & noexcept { + auto a = get_object(); + simdjson_result answer = a.count_fields(); + /* If there was an object, we are now left pointing at its first element. */ + if(answer.error() == SUCCESS) { rewind(); } + return answer; +} +simdjson_inline simdjson_result document::at(size_t index) & noexcept { + auto a = get_array(); + return a.at(index); +} +simdjson_inline simdjson_result document::begin() & noexcept { + return get_array().begin(); +} +simdjson_inline simdjson_result document::end() & noexcept { + return {}; +} + +simdjson_inline simdjson_result document::find_field(std::string_view key) & noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result document::find_field(const char *key) & noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result document::find_field_unordered(std::string_view key) & noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result document::find_field_unordered(const char *key) & noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result document::operator[](std::string_view key) & noexcept { + return start_or_resume_object()[key]; +} +simdjson_inline simdjson_result document::operator[](const char *key) & noexcept { + return start_or_resume_object()[key]; +} + +simdjson_inline error_code document::consume() noexcept { + auto error = iter.skip_child(0); + if(error) { iter.abandon(); } + return error; +} + +simdjson_inline simdjson_result document::raw_json() noexcept { + auto _iter = get_root_value_iterator(); + const uint8_t * starting_point{_iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + // After 'consume()', we could be left pointing just beyond the document, but that + // is ok because we are not going to dereference the final pointer position, we just + // use it to compute the length in bytes. + const uint8_t * final_point{iter.unsafe_pointer()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +simdjson_inline simdjson_result document::type() noexcept { + return get_root_value_iterator().type(); +} + +simdjson_inline simdjson_result document::is_scalar() noexcept { + json_type this_type; + auto error = type().get(this_type); + if(error) { return error; } + return ! ((this_type == json_type::array) || (this_type == json_type::object)); +} + +simdjson_inline bool document::is_negative() noexcept { + return get_root_value_iterator().is_root_negative(); +} + +simdjson_inline simdjson_result document::is_integer() noexcept { + return get_root_value_iterator().is_root_integer(true); +} + +simdjson_inline simdjson_result document::get_number_type() noexcept { + return get_root_value_iterator().get_root_number_type(true); +} + +simdjson_inline simdjson_result document::get_number() noexcept { + return get_root_value_iterator().get_root_number(true); +} + + +simdjson_inline simdjson_result document::raw_json_token() noexcept { + auto _iter = get_root_value_iterator(); + return std::string_view(reinterpret_cast(_iter.peek_start()), _iter.peek_start_length()); +} + +simdjson_inline simdjson_result document::at_pointer(std::string_view json_pointer) noexcept { + rewind(); // Rewind the document each time at_pointer is called + if (json_pointer.empty()) { + return this->get_value(); + } + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: + return (*this).get_array().at_pointer(json_pointer); + case json_type::object: + return (*this).get_object().at_pointer(json_pointer); + default: + return INVALID_JSON_POINTER; + } +} + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + westmere::ondemand::document &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base( + error + ) +{ +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) & noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline error_code simdjson_result::rewind() noexcept { + if (error()) { return error(); } + first.rewind(); + return SUCCESS; +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::get_array() & noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() & noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::get_value() noexcept { + if (error()) { return error(); } + return first.get_value(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} + +template +simdjson_inline simdjson_result simdjson_result::get() & noexcept { + if (error()) { return error(); } + return first.get(); +} +template +simdjson_inline simdjson_result simdjson_result::get() && noexcept { + if (error()) { return error(); } + return std::forward(first).get(); +} +template +simdjson_inline error_code simdjson_result::get(T &out) & noexcept { + if (error()) { return error(); } + return first.get(out); +} +template +simdjson_inline error_code simdjson_result::get(T &out) && noexcept { + if (error()) { return error(); } + return std::forward(first).get(out); +} + +template<> simdjson_inline simdjson_result simdjson_result::get() & noexcept = delete; +template<> simdjson_inline simdjson_result simdjson_result::get() && noexcept { + if (error()) { return error(); } + return std::forward(first); +} +template<> simdjson_inline error_code simdjson_result::get(westmere::ondemand::document &out) & noexcept = delete; +template<> simdjson_inline error_code simdjson_result::get(westmere::ondemand::document &out) && noexcept { + if (error()) { return error(); } + out = std::forward(first); + return SUCCESS; +} + +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} + +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} + + +simdjson_inline bool simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} + +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} + +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} + +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} + + +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator westmere::ondemand::array() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator westmere::ondemand::object() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator westmere::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator westmere::ondemand::value() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline bool simdjson_result::at_end() const noexcept { + if (error()) { return error(); } + return first.at_end(); +} + + +simdjson_inline int32_t simdjson_result::current_depth() const noexcept { + if (error()) { return error(); } + return first.current_depth(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + + +} // namespace simdjson + + +namespace simdjson { +namespace westmere { +namespace ondemand { + +simdjson_inline document_reference::document_reference() noexcept : doc{nullptr} {} +simdjson_inline document_reference::document_reference(document &d) noexcept : doc(&d) {} +simdjson_inline void document_reference::rewind() noexcept { doc->rewind(); } +simdjson_inline simdjson_result document_reference::get_array() & noexcept { return doc->get_array(); } +simdjson_inline simdjson_result document_reference::get_object() & noexcept { return doc->get_object(); } +/** + * The document_reference instances are used primarily/solely for streams of JSON + * documents. + * We decided that calling 'get_double()' on the JSON document '1.233 blabla' should + * give an error, so we check for trailing content. + * + * However, for streams of JSON documents, we want to be able to start from + * "321" "321" "321" + * and parse it successfully as a stream of JSON documents, calling get_uint64_in_string() + * successfully each time. + * + * To achieve this result, we pass a 'false' to a get_root_value_iterator() method: + * this indicates that we allow trailing content. + */ +simdjson_inline simdjson_result document_reference::get_uint64() noexcept { return doc->get_root_value_iterator().get_root_uint64(false); } +simdjson_inline simdjson_result document_reference::get_uint64_in_string() noexcept { return doc->get_root_value_iterator().get_root_uint64_in_string(false); } +simdjson_inline simdjson_result document_reference::get_int64() noexcept { return doc->get_root_value_iterator().get_root_int64(false); } +simdjson_inline simdjson_result document_reference::get_int64_in_string() noexcept { return doc->get_root_value_iterator().get_root_int64_in_string(false); } +simdjson_inline simdjson_result document_reference::get_double() noexcept { return doc->get_root_value_iterator().get_root_double(false); } +simdjson_inline simdjson_result document_reference::get_double_in_string() noexcept { return doc->get_root_value_iterator().get_root_double(false); } +simdjson_inline simdjson_result document_reference::get_string(bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(false, allow_replacement); } +template +simdjson_inline error_code document_reference::get_string(string_type& receiver, bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(receiver, false, allow_replacement); } +simdjson_inline simdjson_result document_reference::get_wobbly_string() noexcept { return doc->get_root_value_iterator().get_root_wobbly_string(false); } +simdjson_inline simdjson_result document_reference::get_raw_json_string() noexcept { return doc->get_root_value_iterator().get_root_raw_json_string(false); } +simdjson_inline simdjson_result document_reference::get_bool() noexcept { return doc->get_root_value_iterator().get_root_bool(false); } +simdjson_inline simdjson_result document_reference::get_value() noexcept { return doc->get_value(); } +simdjson_inline simdjson_result document_reference::is_null() noexcept { return doc->get_root_value_iterator().is_root_null(false); } + +#if SIMDJSON_EXCEPTIONS +simdjson_inline document_reference::operator array() & noexcept(false) { return array(*doc); } +simdjson_inline document_reference::operator object() & noexcept(false) { return object(*doc); } +simdjson_inline document_reference::operator uint64_t() noexcept(false) { return get_uint64(); } +simdjson_inline document_reference::operator int64_t() noexcept(false) { return get_int64(); } +simdjson_inline document_reference::operator double() noexcept(false) { return get_double(); } +simdjson_inline document_reference::operator std::string_view() noexcept(false) { return std::string_view(*doc); } +simdjson_inline document_reference::operator raw_json_string() noexcept(false) { return raw_json_string(*doc); } +simdjson_inline document_reference::operator bool() noexcept(false) { return get_bool(); } +simdjson_inline document_reference::operator value() noexcept(false) { return value(*doc); } +#endif +simdjson_inline simdjson_result document_reference::count_elements() & noexcept { return doc->count_elements(); } +simdjson_inline simdjson_result document_reference::count_fields() & noexcept { return doc->count_fields(); } +simdjson_inline simdjson_result document_reference::at(size_t index) & noexcept { return doc->at(index); } +simdjson_inline simdjson_result document_reference::begin() & noexcept { return doc->begin(); } +simdjson_inline simdjson_result document_reference::end() & noexcept { return doc->end(); } +simdjson_inline simdjson_result document_reference::find_field(std::string_view key) & noexcept { return doc->find_field(key); } +simdjson_inline simdjson_result document_reference::find_field(const char *key) & noexcept { return doc->find_field(key); } +simdjson_inline simdjson_result document_reference::operator[](std::string_view key) & noexcept { return (*doc)[key]; } +simdjson_inline simdjson_result document_reference::operator[](const char *key) & noexcept { return (*doc)[key]; } +simdjson_inline simdjson_result document_reference::find_field_unordered(std::string_view key) & noexcept { return doc->find_field_unordered(key); } +simdjson_inline simdjson_result document_reference::find_field_unordered(const char *key) & noexcept { return doc->find_field_unordered(key); } +simdjson_inline simdjson_result document_reference::type() noexcept { return doc->type(); } +simdjson_inline simdjson_result document_reference::is_scalar() noexcept { return doc->is_scalar(); } +simdjson_inline simdjson_result document_reference::current_location() noexcept { return doc->current_location(); } +simdjson_inline int32_t document_reference::current_depth() const noexcept { return doc->current_depth(); } +simdjson_inline bool document_reference::is_negative() noexcept { return doc->is_negative(); } +simdjson_inline simdjson_result document_reference::is_integer() noexcept { return doc->get_root_value_iterator().is_root_integer(false); } +simdjson_inline simdjson_result document_reference::get_number_type() noexcept { return doc->get_root_value_iterator().get_root_number_type(false); } +simdjson_inline simdjson_result document_reference::get_number() noexcept { return doc->get_root_value_iterator().get_root_number(false); } +simdjson_inline simdjson_result document_reference::raw_json_token() noexcept { return doc->raw_json_token(); } +simdjson_inline simdjson_result document_reference::at_pointer(std::string_view json_pointer) noexcept { return doc->at_pointer(json_pointer); } +simdjson_inline simdjson_result document_reference::raw_json() noexcept { return doc->raw_json();} +simdjson_inline document_reference::operator document&() const noexcept { return *doc; } + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + + + +namespace simdjson { +simdjson_inline simdjson_result::simdjson_result(westmere::ondemand::document_reference value, error_code error) + noexcept : implementation_simdjson_result_base(std::forward(value), error) {} + + +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) & noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline error_code simdjson_result::rewind() noexcept { + if (error()) { return error(); } + first.rewind(); + return SUCCESS; +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::get_array() & noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() & noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::get_value() noexcept { + if (error()) { return error(); } + return first.get_value(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} +simdjson_inline simdjson_result simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator westmere::ondemand::array() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator westmere::ondemand::object() & noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator westmere::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator westmere::ondemand::value() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H +/* end file simdjson/generic/ondemand/document-inl.h for westmere */ +/* including simdjson/generic/ondemand/document_stream-inl.h for westmere: #include "simdjson/generic/ondemand/document_stream-inl.h" */ +/* begin file simdjson/generic/ondemand/document_stream-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document_stream.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include + +namespace simdjson { +namespace westmere { +namespace ondemand { + +#ifdef SIMDJSON_THREADS_ENABLED + +inline void stage1_worker::finish() { + // After calling "run" someone would call finish() to wait + // for the end of the processing. + // This function will wait until either the thread has done + // the processing or, else, the destructor has been called. + std::unique_lock lock(locking_mutex); + cond_var.wait(lock, [this]{return has_work == false;}); +} + +inline stage1_worker::~stage1_worker() { + // The thread may never outlive the stage1_worker instance + // and will always be stopped/joined before the stage1_worker + // instance is gone. + stop_thread(); +} + +inline void stage1_worker::start_thread() { + std::unique_lock lock(locking_mutex); + if(thread.joinable()) { + return; // This should never happen but we never want to create more than one thread. + } + thread = std::thread([this]{ + while(true) { + std::unique_lock thread_lock(locking_mutex); + // We wait for either "run" or "stop_thread" to be called. + cond_var.wait(thread_lock, [this]{return has_work || !can_work;}); + // If, for some reason, the stop_thread() method was called (i.e., the + // destructor of stage1_worker is called, then we want to immediately destroy + // the thread (and not do any more processing). + if(!can_work) { + break; + } + this->owner->stage1_thread_error = this->owner->run_stage1(*this->stage1_thread_parser, + this->_next_batch_start); + this->has_work = false; + // The condition variable call should be moved after thread_lock.unlock() for performance + // reasons but thread sanitizers may report it as a data race if we do. + // See https://stackoverflow.com/questions/35775501/c-should-condition-variable-be-notified-under-lock + cond_var.notify_one(); // will notify "finish" + thread_lock.unlock(); + } + } + ); +} + + +inline void stage1_worker::stop_thread() { + std::unique_lock lock(locking_mutex); + // We have to make sure that all locks can be released. + can_work = false; + has_work = false; + cond_var.notify_all(); + lock.unlock(); + if(thread.joinable()) { + thread.join(); + } +} + +inline void stage1_worker::run(document_stream * ds, parser * stage1, size_t next_batch_start) { + std::unique_lock lock(locking_mutex); + owner = ds; + _next_batch_start = next_batch_start; + stage1_thread_parser = stage1; + has_work = true; + // The condition variable call should be moved after thread_lock.unlock() for performance + // reasons but thread sanitizers may report it as a data race if we do. + // See https://stackoverflow.com/questions/35775501/c-should-condition-variable-be-notified-under-lock + cond_var.notify_one(); // will notify the thread lock that we have work + lock.unlock(); +} + +#endif // SIMDJSON_THREADS_ENABLED + +simdjson_inline document_stream::document_stream( + ondemand::parser &_parser, + const uint8_t *_buf, + size_t _len, + size_t _batch_size, + bool _allow_comma_separated +) noexcept + : parser{&_parser}, + buf{_buf}, + len{_len}, + batch_size{_batch_size <= MINIMAL_BATCH_SIZE ? MINIMAL_BATCH_SIZE : _batch_size}, + allow_comma_separated{_allow_comma_separated}, + error{SUCCESS} + #ifdef SIMDJSON_THREADS_ENABLED + , use_thread(_parser.threaded) // we need to make a copy because _parser.threaded can change + #endif +{ +#ifdef SIMDJSON_THREADS_ENABLED + if(worker.get() == nullptr) { + error = MEMALLOC; + } +#endif +} + +simdjson_inline document_stream::document_stream() noexcept + : parser{nullptr}, + buf{nullptr}, + len{0}, + batch_size{0}, + allow_comma_separated{false}, + error{UNINITIALIZED} + #ifdef SIMDJSON_THREADS_ENABLED + , use_thread(false) + #endif +{ +} + +simdjson_inline document_stream::~document_stream() noexcept +{ + #ifdef SIMDJSON_THREADS_ENABLED + worker.reset(); + #endif +} + +inline size_t document_stream::size_in_bytes() const noexcept { + return len; +} + +inline size_t document_stream::truncated_bytes() const noexcept { + if(error == CAPACITY) { return len - batch_start; } + return parser->implementation->structural_indexes[parser->implementation->n_structural_indexes] - parser->implementation->structural_indexes[parser->implementation->n_structural_indexes + 1]; +} + +simdjson_inline document_stream::iterator::iterator() noexcept + : stream{nullptr}, finished{true} { +} + +simdjson_inline document_stream::iterator::iterator(document_stream* _stream, bool is_end) noexcept + : stream{_stream}, finished{is_end} { +} + +simdjson_inline simdjson_result document_stream::iterator::operator*() noexcept { + //if(stream->error) { return stream->error; } + return simdjson_result(stream->doc, stream->error); +} + +simdjson_inline document_stream::iterator& document_stream::iterator::operator++() noexcept { + // If there is an error, then we want the iterator + // to be finished, no matter what. (E.g., we do not + // keep generating documents with errors, or go beyond + // a document with errors.) + // + // Users do not have to call "operator*()" when they use operator++, + // so we need to end the stream in the operator++ function. + // + // Note that setting finished = true is essential otherwise + // we would enter an infinite loop. + if (stream->error) { finished = true; } + // Note that stream->error() is guarded against error conditions + // (it will immediately return if stream->error casts to false). + // In effect, this next function does nothing when (stream->error) + // is true (hence the risk of an infinite loop). + stream->next(); + // If that was the last document, we're finished. + // It is the only type of error we do not want to appear + // in operator*. + if (stream->error == EMPTY) { finished = true; } + // If we had any other kind of error (not EMPTY) then we want + // to pass it along to the operator* and we cannot mark the result + // as "finished" just yet. + return *this; +} + +simdjson_inline bool document_stream::iterator::operator!=(const document_stream::iterator &other) const noexcept { + return finished != other.finished; +} + +simdjson_inline document_stream::iterator document_stream::begin() noexcept { + start(); + // If there are no documents, we're finished. + return iterator(this, error == EMPTY); +} + +simdjson_inline document_stream::iterator document_stream::end() noexcept { + return iterator(this, true); +} + +inline void document_stream::start() noexcept { + if (error) { return; } + error = parser->allocate(batch_size); + if (error) { return; } + // Always run the first stage 1 parse immediately + batch_start = 0; + error = run_stage1(*parser, batch_start); + while(error == EMPTY) { + // In exceptional cases, we may start with an empty block + batch_start = next_batch_start(); + if (batch_start >= len) { return; } + error = run_stage1(*parser, batch_start); + } + if (error) { return; } + doc_index = batch_start; + doc = document(json_iterator(&buf[batch_start], parser)); + doc.iter._streaming = true; + + #ifdef SIMDJSON_THREADS_ENABLED + if (use_thread && next_batch_start() < len) { + // Kick off the first thread on next batch if needed + error = stage1_thread_parser.allocate(batch_size); + if (error) { return; } + worker->start_thread(); + start_stage1_thread(); + if (error) { return; } + } + #endif // SIMDJSON_THREADS_ENABLED +} + +inline void document_stream::next() noexcept { + // We always enter at once once in an error condition. + if (error) { return; } + next_document(); + if (error) { return; } + auto cur_struct_index = doc.iter._root - parser->implementation->structural_indexes.get(); + doc_index = batch_start + parser->implementation->structural_indexes[cur_struct_index]; + + // Check if at end of structural indexes (i.e. at end of batch) + if(cur_struct_index >= static_cast(parser->implementation->n_structural_indexes)) { + error = EMPTY; + // Load another batch (if available) + while (error == EMPTY) { + batch_start = next_batch_start(); + if (batch_start >= len) { break; } + #ifdef SIMDJSON_THREADS_ENABLED + if(use_thread) { + load_from_stage1_thread(); + } else { + error = run_stage1(*parser, batch_start); + } + #else + error = run_stage1(*parser, batch_start); + #endif + /** + * Whenever we move to another window, we need to update all pointers to make + * it appear as if the input buffer started at the beginning of the window. + * + * Take this input: + * + * {"z":5} {"1":1,"2":2,"4":4} [7, 10, 9] [15, 11, 12, 13] [154, 110, 112, 1311] + * + * Say you process the following window... + * + * '{"z":5} {"1":1,"2":2,"4":4} [7, 10, 9]' + * + * When you do so, the json_iterator has a pointer at the beginning of the memory region + * (pointing at the beginning of '{"z"...'. + * + * When you move to the window that starts at... + * + * '[7, 10, 9] [15, 11, 12, 13] ... + * + * then it is not sufficient to just run stage 1. You also need to re-anchor the + * json_iterator so that it believes we are starting at '[7, 10, 9]...'. + * + * Under the DOM front-end, this gets done automatically because the parser owns + * the pointer the data, and when you call stage1 and then stage2 on the same + * parser, then stage2 will run on the pointer acquired by stage1. + * + * That is, stage1 calls "this->buf = _buf" so the parser remembers the buffer that + * we used. But json_iterator has no callback when stage1 is called on the parser. + * In fact, I think that the parser is unaware of json_iterator. + * + * + * So we need to re-anchor the json_iterator after each call to stage 1 so that + * all of the pointers are in sync. + */ + doc.iter = json_iterator(&buf[batch_start], parser); + doc.iter._streaming = true; + /** + * End of resync. + */ + + if (error) { continue; } // If the error was EMPTY, we may want to load another batch. + doc_index = batch_start; + } + } +} + +inline void document_stream::next_document() noexcept { + // Go to next place where depth=0 (document depth) + error = doc.iter.skip_child(0); + if (error) { return; } + // Always set depth=1 at the start of document + doc.iter._depth = 1; + // consume comma if comma separated is allowed + if (allow_comma_separated) { doc.iter.consume_character(','); } + // Resets the string buffer at the beginning, thus invalidating the strings. + doc.iter._string_buf_loc = parser->string_buf.get(); + doc.iter._root = doc.iter.position(); +} + +inline size_t document_stream::next_batch_start() const noexcept { + return batch_start + parser->implementation->structural_indexes[parser->implementation->n_structural_indexes]; +} + +inline error_code document_stream::run_stage1(ondemand::parser &p, size_t _batch_start) noexcept { + // This code only updates the structural index in the parser, it does not update any json_iterator + // instance. + size_t remaining = len - _batch_start; + if (remaining <= batch_size) { + return p.implementation->stage1(&buf[_batch_start], remaining, stage1_mode::streaming_final); + } else { + return p.implementation->stage1(&buf[_batch_start], batch_size, stage1_mode::streaming_partial); + } +} + +simdjson_inline size_t document_stream::iterator::current_index() const noexcept { + return stream->doc_index; +} + +simdjson_inline std::string_view document_stream::iterator::source() const noexcept { + auto depth = stream->doc.iter.depth(); + auto cur_struct_index = stream->doc.iter._root - stream->parser->implementation->structural_indexes.get(); + + // If at root, process the first token to determine if scalar value + if (stream->doc.iter.at_root()) { + switch (stream->buf[stream->batch_start + stream->parser->implementation->structural_indexes[cur_struct_index]]) { + case '{': case '[': // Depth=1 already at start of document + break; + case '}': case ']': + depth--; + break; + default: // Scalar value document + // TODO: Remove any trailing whitespaces + // This returns a string spanning from start of value to the beginning of the next document (excluded) + return std::string_view(reinterpret_cast(stream->buf) + current_index(), stream->parser->implementation->structural_indexes[++cur_struct_index] - current_index() - 1); + } + cur_struct_index++; + } + + while (cur_struct_index <= static_cast(stream->parser->implementation->n_structural_indexes)) { + switch (stream->buf[stream->batch_start + stream->parser->implementation->structural_indexes[cur_struct_index]]) { + case '{': case '[': + depth++; + break; + case '}': case ']': + depth--; + break; + } + if (depth == 0) { break; } + cur_struct_index++; + } + + return std::string_view(reinterpret_cast(stream->buf) + current_index(), stream->parser->implementation->structural_indexes[cur_struct_index] - current_index() + stream->batch_start + 1);; +} + +inline error_code document_stream::iterator::error() const noexcept { + return stream->error; +} + +#ifdef SIMDJSON_THREADS_ENABLED + +inline void document_stream::load_from_stage1_thread() noexcept { + worker->finish(); + // Swap to the parser that was loaded up in the thread. Make sure the parser has + // enough memory to swap to, as well. + std::swap(stage1_thread_parser,*parser); + error = stage1_thread_error; + if (error) { return; } + + // If there's anything left, start the stage 1 thread! + if (next_batch_start() < len) { + start_stage1_thread(); + } +} + +inline void document_stream::start_stage1_thread() noexcept { + // we call the thread on a lambda that will update + // this->stage1_thread_error + // there is only one thread that may write to this value + // TODO this is NOT exception-safe. + this->stage1_thread_error = UNINITIALIZED; // In case something goes wrong, make sure it's an error + size_t _next_batch_start = this->next_batch_start(); + + worker->run(this, & this->stage1_thread_parser, _next_batch_start); +} + +#endif // SIMDJSON_THREADS_ENABLED + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} +simdjson_inline simdjson_result::simdjson_result( + westmere::ondemand::document_stream &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} + +} + +#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H +/* end file simdjson/generic/ondemand/document_stream-inl.h for westmere */ +/* including simdjson/generic/ondemand/field-inl.h for westmere: #include "simdjson/generic/ondemand/field-inl.h" */ +/* begin file simdjson/generic/ondemand/field-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +// clang 6 doesn't think the default constructor can be noexcept, so we make it explicit +simdjson_inline field::field() noexcept : std::pair() {} + +simdjson_inline field::field(raw_json_string key, ondemand::value &&value) noexcept + : std::pair(key, std::forward(value)) +{ +} + +simdjson_inline simdjson_result field::start(value_iterator &parent_iter) noexcept { + raw_json_string key; + SIMDJSON_TRY( parent_iter.field_key().get(key) ); + SIMDJSON_TRY( parent_iter.field_value() ); + return field::start(parent_iter, key); +} + +simdjson_inline simdjson_result field::start(const value_iterator &parent_iter, raw_json_string key) noexcept { + return field(key, parent_iter.child()); +} + +simdjson_inline simdjson_warn_unused simdjson_result field::unescaped_key(bool allow_replacement) noexcept { + SIMDJSON_ASSUME(first.buf != nullptr); // We would like to call .alive() but Visual Studio won't let us. + simdjson_result answer = first.unescape(second.iter.json_iter(), allow_replacement); + first.consume(); + return answer; +} + +simdjson_inline raw_json_string field::key() const noexcept { + SIMDJSON_ASSUME(first.buf != nullptr); // We would like to call .alive() by Visual Studio won't let us. + return first; +} + +simdjson_inline value &field::value() & noexcept { + return second; +} + +simdjson_inline value field::value() && noexcept { + return std::forward(*this).second; +} + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + westmere::ondemand::field &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} + +simdjson_inline simdjson_result simdjson_result::key() noexcept { + if (error()) { return error(); } + return first.key(); +} +simdjson_inline simdjson_result simdjson_result::unescaped_key(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.unescaped_key(allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::value() noexcept { + if (error()) { return error(); } + return std::move(first.value()); +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H +/* end file simdjson/generic/ondemand/field-inl.h for westmere */ +/* including simdjson/generic/ondemand/json_iterator-inl.h for westmere: #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/json_iterator-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +simdjson_inline json_iterator::json_iterator(json_iterator &&other) noexcept + : token(std::forward(other.token)), + parser{other.parser}, + _string_buf_loc{other._string_buf_loc}, + error{other.error}, + _depth{other._depth}, + _root{other._root}, + _streaming{other._streaming} +{ + other.parser = nullptr; +} +simdjson_inline json_iterator &json_iterator::operator=(json_iterator &&other) noexcept { + token = other.token; + parser = other.parser; + _string_buf_loc = other._string_buf_loc; + error = other.error; + _depth = other._depth; + _root = other._root; + _streaming = other._streaming; + other.parser = nullptr; + return *this; +} + +simdjson_inline json_iterator::json_iterator(const uint8_t *buf, ondemand::parser *_parser) noexcept + : token(buf, &_parser->implementation->structural_indexes[0]), + parser{_parser}, + _string_buf_loc{parser->string_buf.get()}, + _depth{1}, + _root{parser->implementation->structural_indexes.get()}, + _streaming{false} + +{ + logger::log_headers(); +#if SIMDJSON_CHECK_EOF + assert_more_tokens(); +#endif +} + +inline void json_iterator::rewind() noexcept { + token.set_position( root_position() ); + logger::log_headers(); // We start again + _string_buf_loc = parser->string_buf.get(); + _depth = 1; +} + +inline bool json_iterator::balanced() const noexcept { + token_iterator ti(token); + int32_t count{0}; + ti.set_position( root_position() ); + while(ti.peek() <= peek_last()) { + switch (*ti.return_current_and_advance()) + { + case '[': case '{': + count++; + break; + case ']': case '}': + count--; + break; + default: + break; + } + } + return count == 0; +} + + +// GCC 7 warns when the first line of this function is inlined away into oblivion due to the caller +// relating depth and parent_depth, which is a desired effect. The warning does not show up if the +// skip_child() function is not marked inline). +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_warn_unused simdjson_inline error_code json_iterator::skip_child(depth_t parent_depth) noexcept { + if (depth() <= parent_depth) { return SUCCESS; } + switch (*return_current_and_advance()) { + // TODO consider whether matching braces is a requirement: if non-matching braces indicates + // *missing* braces, then future lookups are not in the object/arrays they think they are, + // violating the rule "validate enough structure that the user can be confident they are + // looking at the right values." + // PERF TODO we can eliminate the switch here with a lookup of how much to add to depth + + // For the first open array/object in a value, we've already incremented depth, so keep it the same + // We never stop at colon, but if we did, it wouldn't affect depth + case '[': case '{': case ':': + logger::log_start_value(*this, "skip"); + break; + // If there is a comma, we have just finished a value in an array/object, and need to get back in + case ',': + logger::log_value(*this, "skip"); + break; + // ] or } means we just finished a value and need to jump out of the array/object + case ']': case '}': + logger::log_end_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } +#if SIMDJSON_CHECK_EOF + // If there are no more tokens, the parent is incomplete. + if (at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "Missing [ or { at start"); } +#endif // SIMDJSON_CHECK_EOF + break; + case '"': + if(*peek() == ':') { + // We are at a key!!! + // This might happen if you just started an object and you skip it immediately. + // Performance note: it would be nice to get rid of this check as it is somewhat + // expensive. + // https://github.com/simdjson/simdjson/issues/1742 + logger::log_value(*this, "key"); + return_current_and_advance(); // eat up the ':' + break; // important!!! + } + simdjson_fallthrough; + // Anything else must be a scalar value + default: + // For the first scalar, we will have incremented depth already, so we decrement it here. + logger::log_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } + break; + } + + // Now that we've considered the first value, we only increment/decrement for arrays/objects + while (position() < end_position()) { + switch (*return_current_and_advance()) { + case '[': case '{': + logger::log_start_value(*this, "skip"); + _depth++; + break; + // TODO consider whether matching braces is a requirement: if non-matching braces indicates + // *missing* braces, then future lookups are not in the object/arrays they think they are, + // violating the rule "validate enough structure that the user can be confident they are + // looking at the right values." + // PERF TODO we can eliminate the switch here with a lookup of how much to add to depth + case ']': case '}': + logger::log_end_value(*this, "skip"); + _depth--; + if (depth() <= parent_depth) { return SUCCESS; } + break; + default: + logger::log_value(*this, "skip", ""); + break; + } + } + + return report_error(TAPE_ERROR, "not enough close braces"); +} + +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline bool json_iterator::at_root() const noexcept { + return position() == root_position(); +} + +simdjson_inline bool json_iterator::is_single_token() const noexcept { + return parser->implementation->n_structural_indexes == 1; +} + +simdjson_inline bool json_iterator::streaming() const noexcept { + return _streaming; +} + +simdjson_inline token_position json_iterator::root_position() const noexcept { + return _root; +} + +simdjson_inline void json_iterator::assert_at_document_depth() const noexcept { + SIMDJSON_ASSUME( _depth == 1 ); +} + +simdjson_inline void json_iterator::assert_at_root() const noexcept { + SIMDJSON_ASSUME( _depth == 1 ); +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + // Under Visual Studio, the next SIMDJSON_ASSUME fails with: the argument + // has side effects that will be discarded. + SIMDJSON_ASSUME( token.position() == _root ); +#endif +} + +simdjson_inline void json_iterator::assert_more_tokens(uint32_t required_tokens) const noexcept { + assert_valid_position(token._position + required_tokens - 1); +} + +simdjson_inline void json_iterator::assert_valid_position(token_position position) const noexcept { +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + SIMDJSON_ASSUME( position >= &parser->implementation->structural_indexes[0] ); + SIMDJSON_ASSUME( position < &parser->implementation->structural_indexes[parser->implementation->n_structural_indexes] ); +#endif +} + +simdjson_inline bool json_iterator::at_end() const noexcept { + return position() == end_position(); +} +simdjson_inline token_position json_iterator::end_position() const noexcept { + uint32_t n_structural_indexes{parser->implementation->n_structural_indexes}; + return &parser->implementation->structural_indexes[n_structural_indexes]; +} + +inline std::string json_iterator::to_string() const noexcept { + if( !is_alive() ) { return "dead json_iterator instance"; } + const char * current_structural = reinterpret_cast(token.peek()); + return std::string("json_iterator [ depth : ") + std::to_string(_depth) + + std::string(", structural : '") + std::string(current_structural,1) + + std::string("', offset : ") + std::to_string(token.current_offset()) + + std::string("', error : ") + error_message(error) + + std::string(" ]"); +} + +inline simdjson_result json_iterator::current_location() const noexcept { + if (!is_alive()) { // Unrecoverable error + if (!at_root()) { + return reinterpret_cast(token.peek(-1)); + } else { + return reinterpret_cast(token.peek()); + } + } + if (at_end()) { + return OUT_OF_BOUNDS; + } + return reinterpret_cast(token.peek()); +} + +simdjson_inline bool json_iterator::is_alive() const noexcept { + return parser; +} + +simdjson_inline void json_iterator::abandon() noexcept { + parser = nullptr; + _depth = 0; +} + +simdjson_inline const uint8_t *json_iterator::return_current_and_advance() noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(); +#endif // SIMDJSON_CHECK_EOF + return token.return_current_and_advance(); +} + +simdjson_inline const uint8_t *json_iterator::unsafe_pointer() const noexcept { + // deliberately done without safety guard: + return token.peek(); +} + +simdjson_inline const uint8_t *json_iterator::peek(int32_t delta) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(delta+1); +#endif // SIMDJSON_CHECK_EOF + return token.peek(delta); +} + +simdjson_inline uint32_t json_iterator::peek_length(int32_t delta) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_more_tokens(delta+1); +#endif // #if SIMDJSON_CHECK_EOF + return token.peek_length(delta); +} + +simdjson_inline const uint8_t *json_iterator::peek(token_position position) const noexcept { + // todo: currently we require end-of-string buffering, but the following + // assert_valid_position should be turned on if/when we lift that condition. + // assert_valid_position(position); + // This is almost surely related to SIMDJSON_CHECK_EOF but given that SIMDJSON_CHECK_EOF + // is ON by default, we have no choice but to disable it for real with a comment. + return token.peek(position); +} + +simdjson_inline uint32_t json_iterator::peek_length(token_position position) const noexcept { +#if SIMDJSON_CHECK_EOF + assert_valid_position(position); +#endif // SIMDJSON_CHECK_EOF + return token.peek_length(position); +} + +simdjson_inline token_position json_iterator::last_position() const noexcept { + // The following line fails under some compilers... + // SIMDJSON_ASSUME(parser->implementation->n_structural_indexes > 0); + // since it has side-effects. + uint32_t n_structural_indexes{parser->implementation->n_structural_indexes}; + SIMDJSON_ASSUME(n_structural_indexes > 0); + return &parser->implementation->structural_indexes[n_structural_indexes - 1]; +} +simdjson_inline const uint8_t *json_iterator::peek_last() const noexcept { + return token.peek(last_position()); +} + +simdjson_inline void json_iterator::ascend_to(depth_t parent_depth) noexcept { + SIMDJSON_ASSUME(parent_depth >= 0 && parent_depth < INT32_MAX - 1); + SIMDJSON_ASSUME(_depth == parent_depth + 1); + _depth = parent_depth; +} + +simdjson_inline void json_iterator::descend_to(depth_t child_depth) noexcept { + SIMDJSON_ASSUME(child_depth >= 1 && child_depth < INT32_MAX); + SIMDJSON_ASSUME(_depth == child_depth - 1); + _depth = child_depth; +} + +simdjson_inline depth_t json_iterator::depth() const noexcept { + return _depth; +} + +simdjson_inline uint8_t *&json_iterator::string_buf_loc() noexcept { + return _string_buf_loc; +} + +simdjson_inline error_code json_iterator::report_error(error_code _error, const char *message) noexcept { + SIMDJSON_ASSUME(_error != SUCCESS && _error != UNINITIALIZED && _error != INCORRECT_TYPE && _error != NO_SUCH_FIELD); + logger::log_error(*this, message); + error = _error; + return error; +} + +simdjson_inline token_position json_iterator::position() const noexcept { + return token.position(); +} + +simdjson_inline simdjson_result json_iterator::unescape(raw_json_string in, bool allow_replacement) noexcept { + return parser->unescape(in, _string_buf_loc, allow_replacement); +} + +simdjson_inline simdjson_result json_iterator::unescape_wobbly(raw_json_string in) noexcept { + return parser->unescape_wobbly(in, _string_buf_loc); +} + +simdjson_inline void json_iterator::reenter_child(token_position position, depth_t child_depth) noexcept { + SIMDJSON_ASSUME(child_depth >= 1 && child_depth < INT32_MAX); + SIMDJSON_ASSUME(_depth == child_depth - 1); +#if SIMDJSON_DEVELOPMENT_CHECKS +#ifndef SIMDJSON_CLANG_VISUAL_STUDIO + SIMDJSON_ASSUME(size_t(child_depth) < parser->max_depth()); + SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]); +#endif +#endif + token.set_position(position); + _depth = child_depth; +} + +simdjson_inline error_code json_iterator::consume_character(char c) noexcept { + if (*peek() == c) { + return_current_and_advance(); + return SUCCESS; + } + return TAPE_ERROR; +} + +#if SIMDJSON_DEVELOPMENT_CHECKS + +simdjson_inline token_position json_iterator::start_position(depth_t depth) const noexcept { + SIMDJSON_ASSUME(size_t(depth) < parser->max_depth()); + return size_t(depth) < parser->max_depth() ? parser->start_positions[depth] : 0; +} + +simdjson_inline void json_iterator::set_start_position(depth_t depth, token_position position) noexcept { + SIMDJSON_ASSUME(size_t(depth) < parser->max_depth()); + if(size_t(depth) < parser->max_depth()) { parser->start_positions[depth] = position; } +} + +#endif + + +simdjson_inline error_code json_iterator::optional_error(error_code _error, const char *message) noexcept { + SIMDJSON_ASSUME(_error == INCORRECT_TYPE || _error == NO_SUCH_FIELD); + logger::log_error(*this, message); + return _error; +} + + +simdjson_warn_unused simdjson_inline bool json_iterator::copy_to_buffer(const uint8_t *json, uint32_t max_len, uint8_t *tmpbuf, size_t N) noexcept { + // This function is not expected to be called in performance-sensitive settings. + // Let us guard against silly cases: + if((N < max_len) || (N == 0)) { return false; } + // Copy to the buffer. + std::memcpy(tmpbuf, json, max_len); + if(N > max_len) { // We pad whatever remains with ' '. + std::memset(tmpbuf + max_len, ' ', N - max_len); + } + return true; +} + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(westmere::ondemand::json_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/json_iterator-inl.h for westmere */ +/* including simdjson/generic/ondemand/json_type-inl.h for westmere: #include "simdjson/generic/ondemand/json_type-inl.h" */ +/* begin file simdjson/generic/ondemand/json_type-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +inline std::ostream& operator<<(std::ostream& out, json_type type) noexcept { + switch (type) { + case json_type::array: out << "array"; break; + case json_type::object: out << "object"; break; + case json_type::number: out << "number"; break; + case json_type::string: out << "string"; break; + case json_type::boolean: out << "boolean"; break; + case json_type::null: out << "null"; break; + default: SIMDJSON_UNREACHABLE(); + } + return out; +} + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson_result &type) noexcept(false) { + return out << type.value(); +} +#endif + + + +simdjson_inline number_type number::get_number_type() const noexcept { + return type; +} + +simdjson_inline bool number::is_uint64() const noexcept { + return get_number_type() == number_type::unsigned_integer; +} + +simdjson_inline uint64_t number::get_uint64() const noexcept { + return payload.unsigned_integer; +} + +simdjson_inline number::operator uint64_t() const noexcept { + return get_uint64(); +} + + +simdjson_inline bool number::is_int64() const noexcept { + return get_number_type() == number_type::signed_integer; +} + +simdjson_inline int64_t number::get_int64() const noexcept { + return payload.signed_integer; +} + +simdjson_inline number::operator int64_t() const noexcept { + return get_int64(); +} + +simdjson_inline bool number::is_double() const noexcept { + return get_number_type() == number_type::floating_point_number; +} + +simdjson_inline double number::get_double() const noexcept { + return payload.floating_point_number; +} + +simdjson_inline number::operator double() const noexcept { + return get_double(); +} + +simdjson_inline double number::as_double() const noexcept { + if(is_double()) { + return payload.floating_point_number; + } + if(is_int64()) { + return double(payload.signed_integer); + } + return double(payload.unsigned_integer); +} + +simdjson_inline void number::append_s64(int64_t value) noexcept { + payload.signed_integer = value; + type = number_type::signed_integer; +} + +simdjson_inline void number::append_u64(uint64_t value) noexcept { + payload.unsigned_integer = value; + type = number_type::unsigned_integer; +} + +simdjson_inline void number::append_double(double value) noexcept { + payload.floating_point_number = value; + type = number_type::floating_point_number; +} + +simdjson_inline void number::skip_double() noexcept { + type = number_type::floating_point_number; +} + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(westmere::ondemand::json_type &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H +/* end file simdjson/generic/ondemand/json_type-inl.h for westmere */ +/* including simdjson/generic/ondemand/logger-inl.h for westmere: #include "simdjson/generic/ondemand/logger-inl.h" */ +/* begin file simdjson/generic/ondemand/logger-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/logger.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#include +#include + +namespace simdjson { +namespace westmere { +namespace ondemand { +namespace logger { + +static constexpr const char * DASHES = "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"; +static constexpr const int LOG_EVENT_LEN = 20; +static constexpr const int LOG_BUFFER_LEN = 30; +static constexpr const int LOG_SMALL_BUFFER_LEN = 10; +static int log_depth = 0; // Not threadsafe. Log only. + +// Helper to turn unprintable or newline characters into spaces +static inline char printable_char(char c) { + if (c >= 0x20) { + return c; + } else { + return ' '; + } +} + +template +static inline std::string string_format(const std::string& format, const Args&... args) +{ + SIMDJSON_PUSH_DISABLE_ALL_WARNINGS + int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; + auto size = static_cast(size_s); + if (size <= 0) return std::string(); + std::unique_ptr buf(new char[size]); + std::snprintf(buf.get(), size, format.c_str(), args...); + SIMDJSON_POP_DISABLE_WARNINGS + return std::string(buf.get(), buf.get() + size - 1); +} + +static inline log_level get_log_level_from_env() +{ + SIMDJSON_PUSH_DISABLE_WARNINGS + SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe + char *lvl = getenv("SIMDJSON_LOG_LEVEL"); + SIMDJSON_POP_DISABLE_WARNINGS + if (lvl && simdjson_strcasecmp(lvl, "ERROR") == 0) { return log_level::error; } + return log_level::info; +} + +static inline log_level log_threshold() +{ + static log_level threshold = get_log_level_from_env(); + return threshold; +} + +static inline bool should_log(log_level level) +{ + return level >= log_threshold(); +} + +inline void log_event(const json_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_line(iter, "", type, detail, delta, depth_delta, log_level::info); +} + +inline void log_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail) noexcept { + log_line(iter, index, depth, "", type, detail, log_level::info); +} +inline void log_value(const json_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_line(iter, "", type, detail, delta, depth_delta, log_level::info); +} + +inline void log_start_value(const json_iterator &iter, token_position index, depth_t depth, const char *type, std::string_view detail) noexcept { + log_line(iter, index, depth, "+", type, detail, log_level::info); + if (LOG_ENABLED) { log_depth++; } +} +inline void log_start_value(const json_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_line(iter, "+", type, "", delta, depth_delta, log_level::info); + if (LOG_ENABLED) { log_depth++; } +} + +inline void log_end_value(const json_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + if (LOG_ENABLED) { log_depth--; } + log_line(iter, "-", type, "", delta, depth_delta, log_level::info); +} + +inline void log_error(const json_iterator &iter, const char *error, const char *detail, int delta, int depth_delta) noexcept { + log_line(iter, "ERROR: ", error, detail, delta, depth_delta, log_level::error); +} +inline void log_error(const json_iterator &iter, token_position index, depth_t depth, const char *error, const char *detail) noexcept { + log_line(iter, index, depth, "ERROR: ", error, detail, log_level::error); +} + +inline void log_event(const value_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_event(iter.json_iter(), type, detail, delta, depth_delta); +} + +inline void log_value(const value_iterator &iter, const char *type, std::string_view detail, int delta, int depth_delta) noexcept { + log_value(iter.json_iter(), type, detail, delta, depth_delta); +} + +inline void log_start_value(const value_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_start_value(iter.json_iter(), type, delta, depth_delta); +} + +inline void log_end_value(const value_iterator &iter, const char *type, int delta, int depth_delta) noexcept { + log_end_value(iter.json_iter(), type, delta, depth_delta); +} + +inline void log_error(const value_iterator &iter, const char *error, const char *detail, int delta, int depth_delta) noexcept { + log_error(iter.json_iter(), error, detail, delta, depth_delta); +} + +inline void log_headers() noexcept { + if (LOG_ENABLED) { + if (simdjson_unlikely(should_log(log_level::info))) { + // Technically a static variable is not thread-safe, but if you are using threads and logging... well... + static bool displayed_hint{false}; + log_depth = 0; + printf("\n"); + if (!displayed_hint) { + // We only print this helpful header once. + printf("# Logging provides the depth and position of the iterator user-visible steps:\n"); + printf("# +array says 'this is where we were when we discovered the start array'\n"); + printf( + "# -array says 'this is where we were when we ended the array'\n"); + printf("# skip says 'this is a structural or value I am skipping'\n"); + printf("# +/-skip says 'this is a start/end array or object I am skipping'\n"); + printf("#\n"); + printf("# The indentation of the terms (array, string,...) indicates the depth,\n"); + printf("# in addition to the depth being displayed.\n"); + printf("#\n"); + printf("# Every token in the document has a single depth determined by the tokens before it,\n"); + printf("# and is not affected by what the token actually is.\n"); + printf("#\n"); + printf("# Not all structural elements are presented as tokens in the logs.\n"); + printf("#\n"); + printf("# We never give control to the user within an empty array or an empty object.\n"); + printf("#\n"); + printf("# Inside an array, having a depth greater than the array's depth means that\n"); + printf("# we are pointing inside a value.\n"); + printf("# Having a depth equal to the array means that we are pointing right before a value.\n"); + printf("# Having a depth smaller than the array means that we have moved beyond the array.\n"); + displayed_hint = true; + } + printf("\n"); + printf("| %-*s ", LOG_EVENT_LEN, "Event"); + printf("| %-*s ", LOG_BUFFER_LEN, "Buffer"); + printf("| %-*s ", LOG_SMALL_BUFFER_LEN, "Next"); + // printf("| %-*s ", 5, "Next#"); + printf("| %-*s ", 5, "Depth"); + printf("| Detail "); + printf("|\n"); + + printf("|%.*s", LOG_EVENT_LEN + 2, DASHES); + printf("|%.*s", LOG_BUFFER_LEN + 2, DASHES); + printf("|%.*s", LOG_SMALL_BUFFER_LEN + 2, DASHES); + // printf("|%.*s", 5+2, DASHES); + printf("|%.*s", 5 + 2, DASHES); + printf("|--------"); + printf("|\n"); + fflush(stdout); + } + } +} + +template +inline void log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta, log_level level, Args&&... args) noexcept { + log_line(iter, iter.position()+delta, depth_t(iter.depth()+depth_delta), title_prefix, title, detail, level, std::forward(args)...); +} + +template +inline void log_line(const json_iterator &iter, token_position index, depth_t depth, const char *title_prefix, const char *title, std::string_view detail, log_level level, Args&&... args) noexcept { + if (LOG_ENABLED) { + if (simdjson_unlikely(should_log(level))) { + const int indent = depth * 2; + const auto buf = iter.token.buf; + auto msg = string_format(title, std::forward(args)...); + printf("| %*s%s%-*s ", indent, "", title_prefix, + LOG_EVENT_LEN - indent - int(strlen(title_prefix)), msg.c_str()); + { + // Print the current structural. + printf("| "); + // Before we begin, the index might point right before the document. + // This could be unsafe, see https://github.com/simdjson/simdjson/discussions/1938 + if (index < iter._root) { + printf("%*s", LOG_BUFFER_LEN, ""); + } else { + auto current_structural = &buf[*index]; + for (int i = 0; i < LOG_BUFFER_LEN; i++) { + printf("%c", printable_char(current_structural[i])); + } + } + printf(" "); + } + { + // Print the next structural. + printf("| "); + auto next_structural = &buf[*(index + 1)]; + for (int i = 0; i < LOG_SMALL_BUFFER_LEN; i++) { + printf("%c", printable_char(next_structural[i])); + } + printf(" "); + } + // printf("| %5u ", *(index+1)); + printf("| %5i ", depth); + printf("| %6.*s ", int(detail.size()), detail.data()); + printf("|\n"); + fflush(stdout); + } + } +} + +} // namespace logger +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H +/* end file simdjson/generic/ondemand/logger-inl.h for westmere */ +/* including simdjson/generic/ondemand/object-inl.h for westmere: #include "simdjson/generic/ondemand/object-inl.h" */ +/* begin file simdjson/generic/ondemand/object-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +simdjson_inline simdjson_result object::find_field_unordered(const std::string_view key) & noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::find_field_unordered(const std::string_view key) && noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_unordered_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::operator[](const std::string_view key) & noexcept { + return find_field_unordered(key); +} +simdjson_inline simdjson_result object::operator[](const std::string_view key) && noexcept { + return std::forward(*this).find_field_unordered(key); +} +simdjson_inline simdjson_result object::find_field(const std::string_view key) & noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} +simdjson_inline simdjson_result object::find_field(const std::string_view key) && noexcept { + bool has_value; + SIMDJSON_TRY( iter.find_field_raw(key).get(has_value) ); + if (!has_value) { + logger::log_line(iter.json_iter(), "ERROR: ", "Cannot find key %.*s", "", -1, 0, logger::log_level::error, static_cast(key.size()), key.data()); + return NO_SUCH_FIELD; + } + return value(iter.child()); +} + +simdjson_inline simdjson_result object::start(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.start_object().error() ); + return object(iter); +} +simdjson_inline simdjson_result object::start_root(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.start_root_object().error() ); + return object(iter); +} +simdjson_inline error_code object::consume() noexcept { + if(iter.is_at_key()) { + /** + * whenever you are pointing at a key, calling skip_child() is + * unsafe because you will hit a string and you will assume that + * it is string value, and this mistake will lead you to make bad + * depth computation. + */ + /** + * We want to 'consume' the key. We could really + * just do _json_iter->return_current_and_advance(); at this + * point, but, for clarity, we will use the high-level API to + * eat the key. We assume that the compiler optimizes away + * most of the work. + */ + simdjson_unused raw_json_string actual_key; + auto error = iter.field_key().get(actual_key); + if (error) { iter.abandon(); return error; }; + // Let us move to the value while we are at it. + if ((error = iter.field_value())) { iter.abandon(); return error; } + } + auto error_skip = iter.json_iter().skip_child(iter.depth()-1); + if(error_skip) { iter.abandon(); } + return error_skip; +} + +simdjson_inline simdjson_result object::raw_json() noexcept { + const uint8_t * starting_point{iter.peek_start()}; + auto error = consume(); + if(error) { return error; } + const uint8_t * final_point{iter._json_iter->peek()}; + return std::string_view(reinterpret_cast(starting_point), size_t(final_point - starting_point)); +} + +simdjson_inline simdjson_result object::started(value_iterator &iter) noexcept { + SIMDJSON_TRY( iter.started_object().error() ); + return object(iter); +} + +simdjson_inline object object::resume(const value_iterator &iter) noexcept { + return iter; +} + +simdjson_inline object::object(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} + +simdjson_inline simdjson_result object::begin() noexcept { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!iter.is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + return object_iterator(iter); +} +simdjson_inline simdjson_result object::end() noexcept { + return object_iterator(iter); +} + +inline simdjson_result object::at_pointer(std::string_view json_pointer) noexcept { + if (json_pointer[0] != '/') { return INVALID_JSON_POINTER; } + json_pointer = json_pointer.substr(1); + size_t slash = json_pointer.find('/'); + std::string_view key = json_pointer.substr(0, slash); + // Grab the child with the given key + simdjson_result child; + + // If there is an escape character in the key, unescape it and then get the child. + size_t escape = key.find('~'); + if (escape != std::string_view::npos) { + // Unescape the key + std::string unescaped(key); + do { + switch (unescaped[escape+1]) { + case '0': + unescaped.replace(escape, 2, "~"); + break; + case '1': + unescaped.replace(escape, 2, "/"); + break; + default: + return INVALID_JSON_POINTER; // "Unexpected ~ escape character in JSON pointer"); + } + escape = unescaped.find('~', escape+1); + } while (escape != std::string::npos); + child = find_field(unescaped); // Take note find_field does not unescape keys when matching + } else { + child = find_field(key); + } + if(child.error()) { + return child; // we do not continue if there was an error + } + // If there is a /, we have to recurse and look up more of the path + if (slash != std::string_view::npos) { + child = child.at_pointer(json_pointer.substr(slash)); + } + return child; +} + +simdjson_inline simdjson_result object::count_fields() & noexcept { + size_t count{0}; + // Important: we do not consume any of the values. + for(simdjson_unused auto v : *this) { count++; } + // The above loop will always succeed, but we want to report errors. + if(iter.error()) { return iter.error(); } + // We need to move back at the start because we expect users to iterate through + // the object after counting the number of elements. + iter.reset_object(); + return count; +} + +simdjson_inline simdjson_result object::is_empty() & noexcept { + bool is_not_empty; + auto error = iter.reset_object().get(is_not_empty); + if(error) { return error; } + return !is_not_empty; +} + +simdjson_inline simdjson_result object::reset() & noexcept { + return iter.reset_object(); +} + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(westmere::ondemand::object &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +simdjson_inline simdjson_result simdjson_result::begin() noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() noexcept { + if (error()) { return error(); } + return first.end(); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first).find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) & noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first)[key]; +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) & noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) && noexcept { + if (error()) { return error(); } + return std::forward(first).find_field(key); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + +inline simdjson_result simdjson_result::reset() noexcept { + if (error()) { return error(); } + return first.reset(); +} + +inline simdjson_result simdjson_result::is_empty() noexcept { + if (error()) { return error(); } + return first.is_empty(); +} + +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H +/* end file simdjson/generic/ondemand/object-inl.h for westmere */ +/* including simdjson/generic/ondemand/object_iterator-inl.h for westmere: #include "simdjson/generic/ondemand/object_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/object_iterator-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/field-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +// +// object_iterator +// + +simdjson_inline object_iterator::object_iterator(const value_iterator &_iter) noexcept + : iter{_iter} +{} + +simdjson_inline simdjson_result object_iterator::operator*() noexcept { + error_code error = iter.error(); + if (error) { iter.abandon(); return error; } + auto result = field::start(iter); + // TODO this is a safety rail ... users should exit loops as soon as they receive an error. + // Nonetheless, let's see if performance is OK with this if statement--the compiler may give it to us for free. + if (result.error()) { iter.abandon(); } + return result; +} +simdjson_inline bool object_iterator::operator==(const object_iterator &other) const noexcept { + return !(*this != other); +} +simdjson_inline bool object_iterator::operator!=(const object_iterator &) const noexcept { + return iter.is_open(); +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline object_iterator &object_iterator::operator++() noexcept { + // TODO this is a safety rail ... users should exit loops as soon as they receive an error. + // Nonetheless, let's see if performance is OK with this if statement--the compiler may give it to us for free. + if (!iter.is_open()) { return *this; } // Iterator will be released if there is an error + + simdjson_unused error_code error; + if ((error = iter.skip_child() )) { return *this; } + + simdjson_unused bool has_value; + if ((error = iter.has_next_field().get(has_value) )) { return *this; }; + return *this; +} +SIMDJSON_POP_DISABLE_WARNINGS + +// +// ### Live States +// +// While iterating or looking up values, depth >= iter.depth. at_start may vary. Error is +// always SUCCESS: +// +// - Start: This is the state when the object is first found and the iterator is just past the {. +// In this state, at_start == true. +// - Next: After we hand a scalar value to the user, or an array/object which they then fully +// iterate over, the iterator is at the , or } before the next value. In this state, +// depth == iter.depth, at_start == false, and error == SUCCESS. +// - Unfinished Business: When we hand an array/object to the user which they do not fully +// iterate over, we need to finish that iteration by skipping child values until we reach the +// Next state. In this state, depth > iter.depth, at_start == false, and error == SUCCESS. +// +// ## Error States +// +// In error states, we will yield exactly one more value before stopping. iter.depth == depth +// and at_start is always false. We decrement after yielding the error, moving to the Finished +// state. +// +// - Chained Error: When the object iterator is part of an error chain--for example, in +// `for (auto tweet : doc["tweets"])`, where the tweet field may be missing or not be an +// object--we yield that error in the loop, exactly once. In this state, error != SUCCESS and +// iter.depth == depth, and at_start == false. We decrement depth when we yield the error. +// - Missing Comma Error: When the iterator ++ method discovers there is no comma between fields, +// we flag that as an error and treat it exactly the same as a Chained Error. In this state, +// error == TAPE_ERROR, iter.depth == depth, and at_start == false. +// +// Errors that occur while reading a field to give to the user (such as when the key is not a +// string or the field is missing a colon) are yielded immediately. Depth is then decremented, +// moving to the Finished state without transitioning through an Error state at all. +// +// ## Terminal State +// +// The terminal state has iter.depth < depth. at_start is always false. +// +// - Finished: When we have reached a }, we are finished. We signal this by decrementing depth. +// In this state, iter.depth < depth, at_start == false, and error == SUCCESS. +// + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + westmere::ondemand::object_iterator &&value +) noexcept + : implementation_simdjson_result_base(std::forward(value)) +{ + first.iter.assert_is_valid(); +} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base({}, error) +{ +} + +simdjson_inline simdjson_result simdjson_result::operator*() noexcept { + if (error()) { return error(); } + return *first; +} +// If we're iterating and there is an error, return the error once. +simdjson_inline bool simdjson_result::operator==(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return !error(); } + return first == other.first; +} +// If we're iterating and there is an error, return the error once. +simdjson_inline bool simdjson_result::operator!=(const simdjson_result &other) const noexcept { + if (!first.iter.is_valid()) { return error(); } + return first != other.first; +} +// Checks for ']' and ',' +simdjson_inline simdjson_result &simdjson_result::operator++() noexcept { + // Clear the error if there is one, so we don't yield it twice + if (error()) { second = SUCCESS; return *this; } + ++first; + return *this; +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/object_iterator-inl.h for westmere */ +/* including simdjson/generic/ondemand/parser-inl.h for westmere: #include "simdjson/generic/ondemand/parser-inl.h" */ +/* begin file simdjson/generic/ondemand/parser-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/padded_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/padded_string_view.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/internal/dom_parser_implementation.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/dom/base.h" // for MINIMAL_DOCUMENT_CAPACITY */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document_stream.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/parser.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +simdjson_inline parser::parser(size_t max_capacity) noexcept + : _max_capacity{max_capacity} { +} + +simdjson_warn_unused simdjson_inline error_code parser::allocate(size_t new_capacity, size_t new_max_depth) noexcept { + if (new_capacity > max_capacity()) { return CAPACITY; } + if (string_buf && new_capacity == capacity() && new_max_depth == max_depth()) { return SUCCESS; } + + // string_capacity copied from document::allocate + _capacity = 0; + size_t string_capacity = SIMDJSON_ROUNDUP_N(5 * new_capacity / 3 + SIMDJSON_PADDING, 64); + string_buf.reset(new (std::nothrow) uint8_t[string_capacity]); +#if SIMDJSON_DEVELOPMENT_CHECKS + start_positions.reset(new (std::nothrow) token_position[new_max_depth]); +#endif + if (implementation) { + SIMDJSON_TRY( implementation->set_capacity(new_capacity) ); + SIMDJSON_TRY( implementation->set_max_depth(new_max_depth) ); + } else { + SIMDJSON_TRY( simdjson::get_active_implementation()->create_dom_parser_implementation(new_capacity, new_max_depth, implementation) ); + } + _capacity = new_capacity; + _max_depth = new_max_depth; + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(padded_string_view json) & noexcept { + if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; } + + json.remove_utf8_bom(); + + // Allocate if needed + if (capacity() < json.length() || !string_buf) { + SIMDJSON_TRY( allocate(json.length(), max_depth()) ); + } + + // Run stage 1. + SIMDJSON_TRY( implementation->stage1(reinterpret_cast(json.data()), json.length(), stage1_mode::regular) ); + return document::start({ reinterpret_cast(json.data()), this }); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const char *json, size_t len, size_t allocated) & noexcept { + return iterate(padded_string_view(json, len, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const uint8_t *json, size_t len, size_t allocated) & noexcept { + return iterate(padded_string_view(json, len, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(std::string_view json, size_t allocated) & noexcept { + return iterate(padded_string_view(json, allocated)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(std::string &json) & noexcept { + if(json.capacity() - json.size() < SIMDJSON_PADDING) { + json.reserve(json.size() + SIMDJSON_PADDING); + } + return iterate(padded_string_view(json)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const std::string &json) & noexcept { + return iterate(padded_string_view(json)); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const simdjson_result &result) & noexcept { + // We don't presently have a way to temporarily get a const T& from a simdjson_result without throwing an exception + SIMDJSON_TRY( result.error() ); + padded_string_view json = result.value_unsafe(); + return iterate(json); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate(const simdjson_result &result) & noexcept { + // We don't presently have a way to temporarily get a const T& from a simdjson_result without throwing an exception + SIMDJSON_TRY( result.error() ); + const padded_string &json = result.value_unsafe(); + return iterate(json); +} + +simdjson_warn_unused simdjson_inline simdjson_result parser::iterate_raw(padded_string_view json) & noexcept { + if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; } + + json.remove_utf8_bom(); + + // Allocate if needed + if (capacity() < json.length()) { + SIMDJSON_TRY( allocate(json.length(), max_depth()) ); + } + + // Run stage 1. + SIMDJSON_TRY( implementation->stage1(reinterpret_cast(json.data()), json.length(), stage1_mode::regular) ); + return json_iterator(reinterpret_cast(json.data()), this); +} + +inline simdjson_result parser::iterate_many(const uint8_t *buf, size_t len, size_t batch_size, bool allow_comma_separated) noexcept { + if(batch_size < MINIMAL_BATCH_SIZE) { batch_size = MINIMAL_BATCH_SIZE; } + if((len >= 3) && (std::memcmp(buf, "\xEF\xBB\xBF", 3) == 0)) { + buf += 3; + len -= 3; + } + if(allow_comma_separated && batch_size < len) { batch_size = len; } + return document_stream(*this, buf, len, batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const char *buf, size_t len, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(reinterpret_cast(buf), len, batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const std::string &s, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(s.data(), s.length(), batch_size, allow_comma_separated); +} +inline simdjson_result parser::iterate_many(const padded_string &s, size_t batch_size, bool allow_comma_separated) noexcept { + return iterate_many(s.data(), s.length(), batch_size, allow_comma_separated); +} + +simdjson_inline size_t parser::capacity() const noexcept { + return _capacity; +} +simdjson_inline size_t parser::max_capacity() const noexcept { + return _max_capacity; +} +simdjson_inline size_t parser::max_depth() const noexcept { + return _max_depth; +} + +simdjson_inline void parser::set_max_capacity(size_t max_capacity) noexcept { + if(max_capacity < dom::MINIMAL_DOCUMENT_CAPACITY) { + _max_capacity = max_capacity; + } else { + _max_capacity = dom::MINIMAL_DOCUMENT_CAPACITY; + } +} + +simdjson_inline simdjson_warn_unused simdjson_result parser::unescape(raw_json_string in, uint8_t *&dst, bool allow_replacement) const noexcept { + uint8_t *end = implementation->parse_string(in.buf, dst, allow_replacement); + if (!end) { return STRING_ERROR; } + std::string_view result(reinterpret_cast(dst), end-dst); + dst = end; + return result; +} + +simdjson_inline simdjson_warn_unused simdjson_result parser::unescape_wobbly(raw_json_string in, uint8_t *&dst) const noexcept { + uint8_t *end = implementation->parse_wobbly_string(in.buf, dst); + if (!end) { return STRING_ERROR; } + std::string_view result(reinterpret_cast(dst), end-dst); + dst = end; + return result; +} + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(westmere::ondemand::parser &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H +/* end file simdjson/generic/ondemand/parser-inl.h for westmere */ +/* including simdjson/generic/ondemand/raw_json_string-inl.h for westmere: #include "simdjson/generic/ondemand/raw_json_string-inl.h" */ +/* begin file simdjson/generic/ondemand/raw_json_string-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +namespace westmere { +namespace ondemand { + +simdjson_inline raw_json_string::raw_json_string(const uint8_t * _buf) noexcept : buf{_buf} {} + +simdjson_inline const char * raw_json_string::raw() const noexcept { return reinterpret_cast(buf); } + + +simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(std::string_view target) noexcept { + size_t pos{0}; + // if the content has no escape character, just scan through it quickly! + for(;pos < target.size() && target[pos] != '\\';pos++) {} + // slow path may begin. + bool escaping{false}; + for(;pos < target.size();pos++) { + if((target[pos] == '"') && !escaping) { + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + return true; +} + +simdjson_inline bool raw_json_string::is_free_from_unescaped_quote(const char* target) noexcept { + size_t pos{0}; + // if the content has no escape character, just scan through it quickly! + for(;target[pos] && target[pos] != '\\';pos++) {} + // slow path may begin. + bool escaping{false}; + for(;target[pos];pos++) { + if((target[pos] == '"') && !escaping) { + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + return true; +} + + +simdjson_inline bool raw_json_string::unsafe_is_equal(size_t length, std::string_view target) const noexcept { + // If we are going to call memcmp, then we must know something about the length of the raw_json_string. + return (length >= target.size()) && (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size()); +} + +simdjson_inline bool raw_json_string::unsafe_is_equal(std::string_view target) const noexcept { + // Assumptions: does not contain unescaped quote characters, and + // the raw content is quote terminated within a valid JSON string. + if(target.size() <= SIMDJSON_PADDING) { + return (raw()[target.size()] == '"') && !memcmp(raw(), target.data(), target.size()); + } + const char * r{raw()}; + size_t pos{0}; + for(;pos < target.size();pos++) { + if(r[pos] != target[pos]) { return false; } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_inline bool raw_json_string::is_equal(std::string_view target) const noexcept { + const char * r{raw()}; + size_t pos{0}; + bool escaping{false}; + for(;pos < target.size();pos++) { + if(r[pos] != target[pos]) { return false; } + // if target is a compile-time constant and it is free from + // quotes, then the next part could get optimized away through + // inlining. + if((target[pos] == '"') && !escaping) { + // We have reached the end of the raw_json_string but + // the target is not done. + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + if(r[pos] != '"') { return false; } + return true; +} + + +simdjson_inline bool raw_json_string::unsafe_is_equal(const char * target) const noexcept { + // Assumptions: 'target' does not contain unescaped quote characters, is null terminated and + // the raw content is quote terminated within a valid JSON string. + const char * r{raw()}; + size_t pos{0}; + for(;target[pos];pos++) { + if(r[pos] != target[pos]) { return false; } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_inline bool raw_json_string::is_equal(const char* target) const noexcept { + // Assumptions: does not contain unescaped quote characters, and + // the raw content is quote terminated within a valid JSON string. + const char * r{raw()}; + size_t pos{0}; + bool escaping{false}; + for(;target[pos];pos++) { + if(r[pos] != target[pos]) { return false; } + // if target is a compile-time constant and it is free from + // quotes, then the next part could get optimized away through + // inlining. + if((target[pos] == '"') && !escaping) { + // We have reached the end of the raw_json_string but + // the target is not done. + return false; + } else if(target[pos] == '\\') { + escaping = !escaping; + } else { + escaping = false; + } + } + if(r[pos] != '"') { return false; } + return true; +} + +simdjson_unused simdjson_inline bool operator==(const raw_json_string &a, std::string_view c) noexcept { + return a.unsafe_is_equal(c); +} + +simdjson_unused simdjson_inline bool operator==(std::string_view c, const raw_json_string &a) noexcept { + return a == c; +} + +simdjson_unused simdjson_inline bool operator!=(const raw_json_string &a, std::string_view c) noexcept { + return !(a == c); +} + +simdjson_unused simdjson_inline bool operator!=(std::string_view c, const raw_json_string &a) noexcept { + return !(a == c); +} + + +simdjson_inline simdjson_warn_unused simdjson_result raw_json_string::unescape(json_iterator &iter, bool allow_replacement) const noexcept { + return iter.unescape(*this, allow_replacement); +} + +simdjson_inline simdjson_warn_unused simdjson_result raw_json_string::unescape_wobbly(json_iterator &iter) const noexcept { + return iter.unescape_wobbly(*this); +} + +simdjson_unused simdjson_inline std::ostream &operator<<(std::ostream &out, const raw_json_string &str) noexcept { + bool in_escape = false; + const char *s = str.raw(); + while (true) { + switch (*s) { + case '\\': in_escape = !in_escape; break; + case '"': if (in_escape) { in_escape = false; } else { return out; } break; + default: if (in_escape) { in_escape = false; } + } + out << *s; + s++; + } +} + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(westmere::ondemand::raw_json_string &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +simdjson_inline simdjson_result simdjson_result::raw() const noexcept { + if (error()) { return error(); } + return first.raw(); +} +simdjson_inline simdjson_warn_unused simdjson_result simdjson_result::unescape(westmere::ondemand::json_iterator &iter, bool allow_replacement) const noexcept { + if (error()) { return error(); } + return first.unescape(iter, allow_replacement); +} +simdjson_inline simdjson_warn_unused simdjson_result simdjson_result::unescape_wobbly(westmere::ondemand::json_iterator &iter) const noexcept { + if (error()) { return error(); } + return first.unescape_wobbly(iter); +} +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H +/* end file simdjson/generic/ondemand/raw_json_string-inl.h for westmere */ +/* including simdjson/generic/ondemand/serialization-inl.h for westmere: #include "simdjson/generic/ondemand/serialization-inl.h" */ +/* begin file simdjson/generic/ondemand/serialization-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/document-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/serialization.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { + +inline std::string_view trim(const std::string_view str) noexcept { + // We can almost surely do better by rolling our own find_first_not_of function. + size_t first = str.find_first_not_of(" \t\n\r"); + // If we have the empty string (just white space), then no trimming is possible, and + // we return the empty string_view. + if (std::string_view::npos == first) { return std::string_view(); } + size_t last = str.find_last_not_of(" \t\n\r"); + return str.substr(first, (last - first + 1)); +} + + +inline simdjson_result to_json_string(westmere::ondemand::document& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(westmere::ondemand::document_reference& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(westmere::ondemand::value& x) noexcept { + /** + * If we somehow receive a value that has already been consumed, + * then the following code could be in trouble. E.g., we create + * an array as needed, but if an array was already created, then + * it could be bad. + */ + using namespace westmere::ondemand; + westmere::ondemand::json_type t; + auto error = x.type().get(t); + if(error != SUCCESS) { return error; } + switch (t) + { + case json_type::array: + { + westmere::ondemand::array array; + error = x.get_array().get(array); + if(error) { return error; } + return to_json_string(array); + } + case json_type::object: + { + westmere::ondemand::object object; + error = x.get_object().get(object); + if(error) { return error; } + return to_json_string(object); + } + default: + return trim(x.raw_json_token()); + } +} + +inline simdjson_result to_json_string(westmere::ondemand::object& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(westmere::ondemand::array& x) noexcept { + std::string_view v; + auto error = x.raw_json().get(v); + if(error) {return error; } + return trim(v); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} + +inline simdjson_result to_json_string(simdjson_result x) { + if (x.error()) { return x.error(); } + return to_json_string(x.value_unsafe()); +} +} // namespace simdjson + +namespace simdjson { namespace westmere { namespace ondemand { + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::westmere::ondemand::value x) { + std::string_view v; + auto error = simdjson::to_json_string(x).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::westmere::ondemand::value x) { + std::string_view v; + auto error = simdjson::to_json_string(x).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::westmere::ondemand::array value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::westmere::ondemand::array value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::westmere::ondemand::document& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::westmere::ondemand::document_reference& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result&& x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::westmere::ondemand::document& value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif + +#if SIMDJSON_EXCEPTIONS +inline std::ostream& operator<<(std::ostream& out, simdjson::westmere::ondemand::object value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + throw simdjson::simdjson_error(error); + } +} +inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result x) { + if (x.error()) { throw simdjson::simdjson_error(x.error()); } + return (out << x.value()); +} +#else +inline std::ostream& operator<<(std::ostream& out, simdjson::westmere::ondemand::object value) { + std::string_view v; + auto error = simdjson::to_json_string(value).get(v); + if(error == simdjson::SUCCESS) { + return (out << v); + } else { + return (out << error); + } +} +#endif +}}} // namespace simdjson::westmere::ondemand + +#endif // SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H +/* end file simdjson/generic/ondemand/serialization-inl.h for westmere */ +/* including simdjson/generic/ondemand/token_iterator-inl.h for westmere: #include "simdjson/generic/ondemand/token_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/token_iterator-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/token_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/implementation_simdjson_result_base-inl.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +simdjson_inline token_iterator::token_iterator( + const uint8_t *_buf, + token_position position +) noexcept : buf{_buf}, _position{position} +{ +} + +simdjson_inline uint32_t token_iterator::current_offset() const noexcept { + return *(_position); +} + + +simdjson_inline const uint8_t *token_iterator::return_current_and_advance() noexcept { + return &buf[*(_position++)]; +} + +simdjson_inline const uint8_t *token_iterator::peek(token_position position) const noexcept { + return &buf[*position]; +} +simdjson_inline uint32_t token_iterator::peek_index(token_position position) const noexcept { + return *position; +} +simdjson_inline uint32_t token_iterator::peek_length(token_position position) const noexcept { + return *(position+1) - *position; +} + +simdjson_inline const uint8_t *token_iterator::peek(int32_t delta) const noexcept { + return &buf[*(_position+delta)]; +} +simdjson_inline uint32_t token_iterator::peek_index(int32_t delta) const noexcept { + return *(_position+delta); +} +simdjson_inline uint32_t token_iterator::peek_length(int32_t delta) const noexcept { + return *(_position+delta+1) - *(_position+delta); +} + +simdjson_inline token_position token_iterator::position() const noexcept { + return _position; +} +simdjson_inline void token_iterator::set_position(token_position target_position) noexcept { + _position = target_position; +} + +simdjson_inline bool token_iterator::operator==(const token_iterator &other) const noexcept { + return _position == other._position; +} +simdjson_inline bool token_iterator::operator!=(const token_iterator &other) const noexcept { + return _position != other._position; +} +simdjson_inline bool token_iterator::operator>(const token_iterator &other) const noexcept { + return _position > other._position; +} +simdjson_inline bool token_iterator::operator>=(const token_iterator &other) const noexcept { + return _position >= other._position; +} +simdjson_inline bool token_iterator::operator<(const token_iterator &other) const noexcept { + return _position < other._position; +} +simdjson_inline bool token_iterator::operator<=(const token_iterator &other) const noexcept { + return _position <= other._position; +} + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(westmere::ondemand::token_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/token_iterator-inl.h for westmere */ +/* including simdjson/generic/ondemand/value-inl.h for westmere: #include "simdjson/generic/ondemand/value-inl.h" */ +/* begin file simdjson/generic/ondemand/value-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/array_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/object.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +simdjson_inline value::value(const value_iterator &_iter) noexcept + : iter{_iter} +{ +} +simdjson_inline value value::start(const value_iterator &iter) noexcept { + return iter; +} +simdjson_inline value value::resume(const value_iterator &iter) noexcept { + return iter; +} + +simdjson_inline simdjson_result value::get_array() noexcept { + return array::start(iter); +} +simdjson_inline simdjson_result value::get_object() noexcept { + return object::start(iter); +} +simdjson_inline simdjson_result value::start_or_resume_object() noexcept { + if (iter.at_start()) { + return get_object(); + } else { + return object::resume(iter); + } +} + +simdjson_inline simdjson_result value::get_raw_json_string() noexcept { + return iter.get_raw_json_string(); +} +simdjson_inline simdjson_result value::get_string(bool allow_replacement) noexcept { + return iter.get_string(allow_replacement); +} +template +simdjson_inline error_code value::get_string(string_type& receiver, bool allow_replacement) noexcept { + return iter.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result value::get_wobbly_string() noexcept { + return iter.get_wobbly_string(); +} +simdjson_inline simdjson_result value::get_double() noexcept { + return iter.get_double(); +} +simdjson_inline simdjson_result value::get_double_in_string() noexcept { + return iter.get_double_in_string(); +} +simdjson_inline simdjson_result value::get_uint64() noexcept { + return iter.get_uint64(); +} +simdjson_inline simdjson_result value::get_uint64_in_string() noexcept { + return iter.get_uint64_in_string(); +} +simdjson_inline simdjson_result value::get_int64() noexcept { + return iter.get_int64(); +} +simdjson_inline simdjson_result value::get_int64_in_string() noexcept { + return iter.get_int64_in_string(); +} +simdjson_inline simdjson_result value::get_bool() noexcept { + return iter.get_bool(); +} +simdjson_inline simdjson_result value::is_null() noexcept { + return iter.is_null(); +} +template<> simdjson_inline simdjson_result value::get() noexcept { return get_array(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_object(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_raw_json_string(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_string(false); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_number(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_double(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_uint64(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_int64(); } +template<> simdjson_inline simdjson_result value::get() noexcept { return get_bool(); } + +template simdjson_inline error_code value::get(T &out) noexcept { + return get().get(out); +} + +#if SIMDJSON_EXCEPTIONS +simdjson_inline value::operator array() noexcept(false) { + return get_array(); +} +simdjson_inline value::operator object() noexcept(false) { + return get_object(); +} +simdjson_inline value::operator uint64_t() noexcept(false) { + return get_uint64(); +} +simdjson_inline value::operator int64_t() noexcept(false) { + return get_int64(); +} +simdjson_inline value::operator double() noexcept(false) { + return get_double(); +} +simdjson_inline value::operator std::string_view() noexcept(false) { + return get_string(false); +} +simdjson_inline value::operator raw_json_string() noexcept(false) { + return get_raw_json_string(); +} +simdjson_inline value::operator bool() noexcept(false) { + return get_bool(); +} +#endif + +simdjson_inline simdjson_result value::begin() & noexcept { + return get_array().begin(); +} +simdjson_inline simdjson_result value::end() & noexcept { + return {}; +} +simdjson_inline simdjson_result value::count_elements() & noexcept { + simdjson_result answer; + auto a = get_array(); + answer = a.count_elements(); + // count_elements leaves you pointing inside the array, at the first element. + // We need to move back so that the user can create a new array (which requires that + // we point at '['). + iter.move_at_start(); + return answer; +} +simdjson_inline simdjson_result value::count_fields() & noexcept { + simdjson_result answer; + auto a = get_object(); + answer = a.count_fields(); + iter.move_at_start(); + return answer; +} +simdjson_inline simdjson_result value::at(size_t index) noexcept { + auto a = get_array(); + return a.at(index); +} + +simdjson_inline simdjson_result value::find_field(std::string_view key) noexcept { + return start_or_resume_object().find_field(key); +} +simdjson_inline simdjson_result value::find_field(const char *key) noexcept { + return start_or_resume_object().find_field(key); +} + +simdjson_inline simdjson_result value::find_field_unordered(std::string_view key) noexcept { + return start_or_resume_object().find_field_unordered(key); +} +simdjson_inline simdjson_result value::find_field_unordered(const char *key) noexcept { + return start_or_resume_object().find_field_unordered(key); +} + +simdjson_inline simdjson_result value::operator[](std::string_view key) noexcept { + return start_or_resume_object()[key]; +} +simdjson_inline simdjson_result value::operator[](const char *key) noexcept { + return start_or_resume_object()[key]; +} + +simdjson_inline simdjson_result value::type() noexcept { + return iter.type(); +} + +simdjson_inline simdjson_result value::is_scalar() noexcept { + json_type this_type; + auto error = type().get(this_type); + if(error) { return error; } + return ! ((this_type == json_type::array) || (this_type == json_type::object)); +} + +simdjson_inline bool value::is_negative() noexcept { + return iter.is_negative(); +} + +simdjson_inline simdjson_result value::is_integer() noexcept { + return iter.is_integer(); +} +simdjson_warn_unused simdjson_inline simdjson_result value::get_number_type() noexcept { + return iter.get_number_type(); +} +simdjson_warn_unused simdjson_inline simdjson_result value::get_number() noexcept { + return iter.get_number(); +} + +simdjson_inline std::string_view value::raw_json_token() noexcept { + return std::string_view(reinterpret_cast(iter.peek_start()), iter.peek_start_length()); +} + +simdjson_inline simdjson_result value::raw_json() noexcept { + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: { + ondemand::array array; + SIMDJSON_TRY(get_array().get(array)); + return array.raw_json(); + } + case json_type::object: { + ondemand::object object; + SIMDJSON_TRY(get_object().get(object)); + return object.raw_json(); + } + default: + return raw_json_token(); + } +} + +simdjson_inline simdjson_result value::current_location() noexcept { + return iter.json_iter().current_location(); +} + +simdjson_inline int32_t value::current_depth() const noexcept{ + return iter.json_iter().depth(); +} + +simdjson_inline simdjson_result value::at_pointer(std::string_view json_pointer) noexcept { + json_type t; + SIMDJSON_TRY(type().get(t)); + switch (t) + { + case json_type::array: + return (*this).get_array().at_pointer(json_pointer); + case json_type::object: + return (*this).get_object().at_pointer(json_pointer); + default: + return INVALID_JSON_POINTER; + } +} + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result( + westmere::ondemand::value &&value +) noexcept : + implementation_simdjson_result_base( + std::forward(value) + ) +{ +} +simdjson_inline simdjson_result::simdjson_result( + error_code error +) noexcept : + implementation_simdjson_result_base(error) +{ +} +simdjson_inline simdjson_result simdjson_result::count_elements() & noexcept { + if (error()) { return error(); } + return first.count_elements(); +} +simdjson_inline simdjson_result simdjson_result::count_fields() & noexcept { + if (error()) { return error(); } + return first.count_fields(); +} +simdjson_inline simdjson_result simdjson_result::at(size_t index) noexcept { + if (error()) { return error(); } + return first.at(index); +} +simdjson_inline simdjson_result simdjson_result::begin() & noexcept { + if (error()) { return error(); } + return first.begin(); +} +simdjson_inline simdjson_result simdjson_result::end() & noexcept { + if (error()) { return error(); } + return {}; +} + +simdjson_inline simdjson_result simdjson_result::find_field(std::string_view key) noexcept { + if (error()) { return error(); } + return first.find_field(key); +} +simdjson_inline simdjson_result simdjson_result::find_field(const char *key) noexcept { + if (error()) { return error(); } + return first.find_field(key); +} + +simdjson_inline simdjson_result simdjson_result::find_field_unordered(std::string_view key) noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} +simdjson_inline simdjson_result simdjson_result::find_field_unordered(const char *key) noexcept { + if (error()) { return error(); } + return first.find_field_unordered(key); +} + +simdjson_inline simdjson_result simdjson_result::operator[](std::string_view key) noexcept { + if (error()) { return error(); } + return first[key]; +} +simdjson_inline simdjson_result simdjson_result::operator[](const char *key) noexcept { + if (error()) { return error(); } + return first[key]; +} + +simdjson_inline simdjson_result simdjson_result::get_array() noexcept { + if (error()) { return error(); } + return first.get_array(); +} +simdjson_inline simdjson_result simdjson_result::get_object() noexcept { + if (error()) { return error(); } + return first.get_object(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64() noexcept { + if (error()) { return error(); } + return first.get_uint64(); +} +simdjson_inline simdjson_result simdjson_result::get_uint64_in_string() noexcept { + if (error()) { return error(); } + return first.get_uint64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_int64() noexcept { + if (error()) { return error(); } + return first.get_int64(); +} +simdjson_inline simdjson_result simdjson_result::get_int64_in_string() noexcept { + if (error()) { return error(); } + return first.get_int64_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_double() noexcept { + if (error()) { return error(); } + return first.get_double(); +} +simdjson_inline simdjson_result simdjson_result::get_double_in_string() noexcept { + if (error()) { return error(); } + return first.get_double_in_string(); +} +simdjson_inline simdjson_result simdjson_result::get_string(bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(allow_replacement); +} +template +simdjson_inline error_code simdjson_result::get_string(string_type& receiver, bool allow_replacement) noexcept { + if (error()) { return error(); } + return first.get_string(receiver, allow_replacement); +} +simdjson_inline simdjson_result simdjson_result::get_wobbly_string() noexcept { + if (error()) { return error(); } + return first.get_wobbly_string(); +} +simdjson_inline simdjson_result simdjson_result::get_raw_json_string() noexcept { + if (error()) { return error(); } + return first.get_raw_json_string(); +} +simdjson_inline simdjson_result simdjson_result::get_bool() noexcept { + if (error()) { return error(); } + return first.get_bool(); +} +simdjson_inline simdjson_result simdjson_result::is_null() noexcept { + if (error()) { return error(); } + return first.is_null(); +} + +template simdjson_inline simdjson_result simdjson_result::get() noexcept { + if (error()) { return error(); } + return first.get(); +} +template simdjson_inline error_code simdjson_result::get(T &out) noexcept { + if (error()) { return error(); } + return first.get(out); +} + +template<> simdjson_inline simdjson_result simdjson_result::get() noexcept { + if (error()) { return error(); } + return std::move(first); +} +template<> simdjson_inline error_code simdjson_result::get(westmere::ondemand::value &out) noexcept { + if (error()) { return error(); } + out = first; + return SUCCESS; +} + +simdjson_inline simdjson_result simdjson_result::type() noexcept { + if (error()) { return error(); } + return first.type(); +} +simdjson_inline simdjson_result simdjson_result::is_scalar() noexcept { + if (error()) { return error(); } + return first.is_scalar(); +} +simdjson_inline simdjson_result simdjson_result::is_negative() noexcept { + if (error()) { return error(); } + return first.is_negative(); +} +simdjson_inline simdjson_result simdjson_result::is_integer() noexcept { + if (error()) { return error(); } + return first.is_integer(); +} +simdjson_inline simdjson_result simdjson_result::get_number_type() noexcept { + if (error()) { return error(); } + return first.get_number_type(); +} +simdjson_inline simdjson_result simdjson_result::get_number() noexcept { + if (error()) { return error(); } + return first.get_number(); +} +#if SIMDJSON_EXCEPTIONS +simdjson_inline simdjson_result::operator westmere::ondemand::array() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator westmere::ondemand::object() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator uint64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator int64_t() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator double() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator std::string_view() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator westmere::ondemand::raw_json_string() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +simdjson_inline simdjson_result::operator bool() noexcept(false) { + if (error()) { throw simdjson_error(error()); } + return first; +} +#endif + +simdjson_inline simdjson_result simdjson_result::raw_json_token() noexcept { + if (error()) { return error(); } + return first.raw_json_token(); +} + +simdjson_inline simdjson_result simdjson_result::raw_json() noexcept { + if (error()) { return error(); } + return first.raw_json(); +} + +simdjson_inline simdjson_result simdjson_result::current_location() noexcept { + if (error()) { return error(); } + return first.current_location(); +} + +simdjson_inline simdjson_result simdjson_result::current_depth() const noexcept { + if (error()) { return error(); } + return first.current_depth(); +} + +simdjson_inline simdjson_result simdjson_result::at_pointer(std::string_view json_pointer) noexcept { + if (error()) { return error(); } + return first.at_pointer(json_pointer); +} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H +/* end file simdjson/generic/ondemand/value-inl.h for westmere */ +/* including simdjson/generic/ondemand/value_iterator-inl.h for westmere: #include "simdjson/generic/ondemand/value_iterator-inl.h" */ +/* begin file simdjson/generic/ondemand/value_iterator-inl.h for westmere */ +#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H + +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #define SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/base.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/atomparsing.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/numberparsing.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_iterator.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/json_type-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/raw_json_string-inl.h" */ +/* amalgamation skipped (editor-only): #include "simdjson/generic/ondemand/value_iterator.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +namespace simdjson { +namespace westmere { +namespace ondemand { + +simdjson_inline value_iterator::value_iterator( + json_iterator *json_iter, + depth_t depth, + token_position start_position +) noexcept : _json_iter{json_iter}, _depth{depth}, _start_position{start_position} +{ +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_object() noexcept { + SIMDJSON_TRY( start_container('{', "Not an object", "object") ); + return started_object(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_root_object() noexcept { + SIMDJSON_TRY( start_container('{', "Not an object", "object") ); + return started_root_object(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_object() noexcept { + assert_at_container_start(); +#if SIMDJSON_DEVELOPMENT_CHECKS + _json_iter->set_start_position(_depth, start_position()); +#endif + if (*_json_iter->peek() == '}') { + logger::log_value(*_json_iter, "empty object"); + _json_iter->return_current_and_advance(); + end_container(); + return false; + } + return true; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::check_root_object() noexcept { + // When in streaming mode, we cannot expect peek_last() to be the last structural element of the + // current document. It only works in the normal mode where we have indexed a single document. + // Note that adding a check for 'streaming' is not expensive since we only have at most + // one root element. + if ( ! _json_iter->streaming() ) { + // The following lines do not fully protect against garbage content within the + // object: e.g., `{"a":2} foo }`. Users concerned with garbage content should + // call `at_end()` on the document instance at the end of the processing to + // ensure that the processing has finished at the end. + // + if (*_json_iter->peek_last() != '}') { + _json_iter->abandon(); + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing } at end"); + } + // If the last character is } *and* the first gibberish character is also '}' + // then on-demand could accidentally go over. So we need additional checks. + // https://github.com/simdjson/simdjson/issues/1834 + // Checking that the document is balanced requires a full scan which is potentially + // expensive, but it only happens in edge cases where the first padding character is + // a closing bracket. + if ((*_json_iter->peek(_json_iter->end_position()) == '}') && (!_json_iter->balanced())) { + _json_iter->abandon(); + // The exact error would require more work. It will typically be an unclosed object. + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "the document is unbalanced"); + } + } + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_root_object() noexcept { + auto error = check_root_object(); + if(error) { return error; } + return started_object(); +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::end_container() noexcept { +#if SIMDJSON_CHECK_EOF + if (depth() > 1 && at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing parent ] or }"); } + // if (depth() <= 1 && !at_end()) { return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing [ or { at start"); } +#endif // SIMDJSON_CHECK_EOF + _json_iter->ascend_to(depth()-1); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::has_next_field() noexcept { + assert_at_next(); + + // It's illegal to call this unless there are more tokens: anything that ends in } or ] is + // obligated to verify there are more tokens if they are not the top level. + switch (*_json_iter->return_current_and_advance()) { + case '}': + logger::log_end_value(*_json_iter, "object"); + SIMDJSON_TRY( end_container() ); + return false; + case ',': + return true; + default: + return report_error(TAPE_ERROR, "Missing comma between object fields"); + } +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::find_field_raw(const std::string_view key) noexcept { + error_code error; + bool has_value; + // + // Initially, the object can be in one of a few different places: + // + // 1. The start of the object, at the first field: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2, index 1) + // ``` + if (at_first_field()) { + has_value = true; + + // + // 2. When a previous search did not yield a value or the object is empty: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // { } + // ^ (depth 0, index 2) + // ``` + // + } else if (!is_open()) { +#if SIMDJSON_DEVELOPMENT_CHECKS + // If we're past the end of the object, we're being iterated out of order. + // Note: this isn't perfect detection. It's possible the user is inside some other object; if so, + // this object iterator will blithely scan that object for fields. + if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; } +#endif + return false; + + // 3. When a previous search found a field or an iterator yielded a value: + // + // ``` + // // When a field was not fully consumed (or not even touched at all) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2) + // // When a field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // When the last field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // ``` + // + } else { + if ((error = skip_child() )) { abandon(); return error; } + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } +#if SIMDJSON_DEVELOPMENT_CHECKS + if (_json_iter->start_position(_depth) != start_position()) { return OUT_OF_ORDER_ITERATION; } +#endif + } + while (has_value) { + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + if ((error = field_key().get(actual_key) )) { abandon(); return error; }; + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + if ((error = field_value() )) { abandon(); return error; } + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + //if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); // Skip the value entirely + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } + } + + // If the loop ended, we're out of fields to look at. + return false; +} + +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::find_field_unordered_raw(const std::string_view key) noexcept { + /** + * When find_field_unordered_raw is called, we can either be pointing at the + * first key, pointing outside (at the closing brace) or if a key was matched + * we can be either pointing right afterthe ':' right before the value (that we need skip), + * or we may have consumed the value and we might be at a comma or at the + * final brace (ready for a call to has_next_field()). + */ + error_code error; + bool has_value; + + // First, we scan from that point to the end. + // If we don't find a match, we may loop back around, and scan from the beginning to that point. + token_position search_start = _json_iter->position(); + + // We want to know whether we need to go back to the beginning. + bool at_first = at_first_field(); + /////////////// + // Initially, the object can be in one of a few different places: + // + // 1. At the first key: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2, index 1) + // ``` + // + if (at_first) { + has_value = true; + + // 2. When a previous search did not yield a value or the object is empty: + // + // ``` + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // { } + // ^ (depth 0, index 2) + // ``` + // + } else if (!is_open()) { + +#if SIMDJSON_DEVELOPMENT_CHECKS + // If we're past the end of the object, we're being iterated out of order. + // Note: this isn't perfect detection. It's possible the user is inside some other object; if so, + // this object iterator will blithely scan that object for fields. + if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; } +#endif + SIMDJSON_TRY(reset_object().get(has_value)); + at_first = true; + // 3. When a previous search found a field or an iterator yielded a value: + // + // ``` + // // When a field was not fully consumed (or not even touched at all) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 2) + // // When a field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // When the last field was fully consumed + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // ``` + // + } else { + // If someone queried a key but they not did access the value, then we are left pointing + // at the ':' and we need to move forward through the value... If the value was + // processed then skip_child() does not move the iterator (but may adjust the depth). + if ((error = skip_child() )) { abandon(); return error; } + search_start = _json_iter->position(); + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } +#if SIMDJSON_DEVELOPMENT_CHECKS + if (_json_iter->start_position(_depth) != start_position()) { return OUT_OF_ORDER_ITERATION; } +#endif + } + + // After initial processing, we will be in one of two states: + // + // ``` + // // At the beginning of a field + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 1) + // // At the end of the object + // { "a": [ 1, 2 ], "b": [ 3, 4 ] } + // ^ (depth 0) + // ``` + // + // Next, we find a match starting from the current position. + while (has_value) { + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); // We must be at the start of a field + + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + if ((error = field_key().get(actual_key) )) { abandon(); return error; }; + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + if ((error = field_value() )) { abandon(); return error; } + + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + // if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + if ((error = has_next_field().get(has_value) )) { abandon(); return error; } + } + // Performance note: it maybe wasteful to rewind to the beginning when there might be + // no other query following. Indeed, it would require reskipping the whole object. + // Instead, you can just stay where you are. If there is a new query, there is always time + // to rewind. + if(at_first) { return false; } + + // If we reach the end without finding a match, search the rest of the fields starting at the + // beginning of the object. + // (We have already run through the object before, so we've already validated its structure. We + // don't check errors in this bit.) + SIMDJSON_TRY(reset_object().get(has_value)); + while (true) { + SIMDJSON_ASSUME(has_value); // we should reach search_start before ever reaching the end of the object + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); // We must be at the start of a field + + // Get the key and colon, stopping at the value. + raw_json_string actual_key; + // size_t max_key_length = _json_iter->peek_length() - 2; // -2 for the two quotes + // Note: _json_iter->peek_length() - 2 might overflow if _json_iter->peek_length() < 2. + // field_key() advances the pointer and checks that '"' is found (corresponding to a key). + // The depth is left unchanged by field_key(). + error = field_key().get(actual_key); SIMDJSON_ASSUME(!error); + // field_value() will advance and check that we find a ':' separating the + // key and the value. It will also increment the depth by one. + error = field_value(); SIMDJSON_ASSUME(!error); + + // If it matches, stop and return + // We could do it this way if we wanted to allow arbitrary + // key content (including escaped quotes). + // if (actual_key.unsafe_is_equal(max_key_length, key)) { + // Instead we do the following which may trigger buffer overruns if the + // user provides an adversarial key (containing a well placed unescaped quote + // character and being longer than the number of bytes remaining in the JSON + // input). + if (actual_key.unsafe_is_equal(key)) { + logger::log_event(*this, "match", key, -2); + // If we return here, then we return while pointing at the ':' that we just checked. + return true; + } + + // No match: skip the value and see if , or } is next + logger::log_event(*this, "no match", key, -2); + // The call to skip_child is meant to skip over the value corresponding to the key. + // After skip_child(), we are right before the next comma (',') or the final brace ('}'). + SIMDJSON_TRY( skip_child() ); + // If we reached the end of the key-value pair we started from, then we know + // that the key is not there so we return false. We are either right before + // the next comma or the final brace. + if(_json_iter->position() == search_start) { return false; } + // The has_next_field() advances the pointer and check that either ',' or '}' is found. + // It returns true if ',' is found, false otherwise. If anything other than ',' or '}' is found, + // then we are in error and we abort. + error = has_next_field().get(has_value); SIMDJSON_ASSUME(!error); + // If we make the mistake of exiting here, then we could be left pointing at a key + // in the middle of an object. That's not an allowable state. + } + // If the loop ended, we're out of fields to look at. The program should + // never reach this point. + return false; +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::field_key() noexcept { + assert_at_next(); + + const uint8_t *key = _json_iter->return_current_and_advance(); + if (*(key++) != '"') { return report_error(TAPE_ERROR, "Object key is not a string"); } + return raw_json_string(key); +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::field_value() noexcept { + assert_at_next(); + + if (*_json_iter->return_current_and_advance() != ':') { return report_error(TAPE_ERROR, "Missing colon in object field"); } + _json_iter->descend_to(depth()+1); + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_array() noexcept { + SIMDJSON_TRY( start_container('[', "Not an array", "array") ); + return started_array(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::start_root_array() noexcept { + SIMDJSON_TRY( start_container('[', "Not an array", "array") ); + return started_root_array(); +} + +inline std::string value_iterator::to_string() const noexcept { + auto answer = std::string("value_iterator [ depth : ") + std::to_string(_depth) + std::string(", "); + if(_json_iter != nullptr) { answer += _json_iter->to_string(); } + answer += std::string(" ]"); + return answer; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_array() noexcept { + assert_at_container_start(); + if (*_json_iter->peek() == ']') { + logger::log_value(*_json_iter, "empty array"); + _json_iter->return_current_and_advance(); + SIMDJSON_TRY( end_container() ); + return false; + } + _json_iter->descend_to(depth()+1); +#if SIMDJSON_DEVELOPMENT_CHECKS + _json_iter->set_start_position(_depth, start_position()); +#endif + return true; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::check_root_array() noexcept { + // When in streaming mode, we cannot expect peek_last() to be the last structural element of the + // current document. It only works in the normal mode where we have indexed a single document. + // Note that adding a check for 'streaming' is not expensive since we only have at most + // one root element. + if ( ! _json_iter->streaming() ) { + // The following lines do not fully protect against garbage content within the + // array: e.g., `[1, 2] foo]`. Users concerned with garbage content should + // also call `at_end()` on the document instance at the end of the processing to + // ensure that the processing has finished at the end. + // + if (*_json_iter->peek_last() != ']') { + _json_iter->abandon(); + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "missing ] at end"); + } + // If the last character is ] *and* the first gibberish character is also ']' + // then on-demand could accidentally go over. So we need additional checks. + // https://github.com/simdjson/simdjson/issues/1834 + // Checking that the document is balanced requires a full scan which is potentially + // expensive, but it only happens in edge cases where the first padding character is + // a closing bracket. + if ((*_json_iter->peek(_json_iter->end_position()) == ']') && (!_json_iter->balanced())) { + _json_iter->abandon(); + // The exact error would require more work. It will typically be an unclosed array. + return report_error(INCOMPLETE_ARRAY_OR_OBJECT, "the document is unbalanced"); + } + } + return SUCCESS; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::started_root_array() noexcept { + auto error = check_root_array(); + if (error) { return error; } + return started_array(); +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::has_next_element() noexcept { + assert_at_next(); + + logger::log_event(*this, "has_next_element"); + switch (*_json_iter->return_current_and_advance()) { + case ']': + logger::log_end_value(*_json_iter, "array"); + SIMDJSON_TRY( end_container() ); + return false; + case ',': + _json_iter->descend_to(depth()+1); + return true; + default: + return report_error(TAPE_ERROR, "Missing comma between array elements"); + } +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::parse_bool(const uint8_t *json) const noexcept { + auto not_true = atomparsing::str4ncmp(json, "true"); + auto not_false = atomparsing::str4ncmp(json, "fals") | (json[4] ^ 'e'); + bool error = (not_true && not_false) || jsoncharutils::is_not_structural_or_whitespace(json[not_true ? 5 : 4]); + if (error) { return incorrect_type_error("Not a boolean"); } + return simdjson_result(!not_true); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::parse_null(const uint8_t *json) const noexcept { + bool is_null_string = !atomparsing::str4ncmp(json, "null") && jsoncharutils::is_structural_or_whitespace(json[4]); + // if we start with 'n', we must be a null + if(!is_null_string && json[0]=='n') { return incorrect_type_error("Not a null but starts with n"); } + return is_null_string; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_string(bool allow_replacement) noexcept { + return get_raw_json_string().unescape(json_iter(), allow_replacement); +} +template +simdjson_warn_unused simdjson_inline error_code value_iterator::get_string(string_type& receiver, bool allow_replacement) noexcept { + std::string_view content; + auto err = get_string(allow_replacement).get(content); + if (err) { return err; } + receiver = content; + return SUCCESS; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_wobbly_string() noexcept { + return get_raw_json_string().unescape_wobbly(json_iter()); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_raw_json_string() noexcept { + auto json = peek_scalar("string"); + if (*json != '"') { return incorrect_type_error("Not a string"); } + advance_scalar("string"); + return raw_json_string(json+1); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_uint64() noexcept { + auto result = numberparsing::parse_unsigned(peek_non_root_scalar("uint64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("uint64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_uint64_in_string() noexcept { + auto result = numberparsing::parse_unsigned_in_string(peek_non_root_scalar("uint64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("uint64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_int64() noexcept { + auto result = numberparsing::parse_integer(peek_non_root_scalar("int64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("int64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_int64_in_string() noexcept { + auto result = numberparsing::parse_integer_in_string(peek_non_root_scalar("int64")); + if(result.error() == SUCCESS) { advance_non_root_scalar("int64"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_double() noexcept { + auto result = numberparsing::parse_double(peek_non_root_scalar("double")); + if(result.error() == SUCCESS) { advance_non_root_scalar("double"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_double_in_string() noexcept { + auto result = numberparsing::parse_double_in_string(peek_non_root_scalar("double")); + if(result.error() == SUCCESS) { advance_non_root_scalar("double"); } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_bool() noexcept { + auto result = parse_bool(peek_non_root_scalar("bool")); + if(result.error() == SUCCESS) { advance_non_root_scalar("bool"); } + return result; +} +simdjson_inline simdjson_result value_iterator::is_null() noexcept { + bool is_null_value; + SIMDJSON_TRY(parse_null(peek_non_root_scalar("null")).get(is_null_value)); + if(is_null_value) { advance_non_root_scalar("null"); } + return is_null_value; +} +simdjson_inline bool value_iterator::is_negative() noexcept { + return numberparsing::is_negative(peek_non_root_scalar("numbersign")); +} +simdjson_inline bool value_iterator::is_root_negative() noexcept { + return numberparsing::is_negative(peek_root_scalar("numbersign")); +} +simdjson_inline simdjson_result value_iterator::is_integer() noexcept { + return numberparsing::is_integer(peek_non_root_scalar("integer")); +} +simdjson_inline simdjson_result value_iterator::get_number_type() noexcept { + return numberparsing::get_number_type(peek_non_root_scalar("integer")); +} +simdjson_inline simdjson_result value_iterator::get_number() noexcept { + number num; + error_code error = numberparsing::parse_number(peek_non_root_scalar("number"), num); + if(error) { return error; } + return num; +} + +simdjson_inline simdjson_result value_iterator::is_root_integer(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("is_root_integer"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + return false; // if there are more than 20 characters, it cannot be represented as an integer. + } + auto answer = numberparsing::is_integer(tmpbuf); + // If the parsing was a success, we must still check that it is + // a single scalar. Note that we parse first because of cases like '[]' where + // getting TRAILING_CONTENT is wrong. + if(check_trailing && (answer.error() == SUCCESS) && (!_json_iter->is_single_token())) { return TRAILING_CONTENT; } + return answer; +} + +simdjson_inline simdjson_result value_iterator::get_root_number_type(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("number"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto answer = numberparsing::get_number_type(tmpbuf); + if (check_trailing && (answer.error() == SUCCESS) && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + return answer; +} +simdjson_inline simdjson_result value_iterator::get_root_number(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("number"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + number num; + error_code error = numberparsing::parse_number(tmpbuf, num); + if(error) { return error; } + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("number"); + return num; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_string(bool check_trailing, bool allow_replacement) noexcept { + return get_root_raw_json_string(check_trailing).unescape(json_iter(), allow_replacement); +} +template +simdjson_warn_unused simdjson_inline error_code value_iterator::get_root_string(string_type& receiver, bool check_trailing, bool allow_replacement) noexcept { + std::string_view content; + auto err = get_root_string(check_trailing, allow_replacement).get(content); + if (err) { return err; } + receiver = content; + return SUCCESS; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_wobbly_string(bool check_trailing) noexcept { + return get_root_raw_json_string(check_trailing).unescape_wobbly(json_iter()); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_raw_json_string(bool check_trailing) noexcept { + auto json = peek_scalar("string"); + if (*json != '"') { return incorrect_type_error("Not a string"); } + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_scalar("string"); + return raw_json_string(json+1); +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_uint64(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("uint64"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_unsigned(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("uint64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_uint64_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("uint64"); + uint8_t tmpbuf[20+1+1]{}; // <20 digits> is the longest possible unsigned integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_unsigned_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("uint64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_int64(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("int64"); + uint8_t tmpbuf[20+1+1]; // -<19 digits> is the longest possible integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + + auto result = numberparsing::parse_integer(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("int64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_int64_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("int64"); + uint8_t tmpbuf[20+1+1]; // -<19 digits> is the longest possible integer + tmpbuf[20+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 20+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 20 characters"); + return NUMBER_ERROR; + } + + auto result = numberparsing::parse_integer_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("int64"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_double(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("double"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; // +1 for null termination. + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_double(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("double"); + } + return result; +} + +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_double_in_string(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("double"); + // Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/, + // 1074 is the maximum number of significant fractional digits. Add 8 more digits for the biggest + // number: -0.e-308. + uint8_t tmpbuf[1074+8+1+1]; // +1 for null termination. + tmpbuf[1074+8+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 1074+8+1)) { + logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters"); + return NUMBER_ERROR; + } + auto result = numberparsing::parse_double_in_string(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("double"); + } + return result; +} +simdjson_warn_unused simdjson_inline simdjson_result value_iterator::get_root_bool(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("bool"); + uint8_t tmpbuf[5+1+1]; // +1 for null termination + tmpbuf[5+1] = '\0'; // make sure that buffer is always null terminated. + if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf, 5+1)) { return incorrect_type_error("Not a boolean"); } + auto result = parse_bool(tmpbuf); + if(result.error() == SUCCESS) { + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("bool"); + } + return result; +} +simdjson_inline simdjson_result value_iterator::is_root_null(bool check_trailing) noexcept { + auto max_len = peek_start_length(); + auto json = peek_root_scalar("null"); + bool result = (max_len >= 4 && !atomparsing::str4ncmp(json, "null") && + (max_len == 4 || jsoncharutils::is_structural_or_whitespace(json[4]))); + if(result) { // we have something that looks like a null. + if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; } + advance_root_scalar("null"); + } + return result; +} + +simdjson_warn_unused simdjson_inline error_code value_iterator::skip_child() noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth >= _depth ); + + return _json_iter->skip_child(depth()); +} + +simdjson_inline value_iterator value_iterator::child() const noexcept { + assert_at_child(); + return { _json_iter, depth()+1, _json_iter->token.position() }; +} + +// GCC 7 warns when the first line of this function is inlined away into oblivion due to the caller +// relating depth and iterator depth, which is a desired effect. It does not happen if is_open is +// marked non-inline. +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_STRICT_OVERFLOW_WARNING +simdjson_inline bool value_iterator::is_open() const noexcept { + return _json_iter->depth() >= depth(); +} +SIMDJSON_POP_DISABLE_WARNINGS + +simdjson_inline bool value_iterator::at_end() const noexcept { + return _json_iter->at_end(); +} + +simdjson_inline bool value_iterator::at_start() const noexcept { + return _json_iter->token.position() == start_position(); +} + +simdjson_inline bool value_iterator::at_first_field() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + return _json_iter->token.position() == start_position() + 1; +} + +simdjson_inline void value_iterator::abandon() noexcept { + _json_iter->abandon(); +} + +simdjson_warn_unused simdjson_inline depth_t value_iterator::depth() const noexcept { + return _depth; +} +simdjson_warn_unused simdjson_inline error_code value_iterator::error() const noexcept { + return _json_iter->error; +} +simdjson_warn_unused simdjson_inline uint8_t *&value_iterator::string_buf_loc() noexcept { + return _json_iter->string_buf_loc(); +} +simdjson_warn_unused simdjson_inline const json_iterator &value_iterator::json_iter() const noexcept { + return *_json_iter; +} +simdjson_warn_unused simdjson_inline json_iterator &value_iterator::json_iter() noexcept { + return *_json_iter; +} + +simdjson_inline const uint8_t *value_iterator::peek_start() const noexcept { + return _json_iter->peek(start_position()); +} +simdjson_inline uint32_t value_iterator::peek_start_length() const noexcept { + return _json_iter->peek_length(start_position()); +} + +simdjson_inline const uint8_t *value_iterator::peek_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + if (!is_at_start()) { return peek_start(); } + + // Get the JSON and advance the cursor, decreasing depth to signify that we have retrieved the value. + assert_at_start(); + return _json_iter->peek(); +} + +simdjson_inline void value_iterator::advance_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + if (!is_at_start()) { return; } + + // Get the JSON and advance the cursor, decreasing depth to signify that we have retrieved the value. + assert_at_start(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} + +simdjson_inline error_code value_iterator::start_container(uint8_t start_char, const char *incorrect_type_message, const char *type) noexcept { + logger::log_start_value(*_json_iter, start_position(), depth(), type); + // If we're not at the position anymore, we don't want to advance the cursor. + const uint8_t *json; + if (!is_at_start()) { +#if SIMDJSON_DEVELOPMENT_CHECKS + if (!is_at_iterator_start()) { return OUT_OF_ORDER_ITERATION; } +#endif + json = peek_start(); + if (*json != start_char) { return incorrect_type_error(incorrect_type_message); } + } else { + assert_at_start(); + /** + * We should be prudent. Let us peek. If it is not the right type, we + * return an error. Only once we have determined that we have the right + * type are we allowed to advance! + */ + json = _json_iter->peek(); + if (*json != start_char) { return incorrect_type_error(incorrect_type_message); } + _json_iter->return_current_and_advance(); + } + + + return SUCCESS; +} + + +simdjson_inline const uint8_t *value_iterator::peek_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return peek_start(); } + + assert_at_root(); + return _json_iter->peek(); +} +simdjson_inline const uint8_t *value_iterator::peek_non_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return peek_start(); } + + assert_at_non_root_start(); + return _json_iter->peek(); +} + +simdjson_inline void value_iterator::advance_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return; } + + assert_at_root(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} +simdjson_inline void value_iterator::advance_non_root_scalar(const char *type) noexcept { + logger::log_value(*_json_iter, start_position(), depth(), type); + if (!is_at_start()) { return; } + + assert_at_non_root_start(); + _json_iter->return_current_and_advance(); + _json_iter->ascend_to(depth()-1); +} + +simdjson_inline error_code value_iterator::incorrect_type_error(const char *message) const noexcept { + logger::log_error(*_json_iter, start_position(), depth(), message); + return INCORRECT_TYPE; +} + +simdjson_inline bool value_iterator::is_at_start() const noexcept { + return position() == start_position(); +} + +simdjson_inline bool value_iterator::is_at_key() const noexcept { + // Keys are at the same depth as the object. + // Note here that we could be safer and check that we are within an object, + // but we do not. + return _depth == _json_iter->_depth && *_json_iter->peek() == '"'; +} + +simdjson_inline bool value_iterator::is_at_iterator_start() const noexcept { + // We can legitimately be either at the first value ([1]), or after the array if it's empty ([]). + auto delta = position() - start_position(); + return delta == 1 || delta == 2; +} + +inline void value_iterator::assert_at_start() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position == _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_container_start() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position == _start_position + 1 ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_next() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +simdjson_inline void value_iterator::move_at_start() noexcept { + _json_iter->_depth = _depth; + _json_iter->token.set_position(_start_position); +} + +simdjson_inline void value_iterator::move_at_container_start() noexcept { + _json_iter->_depth = _depth; + _json_iter->token.set_position(_start_position + 1); +} + +simdjson_inline simdjson_result value_iterator::reset_array() noexcept { + if(error()) { return error(); } + move_at_container_start(); + return started_array(); +} + +simdjson_inline simdjson_result value_iterator::reset_object() noexcept { + if(error()) { return error(); } + move_at_container_start(); + return started_object(); +} + +inline void value_iterator::assert_at_child() const noexcept { + SIMDJSON_ASSUME( _json_iter->token._position > _start_position ); + SIMDJSON_ASSUME( _json_iter->_depth == _depth + 1 ); + SIMDJSON_ASSUME( _depth > 0 ); +} + +inline void value_iterator::assert_at_root() const noexcept { + assert_at_start(); + SIMDJSON_ASSUME( _depth == 1 ); +} + +inline void value_iterator::assert_at_non_root_start() const noexcept { + assert_at_start(); + SIMDJSON_ASSUME( _depth > 1 ); +} + +inline void value_iterator::assert_is_valid() const noexcept { + SIMDJSON_ASSUME( _json_iter != nullptr ); +} + +simdjson_inline bool value_iterator::is_valid() const noexcept { + return _json_iter != nullptr; +} + +simdjson_inline simdjson_result value_iterator::type() const noexcept { + switch (*peek_start()) { + case '{': + return json_type::object; + case '[': + return json_type::array; + case '"': + return json_type::string; + case 'n': + return json_type::null; + case 't': case 'f': + return json_type::boolean; + case '-': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return json_type::number; + default: + return TAPE_ERROR; + } +} + +simdjson_inline token_position value_iterator::start_position() const noexcept { + return _start_position; +} + +simdjson_inline token_position value_iterator::position() const noexcept { + return _json_iter->position(); +} + +simdjson_inline token_position value_iterator::end_position() const noexcept { + return _json_iter->end_position(); +} + +simdjson_inline token_position value_iterator::last_position() const noexcept { + return _json_iter->last_position(); +} + +simdjson_inline error_code value_iterator::report_error(error_code error, const char *message) noexcept { + return _json_iter->report_error(error, message); +} + +} // namespace ondemand +} // namespace westmere +} // namespace simdjson + +namespace simdjson { + +simdjson_inline simdjson_result::simdjson_result(westmere::ondemand::value_iterator &&value) noexcept + : implementation_simdjson_result_base(std::forward(value)) {} +simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept + : implementation_simdjson_result_base(error) {} + +} // namespace simdjson + +#endif // SIMDJSON_GENERIC_ONDEMAND_VALUE_ITERATOR_INL_H +/* end file simdjson/generic/ondemand/value_iterator-inl.h for westmere */ +/* end file simdjson/generic/ondemand/amalgamated.h for westmere */ +/* including simdjson/westmere/end.h: #include "simdjson/westmere/end.h" */ +/* begin file simdjson/westmere/end.h */ +/* amalgamation skipped (editor-only): #ifndef SIMDJSON_CONDITIONAL_INCLUDE */ +/* amalgamation skipped (editor-only): #include "simdjson/westmere/base.h" */ +/* amalgamation skipped (editor-only): #endif // SIMDJSON_CONDITIONAL_INCLUDE */ + +#if !SIMDJSON_CAN_ALWAYS_RUN_WESTMERE +SIMDJSON_UNTARGET_REGION +#endif + +/* undefining SIMDJSON_IMPLEMENTATION from "westmere" */ +#undef SIMDJSON_IMPLEMENTATION +/* end file simdjson/westmere/end.h */ + +#endif // SIMDJSON_WESTMERE_IMPLEMENTATION_H +/* end file simdjson/westmere/ondemand.h */ +#else +#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION +#endif + +/* undefining SIMDJSON_CONDITIONAL_INCLUDE */ +#undef SIMDJSON_CONDITIONAL_INCLUDE + +namespace simdjson { + /** + * @copydoc simdjson::SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand + */ + namespace ondemand = SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand; +} // namespace simdjson + +#endif // SIMDJSON_BUILTIN_ONDEMAND_H +/* end file simdjson/builtin/ondemand.h */ + +namespace simdjson { + /** + * @copydoc simdjson::builtin::ondemand + */ + namespace ondemand = builtin::ondemand; +} // namespace simdjson + +#endif // SIMDJSON_ONDEMAND_H +/* end file simdjson/ondemand.h */ + +#endif // SIMDJSON_H +/* end file simdjson.h */ diff --git a/webapp/src/wasm/privateer.js b/webapp/src/wasm/privateer.js index 42fe23b65..2b1ac16bd 100644 --- a/webapp/src/wasm/privateer.js +++ b/webapp/src/wasm/privateer.js @@ -5,7 +5,7 @@ var privateer_module = (() => { return ( async function(moduleArg = {}) { -var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject}));["_main","getExceptionMessage","___get_exception_message","_free","___cpp_exception","___cxa_increment_exception_refcount","___cxa_decrement_exception_refcount","___thrown_object_from_unwind_exception","_fflush","__embind_initialize_bindings","___set_stack_limits","onRuntimeInitialized"].forEach((prop=>{if(!Object.getOwnPropertyDescriptor(Module["ready"],prop)){Object.defineProperty(Module["ready"],prop,{get:()=>abort("You are getting "+prop+" on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js"),set:()=>abort("You are setting "+prop+" on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")})}}));if(!Module.expectedDataFileDownloads){Module.expectedDataFileDownloads=0}Module.expectedDataFileDownloads++;(function(){if(Module["ENVIRONMENT_IS_PTHREAD"]||Module["$ww"])return;var loadPackage=function(metadata){var PACKAGE_PATH="";if(typeof window==="object"){PACKAGE_PATH=window["encodeURIComponent"](window.location.pathname.toString().substring(0,window.location.pathname.toString().lastIndexOf("/"))+"/")}else if(typeof process==="undefined"&&typeof location!=="undefined"){PACKAGE_PATH=encodeURIComponent(location.pathname.toString().substring(0,location.pathname.toString().lastIndexOf("/"))+"/")}var PACKAGE_NAME="privateer.data";var REMOTE_PACKAGE_BASE="privateer.data";if(typeof Module["locateFilePackage"]==="function"&&!Module["locateFile"]){Module["locateFile"]=Module["locateFilePackage"];err("warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)")}var REMOTE_PACKAGE_NAME=Module["locateFile"]?Module["locateFile"](REMOTE_PACKAGE_BASE,""):REMOTE_PACKAGE_BASE;var REMOTE_PACKAGE_SIZE=metadata["remote_package_size"];function fetchRemotePackage(packageName,packageSize,callback,errback){if(typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string"){require("fs").readFile(packageName,(function(err,contents){if(err){errback(err)}else{callback(contents.buffer)}}));return}var xhr=new XMLHttpRequest;xhr.open("GET",packageName,true);xhr.responseType="arraybuffer";xhr.onprogress=function(event){var url=packageName;var size=packageSize;if(event.total)size=event.total;if(event.loaded){if(!xhr.addedTotal){xhr.addedTotal=true;if(!Module.dataFileDownloads)Module.dataFileDownloads={};Module.dataFileDownloads[url]={loaded:event.loaded,total:size}}else{Module.dataFileDownloads[url].loaded=event.loaded}var total=0;var loaded=0;var num=0;for(var download in Module.dataFileDownloads){var data=Module.dataFileDownloads[download];total+=data.total;loaded+=data.loaded;num++}total=Math.ceil(total*Module.expectedDataFileDownloads/num);if(Module["setStatus"])Module["setStatus"](`Downloading data... (${loaded}/${total})`)}else if(!Module.dataFileDownloads){if(Module["setStatus"])Module["setStatus"]("Downloading data...")}};xhr.onerror=function(event){throw new Error("NetworkError for: "+packageName)};xhr.onload=function(event){if(xhr.status==200||xhr.status==304||xhr.status==206||xhr.status==0&&xhr.response){var packageData=xhr.response;callback(packageData)}else{throw new Error(xhr.statusText+" : "+xhr.responseURL)}};xhr.send(null)}function handleError(error){console.error("package error:",error)}var fetchedCallback=null;var fetched=Module["getPreloadedPackage"]?Module["getPreloadedPackage"](REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE):null;if(!fetched)fetchRemotePackage(REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE,(function(data){if(fetchedCallback){fetchedCallback(data);fetchedCallback=null}else{fetched=data}}),handleError);function runWithFS(){function assert(check,msg){if(!check)throw msg+(new Error).stack}Module["FS_createPath"]("/","unprocessed_files",true,true);function DataRequest(start,end,audio){this.start=start;this.end=end;this.audio=audio}DataRequest.prototype={requests:{},open:function(mode,name){this.name=name;this.requests[name]=this;Module["addRunDependency"](`fp ${this.name}`)},send:function(){},onload:function(){var byteArray=this.byteArray.subarray(this.start,this.end);this.finish(byteArray)},finish:function(byteArray){var that=this;Module["FS_createDataFile"](this.name,null,byteArray,true,true,true);Module["removeRunDependency"](`fp ${that.name}`);this.requests[this.name]=null}};var files=metadata["files"];for(var i=0;i{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";var ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(Module["ENVIRONMENT"]){throw new Error("Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)")}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_NODE){if(typeof process=="undefined"||!process.release||process.release.name!=="node")throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");var nodeVersion=process.versions.node;var numericVersion=nodeVersion.split(".").slice(0,3);numericVersion=numericVersion[0]*1e4+numericVersion[1]*100+numericVersion[2].split("-")[0]*1;if(numericVersion<16e4){throw new Error("This emscripten-generated code requires node v16.0.0 (detected v"+nodeVersion+")")}const{createRequire:createRequire}=await import("module");var require=createRequire(import.meta.url);var fs=require("fs");var nodePath=require("path");if(ENVIRONMENT_IS_WORKER){scriptDirectory=nodePath.dirname(scriptDirectory)+"/"}else{scriptDirectory=require("url").fileURLToPath(new URL("./",import.meta.url))}read_=(filename,binary)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);return fs.readFileSync(filename,binary?undefined:"utf8")};readBinary=filename=>{var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};readAsync=(filename,onload,onerror,binary=true)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);fs.readFile(filename,binary?undefined:"utf8",((err,data)=>{if(err)onerror(err);else onload(binary?data.buffer:data)}))};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow};Module["inspect"]=()=>"[Emscripten Module object]"}else if(ENVIRONMENT_IS_SHELL){if(typeof process=="object"&&typeof require==="function"||typeof window=="object"||typeof importScripts=="function")throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");if(typeof read!="undefined"){read_=f=>read(f)}readBinary=f=>{let data;if(typeof readbuffer=="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data=="object");return data};readAsync=(f,onload,onerror)=>{setTimeout((()=>onload(readBinary(f))))};if(typeof clearTimeout=="undefined"){globalThis.clearTimeout=id=>{}}if(typeof setTimeout=="undefined"){globalThis.setTimeout=f=>typeof f=="function"?f():abort()}if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit=="function"){quit_=(status,toThrow)=>{setTimeout((()=>{if(!(toThrow instanceof ExitStatus)){let toLog=toThrow;if(toThrow&&typeof toThrow=="object"&&toThrow.stack){toLog=[toThrow,toThrow.stack]}err(`exiting due to exception: ${toLog}`)}quit(status)}));throw toThrow}}if(typeof print!="undefined"){if(typeof console=="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}if(!(typeof window=="object"||typeof importScripts=="function"))throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=title=>document.title=title}else{throw new Error("environment detection error")}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;checkIncomingModuleAPI();if(Module["arguments"])arguments_=Module["arguments"];legacyModuleProp("arguments","arguments_");if(Module["thisProgram"])thisProgram=Module["thisProgram"];legacyModuleProp("thisProgram","thisProgram");if(Module["quit"])quit_=Module["quit"];legacyModuleProp("quit","quit_");assert(typeof Module["memoryInitializerPrefixURL"]=="undefined","Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["pthreadMainPrefixURL"]=="undefined","Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["cdInitializerPrefixURL"]=="undefined","Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["filePackagePrefixURL"]=="undefined","Module.filePackagePrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["read"]=="undefined","Module.read option was removed (modify read_ in JS)");assert(typeof Module["readAsync"]=="undefined","Module.readAsync option was removed (modify readAsync in JS)");assert(typeof Module["readBinary"]=="undefined","Module.readBinary option was removed (modify readBinary in JS)");assert(typeof Module["setWindowTitle"]=="undefined","Module.setWindowTitle option was removed (modify setWindowTitle in JS)");assert(typeof Module["TOTAL_MEMORY"]=="undefined","Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY");legacyModuleProp("read","read_");legacyModuleProp("readAsync","readAsync");legacyModuleProp("readBinary","readBinary");legacyModuleProp("setWindowTitle","setWindowTitle");assert(!ENVIRONMENT_IS_SHELL,"shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable.");var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];legacyModuleProp("wasmBinary","wasmBinary");var noExitRuntime=Module["noExitRuntime"]||true;legacyModuleProp("noExitRuntime","noExitRuntime");if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed"+(text?": "+text:""))}}var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b)}assert(!Module["STACK_SIZE"],"STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time");assert(typeof Int32Array!="undefined"&&typeof Float64Array!=="undefined"&&Int32Array.prototype.subarray!=undefined&&Int32Array.prototype.set!=undefined,"JS engine does not provide full typed array support");assert(!Module["wasmMemory"],"Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally");assert(!Module["INITIAL_MEMORY"],"Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically");var wasmTable;function writeStackCookie(){var max=_emscripten_stack_get_end();assert((max&3)==0);if(max==0){max+=4}HEAPU32[max>>2]=34821223;checkInt32(34821223);HEAPU32[max+4>>2]=2310721022;checkInt32(2310721022);HEAPU32[0>>2]=1668509029;checkInt32(1668509029)}function checkStackCookie(){if(ABORT)return;var max=_emscripten_stack_get_end();if(max==0){max+=4}var cookie1=HEAPU32[max>>2];var cookie2=HEAPU32[max+4>>2];if(cookie1!=34821223||cookie2!=2310721022){abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString(cookie2)} ${ptrToString(cookie1)}`)}if(HEAPU32[0>>2]!=1668509029){abort("Runtime error: The application has corrupted its heap memory area (address zero)!")}}(function(){var h16=new Int16Array(1);var h8=new Int8Array(h16.buffer);h16[0]=25459;if(h8[0]!==115||h8[1]!==99)throw"Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)"})();var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeKeepaliveCounter=0;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){assert(!runtimeInitialized);runtimeInitialized=true;checkStackCookie();setStackLimits();if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();FS.ignorePermissions=false;TTY.init();callRuntimeCallbacks(__ATINIT__)}function postRun(){checkStackCookie();if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}assert(Math.imul,"This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.fround,"This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.clz32,"This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.trunc,"This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;var runDependencyTracking={};function getUniqueRunDependency(id){var orig=id;while(1){if(!runDependencyTracking[id])return id;id=orig+Math.random()}}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(!runDependencyTracking[id]);runDependencyTracking[id]=1;if(runDependencyWatcher===null&&typeof setInterval!="undefined"){runDependencyWatcher=setInterval((()=>{if(ABORT){clearInterval(runDependencyWatcher);runDependencyWatcher=null;return}var shown=false;for(var dep in runDependencyTracking){if(!shown){shown=true;err("still waiting on run dependencies:")}err("dependency: "+dep)}if(shown){err("(end of list)")}}),1e4)}}else{err("warning: run dependency added without ID")}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(runDependencyTracking[id]);delete runDependencyTracking[id]}else{err("warning: run dependency removed without ID")}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;if(runtimeInitialized){___trap()}var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}function isFileURI(filename){return filename.startsWith("file://")}function createExportWrapper(name,fixedasm){return function(){var displayName=name;var asm=fixedasm;if(!fixedasm){asm=Module["asm"]}assert(runtimeInitialized,"native function `"+displayName+"` called before runtime initialization");if(!asm[name]){assert(asm[name],"exported native function `"+displayName+"` not found")}return asm[name].apply(null,arguments)}}var wasmBinaryFile;if(Module["locateFile"]){wasmBinaryFile="privateer.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}}else{wasmBinaryFile=new URL("privateer.wasm",import.meta.url).href}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}function getBinaryPromise(binaryFile){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"&&!isFileURI(binaryFile)){return fetch(binaryFile,{credentials:"same-origin"}).then((response=>{if(!response["ok"]){throw"failed to load wasm binary file at '"+binaryFile+"'"}return response["arrayBuffer"]()})).catch((()=>getBinarySync(binaryFile)))}else if(readAsync){return new Promise(((resolve,reject)=>{readAsync(binaryFile,(response=>resolve(new Uint8Array(response))),reject)}))}}return Promise.resolve().then((()=>getBinarySync(binaryFile)))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then((binary=>WebAssembly.instantiate(binary,imports))).then((instance=>instance)).then(receiver,(reason=>{err("failed to asynchronously prepare wasm: "+reason);if(isFileURI(wasmBinaryFile)){err("warning: Loading from a file URI ("+wasmBinaryFile+") is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing")}abort(reason)}))}function instantiateAsync(binary,binaryFile,imports,callback){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then((response=>{var result=WebAssembly.instantiateStreaming(response,imports);return result.then(callback,(function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(binaryFile,imports,callback)}))}))}return instantiateArrayBuffer(binaryFile,imports,callback)}function createWasm(){var info={"env":wasmImports,"wasi_snapshot_preview1":wasmImports};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["memory"];assert(wasmMemory,"memory not found in wasm exports");updateMemoryViews();wasmTable=Module["asm"]["__indirect_function_table"];assert(wasmTable,"table not found in wasm exports");addOnInit(Module["asm"]["__wasm_call_ctors"]);removeRunDependency("wasm-instantiate");return exports}addRunDependency("wasm-instantiate");var trueModule=Module;function receiveInstantiationResult(result){assert(Module===trueModule,"the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?");trueModule=null;receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err("Module.instantiateWasm callback failed with error: "+e);readyPromiseReject(e)}}instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult).catch(readyPromiseReject);return{}}var tempDouble;var tempI64;function legacyModuleProp(prop,newName){if(!Object.getOwnPropertyDescriptor(Module,prop)){Object.defineProperty(Module,prop,{configurable:true,get(){abort("Module."+prop+" has been replaced with plain "+newName+" (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}}function ignoredModuleProp(prop){if(Object.getOwnPropertyDescriptor(Module,prop)){abort("`Module."+prop+"` was supplied but `"+prop+"` not included in INCOMING_MODULE_JS_API")}}function isExportedByForceFilesystem(name){return name==="FS_createPath"||name==="FS_createDataFile"||name==="FS_createPreloadedFile"||name==="FS_unlink"||name==="addRunDependency"||name==="FS_createLazyFile"||name==="FS_createDevice"||name==="removeRunDependency"}function missingGlobal(sym,msg){if(typeof globalThis!=="undefined"){Object.defineProperty(globalThis,sym,{configurable:true,get(){warnOnce("`"+sym+"` is not longer defined by emscripten. "+msg);return undefined}})}}missingGlobal("buffer","Please use HEAP8.buffer or wasmMemory.buffer");function missingLibrarySymbol(sym){if(typeof globalThis!=="undefined"&&!Object.getOwnPropertyDescriptor(globalThis,sym)){Object.defineProperty(globalThis,sym,{configurable:true,get(){var msg="`"+sym+"` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line";var librarySymbol=sym;if(!librarySymbol.startsWith("_")){librarySymbol="$"+sym}msg+=" (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='"+librarySymbol+"')";if(isExportedByForceFilesystem(sym)){msg+=". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"}warnOnce(msg);return undefined}})}unexportedRuntimeSymbol(sym)}function unexportedRuntimeSymbol(sym){if(!Object.getOwnPropertyDescriptor(Module,sym)){Object.defineProperty(Module,sym,{configurable:true,get(){var msg="'"+sym+"' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)";if(isExportedByForceFilesystem(sym)){msg+=". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"}abort(msg)}})}}var MAX_UINT8=2**8-1;var MAX_UINT16=2**16-1;var MAX_UINT32=2**32-1;var MAX_UINT53=2**53-1;var MAX_UINT64=2**64-1;var MIN_INT8=-(2**(8-1))+1;var MIN_INT16=-(2**(16-1))+1;var MIN_INT32=-(2**(32-1))+1;var MIN_INT53=-(2**(53-1))+1;var MIN_INT64=-(2**(64-1))+1;function checkInt(value,bits,min,max){assert(Number.isInteger(Number(value)),"attempt to write non-integer ("+value+") into integer heap");assert(value<=max,"value ("+value+") too large to write as "+bits+"-bit value");assert(value>=min,"value ("+value+") too small to write as "+bits+"-bit value")}var checkInt8=value=>checkInt(value,8,MIN_INT8,MAX_UINT8);var checkInt16=value=>checkInt(value,16,MIN_INT16,MAX_UINT16);var checkInt32=value=>checkInt(value,32,MIN_INT32,MAX_UINT32);var checkInt64=value=>checkInt(value,64,MIN_INT64,MAX_UINT64);function ExitStatus(status){this.name="ExitStatus";this.message=`Program terminated with exit(${status})`;this.status=status}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};function getCppExceptionTag(){return Module["asm"]["__cpp_exception"]}function getCppExceptionThrownObjectFromWebAssemblyException(ex){var unwind_header=ex.getArg(getCppExceptionTag(),0);return ___thrown_object_from_unwind_exception(unwind_header)}var withStackSave=f=>{var stack=stackSave();var ret=f();stackRestore(stack);return ret};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{assert(typeof str==="string");if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;if(u>1114111)warnOnce("Invalid Unicode code point "+ptrToString(u)+" encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).");heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>{assert(typeof maxBytesToWrite=="number","stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)};var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):undefined;var UTF8ArrayToString=(heapOrArray,idx,maxBytesToRead)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>{assert(typeof ptr=="number");return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""};function demangle(func){demangle.recursionGuard=(demangle.recursionGuard|0)+1;if(demangle.recursionGuard>1)return func;return withStackSave((function(){try{var s=func;if(s.startsWith("__Z"))s=s.substr(1);var buf=stringToUTF8OnStack(s);var status=stackAlloc(4);var ret=___cxa_demangle(buf,0,0,status);if(HEAP32[status>>2]===0&&ret){return UTF8ToString(ret)}}catch(e){}finally{_free(ret);if(demangle.recursionGuard<2)--demangle.recursionGuard}return func}))}var getExceptionMessageCommon=ptr=>withStackSave((()=>{var type_addr_addr=stackAlloc(4);var message_addr_addr=stackAlloc(4);___get_exception_message(ptr,type_addr_addr,message_addr_addr);var type_addr=HEAPU32[type_addr_addr>>2];var message_addr=HEAPU32[message_addr_addr>>2];var type=UTF8ToString(type_addr);_free(type_addr);var message;if(message_addr){message=UTF8ToString(message_addr);_free(message_addr)}return[type,message]}));function getExceptionMessage(ex){var ptr=getCppExceptionThrownObjectFromWebAssemblyException(ex);return getExceptionMessageCommon(ptr)}Module["getExceptionMessage"]=getExceptionMessage;var ptrToString=ptr=>{assert(typeof ptr==="number");ptr>>>=0;return"0x"+ptr.toString(16).padStart(8,"0")};var setStackLimits=()=>{var stackLow=_emscripten_stack_get_base();var stackHigh=_emscripten_stack_get_end();___set_stack_limits(stackLow,stackHigh)};function jsStackTrace(){var error=new Error;if(!error.stack){try{throw new Error}catch(e){error=e}if(!error.stack){return"(no stack trace available)"}}return error.stack.toString()}function demangleAll(text){var regex=/\b_Z[\w\d_]+/g;return text.replace(regex,(function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"}))}var warnOnce=text=>{if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;if(ENVIRONMENT_IS_NODE)text="warning: "+text;err(text)}};var ___assert_fail=(condition,filename,line,func)=>{abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"])};var ___handle_stack_overflow=requested=>{var base=_emscripten_stack_get_base();var end=_emscripten_stack_get_end();abort(`stack overflow (Attempt to set SP to ${ptrToString(requested)}`+`, with stack limits [${ptrToString(end)} - ${ptrToString(base)}`+"]). If you require more stack space build with -sSTACK_SIZE=")};var setErrNo=value=>{HEAP32[___errno_location()>>2]=value;checkInt32(value);return value};var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter((p=>!!p)),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:path=>{if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},join:function(){var paths=Array.prototype.slice.call(arguments);return PATH.normalize(paths.join("/"))},join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>{if(typeof crypto=="object"&&typeof crypto["getRandomValues"]=="function"){return view=>crypto.getRandomValues(view)}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");var randomFillSync=crypto_module["randomFillSync"];if(randomFillSync){return view=>crypto_module["randomFillSync"](view)}var randomBytes=crypto_module["randomBytes"];return view=>(view.set(randomBytes(view.byteLength)),view)}catch(e){}}abort("no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: (array) => { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };")};var randomFill=view=>(randomFill=initRandomFill())(view);var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter((p=>!!p)),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc(BUFSIZE);var bytesRead=0;var fd=process.stdin.fd;try{bytesRead=fs.readSync(fd,buf,0,BUFSIZE,-1)}catch(e){if(e.toString().includes("EOF"))bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init:function(){},shutdown:function(){},register:function(dev,ops){TTY.ttys[dev]={input:[],output:[],ops:ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open:function(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close:function(stream){stream.tty.ops.fsync(stream.tty)},fsync:function(stream){stream.tty.ops.fsync(stream.tty)},read:function(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}},ioctl_tcgets:function(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets:function(tty,optional_actions,data){return 0},ioctl_tiocgwinsz:function(tty){return[24,80]}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};var zeroMemory=(address,size)=>{HEAPU8.fill(0,address,address+size);return address};var alignMemory=(size,alignment)=>{assert(alignment,"alignment argument is required");return Math.ceil(size/alignment)*alignment};var mmapAlloc=size=>{size=alignMemory(size,65536);var ptr=_emscripten_builtin_memalign(65536,size);if(!ptr)return 0;return zeroMemory(ptr,size)};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){throw FS.genericErrors[44]},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp;old_node.parent=new_dir},unlink(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);assert(size>=0);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var dep=!noRunDep?getUniqueRunDependency(`al ${url}`):"";readAsync(url,(arrayBuffer=>{assert(arrayBuffer,`Loading data file "${url}" failed (no arrayBuffer).`);onload(new Uint8Array(arrayBuffer));if(dep)removeRunDependency(dep)}),(event=>{if(onerror){onerror()}else{throw`Loading data file "${url}" failed.`}}));if(dep)addRunDependency(dep)};var preloadPlugins=Module["preloadPlugins"]||[];function FS_handledByPreloadPlugin(byteArray,fullname,finish,onerror){if(typeof Browser!="undefined")Browser.init();var handled=false;preloadPlugins.forEach((function(plugin){if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,onerror);handled=true}}));return handled}function FS_createPreloadedFile(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish){var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);function processData(byteArray){function finish(byteArray){if(preFinish)preFinish();if(!dontCreateFile){FS.createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}if(onload)onload();removeRunDependency(dep)}if(FS_handledByPreloadPlugin(byteArray,fullname,finish,(()=>{if(onerror)onerror();removeRunDependency(dep)}))){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url,(byteArray=>processData(byteArray)),onerror)}else{processData(url)}}function FS_modeStringToFlags(str){var flagModes={"r":0,"r+":2,"w":512|64|1,"w+":512|64|2,"a":1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags}function FS_getMode(canRead,canWrite){var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode}var ERRNO_CODES={};var NODEFS={isWindows:false,staticInit:()=>{NODEFS.isWindows=!!process.platform.match(/^win/);var flags=process.binding("constants");if(flags["fs"]){flags=flags["fs"]}NODEFS.flagsForNodeMap={1024:flags["O_APPEND"],64:flags["O_CREAT"],128:flags["O_EXCL"],256:flags["O_NOCTTY"],0:flags["O_RDONLY"],2:flags["O_RDWR"],4096:flags["O_SYNC"],512:flags["O_TRUNC"],1:flags["O_WRONLY"],131072:flags["O_NOFOLLOW"]};assert(NODEFS.flagsForNodeMap["0"]===0)},convertNodeCode:e=>{var code=e.code;assert(code in ERRNO_CODES,`unexpected node error code: ${code} (${e})`);return ERRNO_CODES[code]},mount:mount=>{assert(ENVIRONMENT_IS_NODE);return NODEFS.createNode(null,"/",NODEFS.getMode(mount.opts.root),0)},createNode:(parent,name,mode,dev)=>{if(!FS.isDir(mode)&&!FS.isFile(mode)&&!FS.isLink(mode)){throw new FS.ErrnoError(28)}var node=FS.createNode(parent,name,mode);node.node_ops=NODEFS.node_ops;node.stream_ops=NODEFS.stream_ops;return node},getMode:path=>{var stat;try{stat=fs.lstatSync(path);if(NODEFS.isWindows){stat.mode=stat.mode|(stat.mode&292)>>2}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}return stat.mode},realPath:node=>{var parts=[];while(node.parent!==node){parts.push(node.name);node=node.parent}parts.push(node.mount.opts.root);parts.reverse();return PATH.join.apply(null,parts)},flagsForNode:flags=>{flags&=~2097152;flags&=~2048;flags&=~32768;flags&=~524288;flags&=~65536;var newFlags=0;for(var k in NODEFS.flagsForNodeMap){if(flags&k){newFlags|=NODEFS.flagsForNodeMap[k];flags^=k}}if(flags){throw new FS.ErrnoError(28)}return newFlags},node_ops:{getattr:node=>{var path=NODEFS.realPath(node);var stat;try{stat=fs.lstatSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}if(NODEFS.isWindows&&!stat.blksize){stat.blksize=4096}if(NODEFS.isWindows&&!stat.blocks){stat.blocks=(stat.size+stat.blksize-1)/stat.blksize|0}return{dev:stat.dev,ino:stat.ino,mode:stat.mode,nlink:stat.nlink,uid:stat.uid,gid:stat.gid,rdev:stat.rdev,size:stat.size,atime:stat.atime,mtime:stat.mtime,ctime:stat.ctime,blksize:stat.blksize,blocks:stat.blocks}},setattr:(node,attr)=>{var path=NODEFS.realPath(node);try{if(attr.mode!==undefined){fs.chmodSync(path,attr.mode);node.mode=attr.mode}if(attr.timestamp!==undefined){var date=new Date(attr.timestamp);fs.utimesSync(path,date,date)}if(attr.size!==undefined){fs.truncateSync(path,attr.size)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},lookup:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);var mode=NODEFS.getMode(path);return NODEFS.createNode(parent,name,mode)},mknod:(parent,name,mode,dev)=>{var node=NODEFS.createNode(parent,name,mode,dev);var path=NODEFS.realPath(node);try{if(FS.isDir(node.mode)){fs.mkdirSync(path,node.mode)}else{fs.writeFileSync(path,"",{mode:node.mode})}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}return node},rename:(oldNode,newDir,newName)=>{var oldPath=NODEFS.realPath(oldNode);var newPath=PATH.join2(NODEFS.realPath(newDir),newName);try{fs.renameSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}oldNode.name=newName},unlink:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.unlinkSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},rmdir:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.rmdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},readdir:node=>{var path=NODEFS.realPath(node);try{return fs.readdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},symlink:(parent,newName,oldPath)=>{var newPath=PATH.join2(NODEFS.realPath(parent),newName);try{fs.symlinkSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},readlink:node=>{var path=NODEFS.realPath(node);try{path=fs.readlinkSync(path);path=nodePath.relative(nodePath.resolve(node.mount.opts.root),path);return path}catch(e){if(!e.code)throw e;if(e.code==="UNKNOWN")throw new FS.ErrnoError(28);throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}}},stream_ops:{open:stream=>{var path=NODEFS.realPath(stream.node);try{if(FS.isFile(stream.node.mode)){stream.nfd=fs.openSync(path,NODEFS.flagsForNode(stream.flags))}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},close:stream=>{try{if(FS.isFile(stream.node.mode)&&stream.nfd){fs.closeSync(stream.nfd)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},read:(stream,buffer,offset,length,position)=>{if(length===0)return 0;try{return fs.readSync(stream.nfd,Buffer.from(buffer.buffer),offset,length,position)}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},write:(stream,buffer,offset,length,position)=>{try{return fs.writeSync(stream.nfd,Buffer.from(buffer.buffer),offset,length,position)}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},llseek:(stream,offset,whence)=>{var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){try{var stat=fs.fstatSync(stream.nfd);position+=stat.size}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}}}if(position<0){throw new FS.ErrnoError(28)}return position},mmap:(stream,length,position,prot,flags)=>{if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}var ptr=mmapAlloc(length);NODEFS.stream_ops.read(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}},msync:(stream,buffer,offset,length,mmapFlags)=>{NODEFS.stream_ops.write(stream,buffer,0,length,offset,false);return 0}}};var ERRNO_MESSAGES={0:"Success",1:"Arg list too long",2:"Permission denied",3:"Address already in use",4:"Address not available",5:"Address family not supported by protocol family",6:"No more processes",7:"Socket already connected",8:"Bad file number",9:"Trying to read unreadable message",10:"Mount device busy",11:"Operation canceled",12:"No children",13:"Connection aborted",14:"Connection refused",15:"Connection reset by peer",16:"File locking deadlock error",17:"Destination address required",18:"Math arg out of domain of func",19:"Quota exceeded",20:"File exists",21:"Bad address",22:"File too large",23:"Host is unreachable",24:"Identifier removed",25:"Illegal byte sequence",26:"Connection already in progress",27:"Interrupted system call",28:"Invalid argument",29:"I/O error",30:"Socket is already connected",31:"Is a directory",32:"Too many symbolic links",33:"Too many open files",34:"Too many links",35:"Message too long",36:"Multihop attempted",37:"File or path name too long",38:"Network interface is not configured",39:"Connection reset by network",40:"Network is unreachable",41:"Too many open files in system",42:"No buffer space available",43:"No such device",44:"No such file or directory",45:"Exec format error",46:"No record locks available",47:"The link has been severed",48:"Not enough core",49:"No message of desired type",50:"Protocol not available",51:"No space left on device",52:"Function not implemented",53:"Socket is not connected",54:"Not a directory",55:"Directory not empty",56:"State not recoverable",57:"Socket operation on non-socket",59:"Not a typewriter",60:"No such device or address",61:"Value too large for defined data type",62:"Previous owner died",63:"Not super-user",64:"Broken pipe",65:"Protocol error",66:"Unknown protocol",67:"Protocol wrong type for socket",68:"Math result not representable",69:"Read only file system",70:"Illegal seek",71:"No such process",72:"Stale file handle",73:"Connection timed out",74:"Text file busy",75:"Cross-device link",100:"Device not a stream",101:"Bad font file fmt",102:"Invalid slot",103:"Invalid request code",104:"No anode",105:"Block device required",106:"Channel number out of range",107:"Level 3 halted",108:"Level 3 reset",109:"Link number out of range",110:"Protocol driver not attached",111:"No CSI structure available",112:"Level 2 halted",113:"Invalid exchange",114:"Invalid request descriptor",115:"Exchange full",116:"No data (for no delay io)",117:"Timer expired",118:"Out of streams resources",119:"Machine is not on the network",120:"Package not installed",121:"The object is remote",122:"Advertise error",123:"Srmount error",124:"Communication error on send",125:"Cross mount point (not really error)",126:"Given log. name not unique",127:"f.d. invalid for this operation",128:"Remote address changed",129:"Can access a needed shared lib",130:"Accessing a corrupted shared lib",131:".lib section in a.out corrupted",132:"Attempting to link in too many libs",133:"Attempting to exec a shared library",135:"Streams pipe error",136:"Too many users",137:"Socket type not supported",138:"Not supported",139:"Protocol family not supported",140:"Can't send after socket shutdown",141:"Too many references",142:"Host is down",148:"No medium (in tape drive)",156:"Level 2 not synchronized"};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:(path,opts={})=>{path=PATH_FS.resolve(path);if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};opts=Object.assign(defaults,opts);if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=path.split("/").filter((p=>!!p));var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:node=>{var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?`${mount}/${path}`:mount+path}path=path?`${node.name}/${path}`:node.name;node=node.parent}},hashName:(parentid,name)=>{var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:node=>{var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:node=>{var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:(parent,name)=>{var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:(parent,name,mode,rdev)=>{assert(typeof parent=="object");var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:node=>{FS.hashRemoveNode(node)},isRoot:node=>node===node.parent,isMountpoint:node=>!!node.mounted,isFile:mode=>(mode&61440)===32768,isDir:mode=>(mode&61440)===16384,isLink:mode=>(mode&61440)===40960,isChrdev:mode=>(mode&61440)===8192,isBlkdev:mode=>(mode&61440)===24576,isFIFO:mode=>(mode&61440)===4096,isSocket:mode=>(mode&49152)===49152,flagsToPermissionString:flag=>{var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:(node,perms)=>{if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup:dir=>{var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:(dir,name)=>{try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:(dir,name,isdir)=>{var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:(node,flags)=>{if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:()=>{for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked:fd=>{var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream:(stream,fd=-1)=>{if(!FS.FSStream){FS.FSStream=function(){this.shared={}};FS.FSStream.prototype={};Object.defineProperties(FS.FSStream.prototype,{object:{get(){return this.node},set(val){this.node=val}},isRead:{get(){return(this.flags&2097155)!==1}},isWrite:{get(){return(this.flags&2097155)!==0}},isAppend:{get(){return this.flags&1024}},flags:{get(){return this.shared.flags},set(val){this.shared.flags=val}},position:{get(){return this.shared.position},set(val){this.shared.position=val}}})}stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:fd=>{FS.streams[fd]=null},chrdev_stream_ops:{open:stream=>{var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:()=>{throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice:(dev,ops)=>{FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts:mount=>{var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:(populate,callback)=>{if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){assert(FS.syncFSRequests>0);FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach((mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)}))},mount:(type,opts,mountpoint)=>{if(typeof type=="string"){throw type}var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:mountpoint=>{var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach((hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}}));node.mounted=null;var idx=node.mount.mounts.indexOf(mount);assert(idx!==-1);node.mount.mounts.splice(idx,1)},lookup:(parent,name)=>parent.node_ops.lookup(parent,name),mknod:(path,mode,dev)=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:(path,mode)=>{mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:(path,mode)=>{mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:(path,mode)=>{var dirs=path.split("/");var d="";for(var i=0;i{if(typeof dev=="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink:(oldpath,newpath)=>{if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename:(old_path,new_path)=>{var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name)}catch(e){throw e}finally{FS.hashAddNode(old_node)}},rmdir:path=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node)},readdir:path=>{var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node.node_ops.readdir){throw new FS.ErrnoError(54)}return node.node_ops.readdir(node)},unlink:path=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.unlink(parent,name);FS.destroyNode(node)},readlink:path=>{var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return PATH_FS.resolve(FS.getPath(link.parent),link.node_ops.readlink(link))},stat:(path,dontFollow)=>{var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;if(!node){throw new FS.ErrnoError(44)}if(!node.node_ops.getattr){throw new FS.ErrnoError(63)}return node.node_ops.getattr(node)},lstat:path=>FS.stat(path,true),chmod:(path,mode,dontFollow)=>{var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{mode:mode&4095|node.mode&~4095,timestamp:Date.now()})},lchmod:(path,mode)=>{FS.chmod(path,mode,true)},fchmod:(fd,mode)=>{var stream=FS.getStreamChecked(fd);FS.chmod(stream.node,mode)},chown:(path,uid,gid,dontFollow)=>{var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{timestamp:Date.now()})},lchown:(path,uid,gid)=>{FS.chown(path,uid,gid,true)},fchown:(fd,uid,gid)=>{var stream=FS.getStreamChecked(fd);FS.chown(stream.node,uid,gid)},truncate:(path,len)=>{if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}node.node_ops.setattr(node,{size:len,timestamp:Date.now()})},ftruncate:(fd,len)=>{var stream=FS.getStreamChecked(fd);if((stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.truncate(stream.node,len)},utime:(path,atime,mtime)=>{var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;node.node_ops.setattr(node,{timestamp:Math.max(atime,mtime)})},open:(path,flags,mode)=>{if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags=="string"?FS_modeStringToFlags(flags):flags;mode=typeof mode=="undefined"?438:mode;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;if(typeof path=="object"){node=path}else{path=PATH.normalize(path);try{var lookup=FS.lookupPath(path,{follow:!(flags&131072)});node=lookup.node}catch(e){}}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else{node=FS.mknod(path,mode,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512&&!created){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node:node,path:FS.getPath(node),flags:flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false});if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(Module["logReadFiles"]&&!(flags&1)){if(!FS.readFiles)FS.readFiles={};if(!(path in FS.readFiles)){FS.readFiles[path]=1}}return stream},close:stream=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed:stream=>stream.fd===null,llseek:(stream,offset,whence)=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read:(stream,buffer,offset,length,position)=>{assert(offset>=0);if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write:(stream,buffer,offset,length,position,canOwn)=>{assert(offset>=0);if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},allocate:(stream,offset,length)=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(offset<0||length<=0){throw new FS.ErrnoError(28)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(!FS.isFile(stream.node.mode)&&!FS.isDir(stream.node.mode)){throw new FS.ErrnoError(43)}if(!stream.stream_ops.allocate){throw new FS.ErrnoError(138)}stream.stream_ops.allocate(stream,offset,length)},mmap:(stream,length,position,prot,flags)=>{if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync:(stream,buffer,offset,length,mmapFlags)=>{assert(offset>=0);if(!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},munmap:stream=>0,ioctl:(stream,cmd,arg)=>{if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile:(path,opts={})=>{opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error(`Invalid encoding type "${opts.encoding}"`)}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret=UTF8ArrayToString(buf,0)}else if(opts.encoding==="binary"){ret=buf}FS.close(stream);return ret},writeFile:(path,data,opts={})=>{opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){var buf=new Uint8Array(lengthBytesUTF8(data)+1);var actualNumBytes=stringToUTF8Array(data,buf,0,buf.length);FS.write(stream,buf,0,actualNumBytes,undefined,opts.canOwn)}else if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir:path=>{var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories:()=>{FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices:()=>{FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomLeft=randomFill(randomBuffer).byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories:()=>{FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount:()=>{var node=FS.createNode(proc_self,"fd",16384|511,73);node.node_ops={lookup:(parent,name)=>{var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams:()=>{if(Module["stdin"]){FS.createDevice("/dev","stdin",Module["stdin"])}else{FS.symlink("/dev/tty","/dev/stdin")}if(Module["stdout"]){FS.createDevice("/dev","stdout",null,Module["stdout"])}else{FS.symlink("/dev/tty","/dev/stdout")}if(Module["stderr"]){FS.createDevice("/dev","stderr",null,Module["stderr"])}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1);assert(stdin.fd===0,`invalid handle for stdin (${stdin.fd})`);assert(stdout.fd===1,`invalid handle for stdout (${stdout.fd})`);assert(stderr.fd===2,`invalid handle for stderr (${stderr.fd})`)},ensureErrnoError:()=>{if(FS.ErrnoError)return;FS.ErrnoError=function ErrnoError(errno,node){this.name="ErrnoError";this.node=node;this.setErrno=function(errno){this.errno=errno;for(var key in ERRNO_CODES){if(ERRNO_CODES[key]===errno){this.code=key;break}}};this.setErrno(errno);this.message=ERRNO_MESSAGES[errno];if(this.stack){Object.defineProperty(this,"stack",{value:(new Error).stack,writable:true});this.stack=demangleAll(this.stack)}};FS.ErrnoError.prototype=new Error;FS.ErrnoError.prototype.constructor=FS.ErrnoError;[44].forEach((code=>{FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack=""}))},staticInit:()=>{FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={"MEMFS":MEMFS,"NODEFS":NODEFS}},init:(input,output,error)=>{assert(!FS.init.initialized,"FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)");FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()},quit:()=>{FS.init.initialized=false;_fflush(0);for(var i=0;i{var ret=FS.analyzePath(path,dontResolveLastLink);if(!ret.exists){return null}return ret.object},analyzePath:(path,dontResolveLastLink)=>{try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath:(parent,path,canRead,canWrite)=>{parent=typeof parent=="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){}parent=current}return current},createFile:(parent,name,properties,canRead,canWrite)=>{var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile:(parent,name,data,canRead,canWrite,canOwn)=>{var path=name;if(parent){parent=typeof parent=="string"?parent:FS.getPath(parent);path=name?PATH.join2(parent,name):parent}var mode=FS_getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data=="string"){var arr=new Array(data.length);for(var i=0,len=data.length;i{var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(!!input,!!output);if(!FS.createDevice.major)FS.createDevice.major=64;var dev=FS.makedev(FS.createDevice.major++,0);FS.registerDevice(dev,{open:stream=>{stream.seekable=false},close:stream=>{if(output&&output.buffer&&output.buffer.length){output(10)}},read:(stream,buffer,offset,length,pos)=>{var bytesRead=0;for(var i=0;i{for(var i=0;i{if(obj.isDevice||obj.isFolder||obj.link||obj.contents)return true;if(typeof XMLHttpRequest!="undefined"){throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.")}else if(read_){try{obj.contents=intArrayFromString(read_(obj.url),true);obj.usedBytes=obj.contents.length}catch(e){throw new FS.ErrnoError(29)}}else{throw new Error("Cannot load without read() or XMLHttpRequest.")}},createLazyFile:(parent,name,url,canRead,canWrite)=>{function LazyUint8Array(){this.lengthKnown=false;this.chunks=[]}LazyUint8Array.prototype.get=function LazyUint8Array_get(idx){if(idx>this.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter((chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]}));if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach((key=>{var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}}));function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);assert(size>=0);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}};node.stream_ops=stream_ops;return node},absolutePath:()=>{abort("FS.absolutePath has been removed; use PATH_FS.resolve instead")},createFolder:()=>{abort("FS.createFolder has been removed; use FS.mkdir instead")},createLink:()=>{abort("FS.createLink has been removed; use FS.symlink instead")},joinPath:()=>{abort("FS.joinPath has been removed; use PATH.join instead")},mmapAlloc:()=>{abort("FS.mmapAlloc has been replaced by the top level function mmapAlloc")},standardizePath:()=>{abort("FS.standardizePath has been removed; use PATH.normalize instead")}};var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt:function(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return PATH.join2(dir,path)},doStat:function(func,path,buf){try{var stat=func(path)}catch(e){if(e&&e.node&&PATH.normalize(path)!==PATH.normalize(FS.getPath(e.node))){return-54}throw e}HEAP32[buf>>2]=stat.dev;checkInt32(stat.dev);HEAP32[buf+4>>2]=stat.mode;checkInt32(stat.mode);HEAPU32[buf+8>>2]=stat.nlink;checkInt32(stat.nlink);HEAP32[buf+12>>2]=stat.uid;checkInt32(stat.uid);HEAP32[buf+16>>2]=stat.gid;checkInt32(stat.gid);HEAP32[buf+20>>2]=stat.rdev;checkInt32(stat.rdev);tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+24>>2]=tempI64[0],HEAP32[buf+28>>2]=tempI64[1];checkInt64(stat.size);HEAP32[buf+32>>2]=4096;checkInt32(4096);HEAP32[buf+36>>2]=stat.blocks;checkInt32(stat.blocks);var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();tempI64=[Math.floor(atime/1e3)>>>0,(tempDouble=Math.floor(atime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];checkInt64(Math.floor(atime/1e3));HEAPU32[buf+48>>2]=atime%1e3*1e3;checkInt32(atime%1e3*1e3);tempI64=[Math.floor(mtime/1e3)>>>0,(tempDouble=Math.floor(mtime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+56>>2]=tempI64[0],HEAP32[buf+60>>2]=tempI64[1];checkInt64(Math.floor(mtime/1e3));HEAPU32[buf+64>>2]=mtime%1e3*1e3;checkInt32(mtime%1e3*1e3);tempI64=[Math.floor(ctime/1e3)>>>0,(tempDouble=Math.floor(ctime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+72>>2]=tempI64[0],HEAP32[buf+76>>2]=tempI64[1];checkInt64(Math.floor(ctime/1e3));HEAPU32[buf+80>>2]=ctime%1e3*1e3;checkInt32(ctime%1e3*1e3);tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+88>>2]=tempI64[0],HEAP32[buf+92>>2]=tempI64[1];checkInt64(stat.ino);return 0},doMsync:function(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},varargs:undefined,get(){assert(SYSCALLS.varargs!=undefined);SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStreamChecked(fd);return stream}};function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.createStream(stream,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 5:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;checkInt16(2);return 0}case 6:case 7:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:{if(!stream.tty)return-59;return 0}case 21505:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcgets){var termios=stream.tty.ops.ioctl_tcgets(stream);var argp=SYSCALLS.get();HEAP32[argp>>2]=termios.c_iflag||0;checkInt32(termios.c_iflag||0);HEAP32[argp+4>>2]=termios.c_oflag||0;checkInt32(termios.c_oflag||0);HEAP32[argp+8>>2]=termios.c_cflag||0;checkInt32(termios.c_cflag||0);HEAP32[argp+12>>2]=termios.c_lflag||0;checkInt32(termios.c_lflag||0);for(var i=0;i<32;i++){HEAP8[argp+i+17>>0]=termios.c_cc[i]||0;checkInt8(termios.c_cc[i]||0)}return 0}return 0}case 21510:case 21511:case 21512:{if(!stream.tty)return-59;return 0}case 21506:case 21507:case 21508:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcsets){var argp=SYSCALLS.get();var c_iflag=HEAP32[argp>>2];var c_oflag=HEAP32[argp+4>>2];var c_cflag=HEAP32[argp+8>>2];var c_lflag=HEAP32[argp+12>>2];var c_cc=[];for(var i=0;i<32;i++){c_cc.push(HEAP8[argp+i+17>>0])}return stream.tty.ops.ioctl_tcsets(stream.tty,op,{c_iflag:c_iflag,c_oflag:c_oflag,c_cflag:c_cflag,c_lflag:c_lflag,c_cc:c_cc})}return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;checkInt32(0);return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tiocgwinsz){var winsize=stream.tty.ops.ioctl_tiocgwinsz(stream.tty);var argp=SYSCALLS.get();HEAP16[argp>>1]=winsize[0];checkInt16(winsize[0]);HEAP16[argp+2>>1]=winsize[1];checkInt16(winsize[1])}return 0}case 21524:{if(!stream.tty)return-59;return 0}case 21515:{if(!stream.tty)return-59;return 0}default:return-28}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?SYSCALLS.get():0;return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___throw_exception_with_stack_trace(ex){var e=new WebAssembly.Exception(getCppExceptionTag(),[ex],{traceStack:true});e.message=getExceptionMessage(e);if(e.stack){var arr=e.stack.split("\n");arr.splice(1,1);e.stack=arr.join("\n")}throw e}var structRegistrations={};function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAP32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach((function(type){typeDependencies[type]=dependentTypes}));function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push((()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}}))}}));if(0===unregisteredTypes.length){onComplete(typeConverters)}}var __embind_finalize_value_object=function(structType){var reg=structRegistrations[structType];delete structRegistrations[structType];var rawConstructor=reg.rawConstructor;var rawDestructor=reg.rawDestructor;var fieldRecords=reg.fields;var fieldTypes=fieldRecords.map((field=>field.getterReturnType)).concat(fieldRecords.map((field=>field.setterArgumentType)));whenDependentTypesAreResolved([structType],fieldTypes,(fieldTypes=>{var fields={};fieldRecords.forEach(((field,i)=>{var fieldName=field.fieldName;var getterReturnType=fieldTypes[i];var getter=field.getter;var getterContext=field.getterContext;var setterArgumentType=fieldTypes[i+fieldRecords.length];var setter=field.setter;var setterContext=field.setterContext;fields[fieldName]={read:ptr=>getterReturnType["fromWireType"](getter(getterContext,ptr)),write:(ptr,o)=>{var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,o));runDestructors(destructors)}}}));return[{name:reg.name,"fromWireType":function(ptr){var rv={};for(var i in fields){rv[i]=fields[i].read(ptr)}rawDestructor(ptr);return rv},"toWireType":function(destructors,o){for(var fieldName in fields){if(!(fieldName in o)){throw new TypeError(`Missing field: "${fieldName}"`)}}var ptr=rawConstructor();for(fieldName in fields){fields[fieldName].write(ptr,o[fieldName])}if(destructors!==null){destructors.push(rawDestructor,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:rawDestructor}]}))};function __embind_register_bigint(primitiveType,name,size,minRange,maxRange){}function getShiftFromSize(size){switch(size){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError(`Unknown type size: ${size}`)}}function embind_init_charCodes(){var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes}var embind_charCodes=undefined;function readLatin1String(ptr){var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}function sharedRegisterType(rawType,registeredInstance,options={}){var name=registeredInstance.name;if(!rawType){throwBindingError(`type "${name}" must have a positive integer typeid pointer`)}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError(`Cannot register type '${name}' twice`)}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach((cb=>cb()))}}function registerType(rawType,registeredInstance,options={}){if(!("argPackAdvance"in registeredInstance)){throw new TypeError("registerType registeredInstance requires argPackAdvance")}return sharedRegisterType(rawType,registeredInstance,options)}function __embind_register_bool(rawType,name,size,trueValue,falseValue){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(wt){return!!wt},"toWireType":function(destructors,o){return o?trueValue:falseValue},"argPackAdvance":8,"readValueFromPointer":function(pointer){var heap;if(size===1){heap=HEAP8}else if(size===2){heap=HEAP16}else if(size===4){heap=HEAP32}else{throw new TypeError("Unknown boolean type size: "+name)}return this["fromWireType"](heap[pointer>>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationRegistry=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}var registeredPointers={};function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}var delayFunction=undefined;function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}var attachFinalizer=function(handle){if("undefined"===typeof FinalizationRegistry){attachFinalizer=handle=>handle;return handle}finalizationRegistry=new FinalizationRegistry((info=>{console.warn(info.leakWarning.stack.replace(/^Error: /,""));releaseClassHandle(info.$$)}));attachFinalizer=handle=>{var $$=handle.$$;var hasSmartPtr=!!$$.smartPtr;if(hasSmartPtr){var info={$$:$$};var cls=$$.ptrType.registeredClass;info.leakWarning=new Error(`Embind found a leaked C++ instance ${cls.name} <${ptrToString($$.ptr)}>.\n`+"We'll free it automatically in this case, but this functionality is not reliable across various environments.\n"+"Make sure to invoke .delete() manually once you're done with the instance instead.\n"+"Originally allocated");if("captureStackTrace"in Error){Error.captureStackTrace(info.leakWarning,RegisteredPointer_fromWireType)}finalizationRegistry.register(handle,info,handle)}return handle};detachFinalizer=handle=>finalizationRegistry.unregister(handle);return attachFinalizer(handle)};function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return`_${name}`}return name}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return{[name]:function(){return body.apply(this,arguments)}}[name]}function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${arguments.length}) - expects one of (${proto[methodName].overloadTable})!`)}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError(`Cannot register public name '${name}' twice`)}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`)}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError(`Expected null or instance of ${desiredClass.name}, got an instance of ${ptrClass.name}`)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,Emval.toHandle((function(){clonedHandle["delete"]()})));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}var dynCallLegacy=(sig,ptr,args)=>{assert("dynCall_"+sig in Module,`bad function pointer type - dynCall function not found for sig '${sig}'`);if(args&&args.length){assert(args.length===sig.substring(1).replace(/j/g,"--").length)}else{assert(sig.length==1)}var f=Module["dynCall_"+sig];return args&&args.length?f.apply(null,[ptr].concat(args)):f.call(null,ptr)};var wasmTableMirror=[];var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}assert(wasmTable.get(funcPtr)==func,"JavaScript-side Wasm function table mirror is out of date!");return func};var dynCall=(sig,ptr,args)=>{if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}assert(getWasmTableEntry(ptr),`missing table entry in dynCall: ${ptr}`);var rtn=getWasmTableEntry(ptr).apply(null,args);return rtn};var getDynCaller=(sig,ptr)=>{assert(sig.includes("j")||sig.includes("p"),"getDynCaller should only be called with i64 sigs");var argCache=[];return function(){argCache.length=0;Object.assign(argCache,arguments);return dynCall(sig,ptr,argCache)}};function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(){if(signature.includes("j")){return getDynCaller(signature,rawFunction)}return getWasmTableEntry(rawFunction)}var fp=makeDynCaller();if(typeof fp!="function"){throwBindingError(`unknown function pointer with signature ${signature}: ${rawFunction}`)}return fp}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,(function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}}));errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return`${this.name}: ${this.message}`}};return errorClass}var UnboundTypeError=undefined;function getTypeName(type){var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv}function throwUnboundTypeError(message,types){var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(`${message}: `+unboundTypes.map(getTypeName).join([", "]))}function __embind_register_class(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor){name=readLatin1String(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);if(upcast){upcast=embind__requireFunction(upcastSignature,upcast)}if(downcast){downcast=embind__requireFunction(downcastSignature,downcast)}rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,(function(){throwUnboundTypeError(`Cannot construct ${name} due to unbound types`,[baseClassRawType])}));whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],(function(base){base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(legalFunctionName,(function(){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError("Use 'new' to construct "+name)}if(undefined===registeredClass.constructor_body){throw new BindingError(name+" has no accessible constructor")}var body=registeredClass.constructor_body[arguments.length];if(undefined===body){throw new BindingError(`Tried to invoke ctor of ${name} with invalid number of parameters (${arguments.length}) - expected (${Object.keys(registeredClass.constructor_body).toString()}) parameters instead!`)}return body.apply(this,arguments)}));var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);if(registeredClass.baseClass){if(registeredClass.baseClass.__derivedClasses===undefined){registeredClass.baseClass.__derivedClasses=[]}registeredClass.baseClass.__derivedClasses.push(registeredClass)}var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+"*",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+" const*",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]}))}function heap32VectorToArray(count,firstElement){var array=[];for(var i=0;i>2])}return array}function newFunc(constructor,argumentList){if(!(constructor instanceof Function)){throw new TypeError(`new_ called with constructor type ${typeof constructor} which is not a function`)}var dummy=createNamedFunction(constructor.name||"unknownFunctionName",(function(){}));dummy.prototype=constructor.prototype;var obj=new dummy;var r=constructor.apply(obj,argumentList);return r instanceof Object?r:obj}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc,isAsync){var argCount=argTypes.length;if(argCount<2){throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")}assert(!isAsync,"Async bindings are only supported with JSPI.");var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i0?", ":"")+argsListWired}invokerFnBody+=(returns||isAsync?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],(function(classType){classType=classType[0];var humanName=`constructor ${classType.name}`;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError(`Cannot register multiple constructors with identical number of parameters (${argCount-1}) for class '${classType.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!`)}classType.registeredClass.constructor_body[argCount-1]=()=>{throwUnboundTypeError(`Cannot construct ${classType.name} due to unbound types`,rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,(function(argTypes){argTypes.splice(1,0,null);classType.registeredClass.constructor_body[argCount-1]=craftInvokerFunction(humanName,argTypes,null,invoker,rawConstructor);return[]}));return[]}))}function __embind_register_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual,isAsync){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],(function(classType){classType=classType[0];var humanName=`${classType.name}.${methodName}`;if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError(`Cannot call ${humanName} due to unbound types`,rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,(function(argTypes){var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context,isAsync);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]}));return[]}))}function handleAllocatorInit(){Object.assign(HandleAllocator.prototype,{get(id){assert(this.allocated[id]!==undefined,`invalid handle: ${id}`);return this.allocated[id]},has(id){return this.allocated[id]!==undefined},allocate(handle){var id=this.freelist.pop()||this.allocated.length;this.allocated[id]=handle;return id},free(id){assert(this.allocated[id]!==undefined);this.allocated[id]=undefined;this.freelist.push(id)}})}function HandleAllocator(){this.allocated=[undefined];this.freelist=[]}var emval_handles=new HandleAllocator;function __emval_decref(handle){if(handle>=emval_handles.reserved&&0===--emval_handles.get(handle).refcount){emval_handles.free(handle)}}function count_emval_handles(){var count=0;for(var i=emval_handles.reserved;i{if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handles.get(handle).value},toHandle:value=>{switch(value){case undefined:return 1;case null:return 2;case true:return 3;case false:return 4;default:{return emval_handles.allocate({refcount:1,value:value})}}}};function __embind_register_emval(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(handle){var rv=Emval.toValue(handle);__emval_decref(handle);return rv},"toWireType":function(destructors,value){return Emval.toHandle(value)},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})}function embindRepr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!="number"&&typeof value!="boolean"){throw new TypeError(`Cannot convert ${embindRepr(value)} to ${this.name}`)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn,isAsync){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,(function(){throwUnboundTypeError(`Cannot call ${name} due to unbound types`,argTypes)}),argCount-1);whenDependentTypesAreResolved([],argTypes,(function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn,isAsync),argCount-1);return[]}))}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=value=>value;if(minRange===0){var bitshift=32-8*size;fromWireType=value=>value<>>bitshift}var isUnsignedType=name.includes("unsigned");var checkAssertions=(value,toTypeName)=>{if(typeof value!="number"&&typeof value!="boolean"){throw new TypeError(`Cannot convert "${embindRepr(value)}" to ${toTypeName}`)}if(valuemaxRange){throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!`)}};var toWireType;if(isUnsignedType){toWireType=function(destructors,value){checkAssertions(value,this.name);return value>>>0}}else{toWireType=function(destructors,value){checkAssertions(value,this.name);return value}}registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":toWireType,"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(heap.buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;checkInt32(length);if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+i]=charCode}}else{for(var i=0;i{assert(ptr%2==0,"Pointer passed to UTF16ToString must be aligned to two bytes!");var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder)return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr));var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str};var stringToUTF16=(str,outPtr,maxBytesToWrite)=>{assert(outPtr%2==0,"Pointer passed to stringToUTF16 must be aligned to two bytes!");assert(typeof maxBytesToWrite=="number","stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;checkInt16(codeUnit);outPtr+=2}HEAP16[outPtr>>1]=0;checkInt16(0);return outPtr-startPtr};var lengthBytesUTF16=str=>str.length*2;var UTF32ToString=(ptr,maxBytesToRead)=>{assert(ptr%4==0,"Pointer passed to UTF32ToString must be aligned to four bytes!");var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str};var stringToUTF32=(str,outPtr,maxBytesToWrite)=>{assert(outPtr%4==0,"Pointer passed to stringToUTF32 must be aligned to four bytes!");assert(typeof maxBytesToWrite=="number","stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;checkInt32(codeUnit);outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;checkInt32(0);return outPtr-startPtr};var lengthBytesUTF32=str=>{var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len};var __embind_register_std_wstring=function(rawType,charSize,name){name=readLatin1String(name);var decodeString,encodeString,getHeap,lengthBytesUTF,shift;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;getHeap=()=>HEAPU16;shift=1}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;getHeap=()=>HEAPU32;shift=2}registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value=="string")){throwBindingError(`Cannot pass non-string to C++ string type ${name}`)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})};function __embind_register_value_object(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}}function __embind_register_value_object_field(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function __emval_incref(handle){if(handle>4){emval_handles.get(handle).refcount+=1}}function requireRegisteredType(rawType,humanName){var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl}function __emval_take_value(type,arg){type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](arg);return Emval.toHandle(v)}var _abort=()=>{abort("native code called abort()")};var _emscripten_memcpy_big=(dest,src,num)=>HEAPU8.copyWithin(dest,src,src+num);var getHeapMax=()=>2147483648;var _emscripten_get_now;_emscripten_get_now=()=>performance.now();var growMemory=size=>{var b=wasmMemory.buffer;var pages=size-b.byteLength+65535>>>16;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){err(`growMemory: Attempted to grow heap from ${b.byteLength} bytes to ${size} bytes, but got error: ${e}`)}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;assert(requestedSize>oldSize);var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){err(`Cannot enlarge memory, asked to go up to ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!`);return false}var alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var t0=_emscripten_get_now();var replacement=growMemory(newSize);var t1=_emscripten_get_now();out(`Heap resize call from ${oldSize} to ${newSize} took ${t1-t0} msecs. Success: ${!!replacement}`);if(replacement){return true}}err(`Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!`);return false};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var stringToAscii=(str,buffer)=>{for(var i=0;i>0]=str.charCodeAt(i);checkInt8(str.charCodeAt(i))}HEAP8[buffer>>0]=0;checkInt8(0)};var _environ_get=(__environ,environ_buf)=>{var bufSize=0;getEnvStrings().forEach((function(string,i){var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>2]=ptr;checkInt32(ptr);stringToAscii(string,ptr);bufSize+=string.length+1}));return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;checkInt32(strings.length);var bufSize=0;strings.forEach((function(string){bufSize+=string.length+1}));HEAPU32[penviron_buf_size>>2]=bufSize;checkInt32(bufSize);return 0};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;checkInt32(num);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}function convertI32PairToI53Checked(lo,hi){assert(lo==lo>>>0||lo==(lo|0));assert(hi===(hi|0));return hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];checkInt64(stream.position);if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(typeof offset!=="undefined"){offset+=curr}}return ret};function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=doWritev(stream,iov,iovcnt);HEAPU32[pnum>>2]=num;checkInt32(num);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var arraySum=(array,index)=>{var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum};var MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];var addDays=(date,days)=>{var newDate=new Date(date.getTime());while(days>0){var leap=isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate};var writeArrayToMemory=(array,buffer)=>{assert(array.length>=0,"writeArrayToMemory array must have a length (should be an array or typed array)");HEAP8.set(array,buffer)};var _strftime=(s,maxsize,format,tm)=>{var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value=="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}return thisDate.getFullYear()}return thisDate.getFullYear()-1}var EXPANSION_RULES_2={"%a":date=>WEEKDAYS[date.tm_wday].substring(0,3),"%A":date=>WEEKDAYS[date.tm_wday],"%b":date=>MONTHS[date.tm_mon].substring(0,3),"%B":date=>MONTHS[date.tm_mon],"%C":date=>{var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":date=>leadingNulls(date.tm_mday,2),"%e":date=>leadingSomething(date.tm_mday,2," "),"%g":date=>getWeekBasedYear(date).toString().substring(2),"%G":date=>getWeekBasedYear(date),"%H":date=>leadingNulls(date.tm_hour,2),"%I":date=>{var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":date=>leadingNulls(date.tm_mday+arraySum(isLeapYear(date.tm_year+1900)?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR,date.tm_mon-1),3),"%m":date=>leadingNulls(date.tm_mon+1,2),"%M":date=>leadingNulls(date.tm_min,2),"%n":()=>"\n","%p":date=>{if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}return"PM"},"%S":date=>leadingNulls(date.tm_sec,2),"%t":()=>"\t","%u":date=>date.tm_wday||7,"%U":date=>{var days=date.tm_yday+7-date.tm_wday;return leadingNulls(Math.floor(days/7),2)},"%V":date=>{var val=Math.floor((date.tm_yday+7-(date.tm_wday+6)%7)/7);if((date.tm_wday+371-date.tm_yday-2)%7<=2){val++}if(!val){val=52;var dec31=(date.tm_wday+7-date.tm_yday-1)%7;if(dec31==4||dec31==5&&isLeapYear(date.tm_year%400-1)){val++}}else if(val==53){var jan1=(date.tm_wday+371-date.tm_yday)%7;if(jan1!=4&&(jan1!=3||!isLeapYear(date.tm_year)))val=1}return leadingNulls(val,2)},"%w":date=>date.tm_wday,"%W":date=>{var days=date.tm_yday+7-(date.tm_wday+6)%7;return leadingNulls(Math.floor(days/7),2)},"%y":date=>(date.tm_year+1900).toString().substring(2),"%Y":date=>date.tm_year+1900,"%z":date=>{var off=date.tm_gmtoff;var ahead=off>=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":date=>date.tm_zone,"%%":()=>"%"};pattern=pattern.replace(/%%/g,"\0\0");for(var rule in EXPANSION_RULES_2){if(pattern.includes(rule)){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}pattern=pattern.replace(/\0\0/g,"%");var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1};var _strftime_l=(s,maxsize,format,tm,loc)=>_strftime(s,maxsize,format,tm);var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.createPreloadedFile=FS_createPreloadedFile;FS.staticInit();Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_unlink"]=FS.unlink;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createDevice"]=FS.createDevice;if(ENVIRONMENT_IS_NODE){NODEFS.staticInit()}ERRNO_CODES={"EPERM":63,"ENOENT":44,"ESRCH":71,"EINTR":27,"EIO":29,"ENXIO":60,"E2BIG":1,"ENOEXEC":45,"EBADF":8,"ECHILD":12,"EAGAIN":6,"EWOULDBLOCK":6,"ENOMEM":48,"EACCES":2,"EFAULT":21,"ENOTBLK":105,"EBUSY":10,"EEXIST":20,"EXDEV":75,"ENODEV":43,"ENOTDIR":54,"EISDIR":31,"EINVAL":28,"ENFILE":41,"EMFILE":33,"ENOTTY":59,"ETXTBSY":74,"EFBIG":22,"ENOSPC":51,"ESPIPE":70,"EROFS":69,"EMLINK":34,"EPIPE":64,"EDOM":18,"ERANGE":68,"ENOMSG":49,"EIDRM":24,"ECHRNG":106,"EL2NSYNC":156,"EL3HLT":107,"EL3RST":108,"ELNRNG":109,"EUNATCH":110,"ENOCSI":111,"EL2HLT":112,"EDEADLK":16,"ENOLCK":46,"EBADE":113,"EBADR":114,"EXFULL":115,"ENOANO":104,"EBADRQC":103,"EBADSLT":102,"EDEADLOCK":16,"EBFONT":101,"ENOSTR":100,"ENODATA":116,"ETIME":117,"ENOSR":118,"ENONET":119,"ENOPKG":120,"EREMOTE":121,"ENOLINK":47,"EADV":122,"ESRMNT":123,"ECOMM":124,"EPROTO":65,"EMULTIHOP":36,"EDOTDOT":125,"EBADMSG":9,"ENOTUNIQ":126,"EBADFD":127,"EREMCHG":128,"ELIBACC":129,"ELIBBAD":130,"ELIBSCN":131,"ELIBMAX":132,"ELIBEXEC":133,"ENOSYS":52,"ENOTEMPTY":55,"ENAMETOOLONG":37,"ELOOP":32,"EOPNOTSUPP":138,"EPFNOSUPPORT":139,"ECONNRESET":15,"ENOBUFS":42,"EAFNOSUPPORT":5,"EPROTOTYPE":67,"ENOTSOCK":57,"ENOPROTOOPT":50,"ESHUTDOWN":140,"ECONNREFUSED":14,"EADDRINUSE":3,"ECONNABORTED":13,"ENETUNREACH":40,"ENETDOWN":38,"ETIMEDOUT":73,"EHOSTDOWN":142,"EHOSTUNREACH":23,"EINPROGRESS":26,"EALREADY":7,"EDESTADDRREQ":17,"EMSGSIZE":35,"EPROTONOSUPPORT":66,"ESOCKTNOSUPPORT":137,"EADDRNOTAVAIL":4,"ENETRESET":39,"EISCONN":30,"ENOTCONN":53,"ETOOMANYREFS":141,"EUSERS":136,"EDQUOT":19,"ESTALE":72,"ENOTSUP":138,"ENOMEDIUM":148,"EILSEQ":25,"EOVERFLOW":61,"ECANCELED":11,"ENOTRECOVERABLE":56,"EOWNERDEAD":62,"ESTRPIPE":135};InternalError=Module["InternalError"]=class InternalError extends Error{constructor(message){super(message);this.name="InternalError"}};embind_init_charCodes();BindingError=Module["BindingError"]=class BindingError extends Error{constructor(message){super(message);this.name="BindingError"}};init_ClassHandle();init_embind();init_RegisteredPointer();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");handleAllocatorInit();init_emval();function checkIncomingModuleAPI(){ignoredModuleProp("fetchSettings")}var wasmImports={__assert_fail:___assert_fail,__handle_stack_overflow:___handle_stack_overflow,__syscall_fcntl64:___syscall_fcntl64,__syscall_ioctl:___syscall_ioctl,__syscall_openat:___syscall_openat,__throw_exception_with_stack_trace:___throw_exception_with_stack_trace,_embind_finalize_value_object:__embind_finalize_value_object,_embind_register_bigint:__embind_register_bigint,_embind_register_bool:__embind_register_bool,_embind_register_class:__embind_register_class,_embind_register_class_constructor:__embind_register_class_constructor,_embind_register_class_function:__embind_register_class_function,_embind_register_emval:__embind_register_emval,_embind_register_float:__embind_register_float,_embind_register_function:__embind_register_function,_embind_register_integer:__embind_register_integer,_embind_register_memory_view:__embind_register_memory_view,_embind_register_std_string:__embind_register_std_string,_embind_register_std_wstring:__embind_register_std_wstring,_embind_register_value_object:__embind_register_value_object,_embind_register_value_object_field:__embind_register_value_object_field,_embind_register_void:__embind_register_void,_emval_decref:__emval_decref,_emval_incref:__emval_incref,_emval_take_value:__emval_take_value,abort:_abort,emscripten_memcpy_big:_emscripten_memcpy_big,emscripten_resize_heap:_emscripten_resize_heap,environ_get:_environ_get,environ_sizes_get:_environ_sizes_get,fd_close:_fd_close,fd_read:_fd_read,fd_seek:_fd_seek,fd_write:_fd_write,strftime_l:_strftime_l};var asm=createWasm();var ___wasm_call_ctors=createExportWrapper("__wasm_call_ctors");var _malloc=createExportWrapper("malloc");var _fflush=Module["_fflush"]=createExportWrapper("fflush");var _free=Module["_free"]=createExportWrapper("free");var ___errno_location=createExportWrapper("__errno_location");var ___getTypeName=createExportWrapper("__getTypeName");var __embind_initialize_bindings=Module["__embind_initialize_bindings"]=createExportWrapper("_embind_initialize_bindings");var _emscripten_builtin_memalign=createExportWrapper("emscripten_builtin_memalign");var ___trap=function(){return(___trap=Module["asm"]["__trap"]).apply(null,arguments)};var setTempRet0=createExportWrapper("setTempRet0");var _emscripten_stack_init=function(){return(_emscripten_stack_init=Module["asm"]["emscripten_stack_init"]).apply(null,arguments)};var _emscripten_stack_get_free=function(){return(_emscripten_stack_get_free=Module["asm"]["emscripten_stack_get_free"]).apply(null,arguments)};var _emscripten_stack_get_base=function(){return(_emscripten_stack_get_base=Module["asm"]["emscripten_stack_get_base"]).apply(null,arguments)};var _emscripten_stack_get_end=function(){return(_emscripten_stack_get_end=Module["asm"]["emscripten_stack_get_end"]).apply(null,arguments)};var stackSave=createExportWrapper("stackSave");var stackRestore=createExportWrapper("stackRestore");var stackAlloc=createExportWrapper("stackAlloc");var _emscripten_stack_get_current=function(){return(_emscripten_stack_get_current=Module["asm"]["emscripten_stack_get_current"]).apply(null,arguments)};var ___cxa_decrement_exception_refcount=Module["___cxa_decrement_exception_refcount"]=createExportWrapper("__cxa_decrement_exception_refcount");var ___cxa_increment_exception_refcount=Module["___cxa_increment_exception_refcount"]=createExportWrapper("__cxa_increment_exception_refcount");var ___cxa_demangle=createExportWrapper("__cxa_demangle");var ___thrown_object_from_unwind_exception=Module["___thrown_object_from_unwind_exception"]=createExportWrapper("__thrown_object_from_unwind_exception");var ___get_exception_message=Module["___get_exception_message"]=createExportWrapper("__get_exception_message");var ___set_stack_limits=Module["___set_stack_limits"]=createExportWrapper("__set_stack_limits");var dynCall_jiji=Module["dynCall_jiji"]=createExportWrapper("dynCall_jiji");var dynCall_viijii=Module["dynCall_viijii"]=createExportWrapper("dynCall_viijii");var dynCall_iiiiij=Module["dynCall_iiiiij"]=createExportWrapper("dynCall_iiiiij");var dynCall_iiiiijj=Module["dynCall_iiiiijj"]=createExportWrapper("dynCall_iiiiijj");var dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=createExportWrapper("dynCall_iiiiiijj");function intArrayFromBase64(s){if(typeof ENVIRONMENT_IS_NODE!="undefined"&&ENVIRONMENT_IS_NODE){var buf=Buffer.from(s,"base64");return new Uint8Array(buf["buffer"],buf["byteOffset"],buf["byteLength"])}try{var decoded=atob(s);var bytes=new Uint8Array(decoded.length);for(var i=0;i0){return}stackCheckInit();preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();assert(!Module["_main"],'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]');postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}checkStackCookie()}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); +var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject}));["_main","getExceptionMessage","___get_exception_message","_free","___cpp_exception","___cxa_increment_exception_refcount","___cxa_decrement_exception_refcount","___thrown_object_from_unwind_exception","_fflush","__embind_initialize_bindings","___set_stack_limits","onRuntimeInitialized"].forEach((prop=>{if(!Object.getOwnPropertyDescriptor(Module["ready"],prop)){Object.defineProperty(Module["ready"],prop,{get:()=>abort("You are getting "+prop+" on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js"),set:()=>abort("You are setting "+prop+" on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")})}}));if(!Module.expectedDataFileDownloads){Module.expectedDataFileDownloads=0}Module.expectedDataFileDownloads++;(function(){if(Module["ENVIRONMENT_IS_PTHREAD"]||Module["$ww"])return;var loadPackage=function(metadata){var PACKAGE_PATH="";if(typeof window==="object"){PACKAGE_PATH=window["encodeURIComponent"](window.location.pathname.toString().substring(0,window.location.pathname.toString().lastIndexOf("/"))+"/")}else if(typeof process==="undefined"&&typeof location!=="undefined"){PACKAGE_PATH=encodeURIComponent(location.pathname.toString().substring(0,location.pathname.toString().lastIndexOf("/"))+"/")}var PACKAGE_NAME="privateer.data";var REMOTE_PACKAGE_BASE="privateer.data";if(typeof Module["locateFilePackage"]==="function"&&!Module["locateFile"]){Module["locateFile"]=Module["locateFilePackage"];err("warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)")}var REMOTE_PACKAGE_NAME=Module["locateFile"]?Module["locateFile"](REMOTE_PACKAGE_BASE,""):REMOTE_PACKAGE_BASE;var REMOTE_PACKAGE_SIZE=metadata["remote_package_size"];function fetchRemotePackage(packageName,packageSize,callback,errback){if(typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string"){require("fs").readFile(packageName,(function(err,contents){if(err){errback(err)}else{callback(contents.buffer)}}));return}var xhr=new XMLHttpRequest;xhr.open("GET",packageName,true);xhr.responseType="arraybuffer";xhr.onprogress=function(event){var url=packageName;var size=packageSize;if(event.total)size=event.total;if(event.loaded){if(!xhr.addedTotal){xhr.addedTotal=true;if(!Module.dataFileDownloads)Module.dataFileDownloads={};Module.dataFileDownloads[url]={loaded:event.loaded,total:size}}else{Module.dataFileDownloads[url].loaded=event.loaded}var total=0;var loaded=0;var num=0;for(var download in Module.dataFileDownloads){var data=Module.dataFileDownloads[download];total+=data.total;loaded+=data.loaded;num++}total=Math.ceil(total*Module.expectedDataFileDownloads/num);if(Module["setStatus"])Module["setStatus"](`Downloading data... (${loaded}/${total})`)}else if(!Module.dataFileDownloads){if(Module["setStatus"])Module["setStatus"]("Downloading data...")}};xhr.onerror=function(event){throw new Error("NetworkError for: "+packageName)};xhr.onload=function(event){if(xhr.status==200||xhr.status==304||xhr.status==206||xhr.status==0&&xhr.response){var packageData=xhr.response;callback(packageData)}else{throw new Error(xhr.statusText+" : "+xhr.responseURL)}};xhr.send(null)}function handleError(error){console.error("package error:",error)}var fetchedCallback=null;var fetched=Module["getPreloadedPackage"]?Module["getPreloadedPackage"](REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE):null;if(!fetched)fetchRemotePackage(REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE,(function(data){if(fetchedCallback){fetchedCallback(data);fetchedCallback=null}else{fetched=data}}),handleError);function runWithFS(){function assert(check,msg){if(!check)throw msg+(new Error).stack}Module["FS_createPath"]("/","unprocessed_files",true,true);function DataRequest(start,end,audio){this.start=start;this.end=end;this.audio=audio}DataRequest.prototype={requests:{},open:function(mode,name){this.name=name;this.requests[name]=this;Module["addRunDependency"](`fp ${this.name}`)},send:function(){},onload:function(){var byteArray=this.byteArray.subarray(this.start,this.end);this.finish(byteArray)},finish:function(byteArray){var that=this;Module["FS_createDataFile"](this.name,null,byteArray,true,true,true);Module["removeRunDependency"](`fp ${that.name}`);this.requests[this.name]=null}};var files=metadata["files"];for(var i=0;i{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";var ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(Module["ENVIRONMENT"]){throw new Error("Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)")}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_NODE){if(typeof process=="undefined"||!process.release||process.release.name!=="node")throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");var nodeVersion=process.versions.node;var numericVersion=nodeVersion.split(".").slice(0,3);numericVersion=numericVersion[0]*1e4+numericVersion[1]*100+numericVersion[2].split("-")[0]*1;if(numericVersion<16e4){throw new Error("This emscripten-generated code requires node v16.0.0 (detected v"+nodeVersion+")")}const{createRequire:createRequire}=await import("module");var require=createRequire(import.meta.url);var fs=require("fs");var nodePath=require("path");if(ENVIRONMENT_IS_WORKER){scriptDirectory=nodePath.dirname(scriptDirectory)+"/"}else{scriptDirectory=require("url").fileURLToPath(new URL("./",import.meta.url))}read_=(filename,binary)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);return fs.readFileSync(filename,binary?undefined:"utf8")};readBinary=filename=>{var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};readAsync=(filename,onload,onerror,binary=true)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);fs.readFile(filename,binary?undefined:"utf8",((err,data)=>{if(err)onerror(err);else onload(binary?data.buffer:data)}))};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow};Module["inspect"]=()=>"[Emscripten Module object]"}else if(ENVIRONMENT_IS_SHELL){if(typeof process=="object"&&typeof require==="function"||typeof window=="object"||typeof importScripts=="function")throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");if(typeof read!="undefined"){read_=f=>read(f)}readBinary=f=>{let data;if(typeof readbuffer=="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data=="object");return data};readAsync=(f,onload,onerror)=>{setTimeout((()=>onload(readBinary(f))))};if(typeof clearTimeout=="undefined"){globalThis.clearTimeout=id=>{}}if(typeof setTimeout=="undefined"){globalThis.setTimeout=f=>typeof f=="function"?f():abort()}if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit=="function"){quit_=(status,toThrow)=>{setTimeout((()=>{if(!(toThrow instanceof ExitStatus)){let toLog=toThrow;if(toThrow&&typeof toThrow=="object"&&toThrow.stack){toLog=[toThrow,toThrow.stack]}err(`exiting due to exception: ${toLog}`)}quit(status)}));throw toThrow}}if(typeof print!="undefined"){if(typeof console=="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}if(!(typeof window=="object"||typeof importScripts=="function"))throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=title=>document.title=title}else{throw new Error("environment detection error")}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;checkIncomingModuleAPI();if(Module["arguments"])arguments_=Module["arguments"];legacyModuleProp("arguments","arguments_");if(Module["thisProgram"])thisProgram=Module["thisProgram"];legacyModuleProp("thisProgram","thisProgram");if(Module["quit"])quit_=Module["quit"];legacyModuleProp("quit","quit_");assert(typeof Module["memoryInitializerPrefixURL"]=="undefined","Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["pthreadMainPrefixURL"]=="undefined","Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["cdInitializerPrefixURL"]=="undefined","Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["filePackagePrefixURL"]=="undefined","Module.filePackagePrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["read"]=="undefined","Module.read option was removed (modify read_ in JS)");assert(typeof Module["readAsync"]=="undefined","Module.readAsync option was removed (modify readAsync in JS)");assert(typeof Module["readBinary"]=="undefined","Module.readBinary option was removed (modify readBinary in JS)");assert(typeof Module["setWindowTitle"]=="undefined","Module.setWindowTitle option was removed (modify setWindowTitle in JS)");assert(typeof Module["TOTAL_MEMORY"]=="undefined","Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY");legacyModuleProp("read","read_");legacyModuleProp("readAsync","readAsync");legacyModuleProp("readBinary","readBinary");legacyModuleProp("setWindowTitle","setWindowTitle");assert(!ENVIRONMENT_IS_SHELL,"shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable.");var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];legacyModuleProp("wasmBinary","wasmBinary");var noExitRuntime=Module["noExitRuntime"]||false;legacyModuleProp("noExitRuntime","noExitRuntime");if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed"+(text?": "+text:""))}}var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b)}assert(!Module["STACK_SIZE"],"STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time");assert(typeof Int32Array!="undefined"&&typeof Float64Array!=="undefined"&&Int32Array.prototype.subarray!=undefined&&Int32Array.prototype.set!=undefined,"JS engine does not provide full typed array support");assert(!Module["wasmMemory"],"Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally");assert(!Module["INITIAL_MEMORY"],"Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically");var wasmTable;function writeStackCookie(){var max=_emscripten_stack_get_end();assert((max&3)==0);if(max==0){max+=4}HEAPU32[max>>2]=34821223;checkInt32(34821223);HEAPU32[max+4>>2]=2310721022;checkInt32(2310721022);HEAPU32[0>>2]=1668509029;checkInt32(1668509029)}function checkStackCookie(){if(ABORT)return;var max=_emscripten_stack_get_end();if(max==0){max+=4}var cookie1=HEAPU32[max>>2];var cookie2=HEAPU32[max+4>>2];if(cookie1!=34821223||cookie2!=2310721022){abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString(cookie2)} ${ptrToString(cookie1)}`)}if(HEAPU32[0>>2]!=1668509029){abort("Runtime error: The application has corrupted its heap memory area (address zero)!")}}(function(){var h16=new Int16Array(1);var h8=new Int8Array(h16.buffer);h16[0]=25459;if(h8[0]!==115||h8[1]!==99)throw"Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)"})();var __ATPRERUN__=[];var __ATINIT__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;var runtimeKeepaliveCounter=0;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){assert(!runtimeInitialized);runtimeInitialized=true;checkStackCookie();setStackLimits();if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();FS.ignorePermissions=false;TTY.init();callRuntimeCallbacks(__ATINIT__)}function postRun(){checkStackCookie();if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}assert(Math.imul,"This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.fround,"This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.clz32,"This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.trunc,"This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;var runDependencyTracking={};function getUniqueRunDependency(id){var orig=id;while(1){if(!runDependencyTracking[id])return id;id=orig+Math.random()}}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(!runDependencyTracking[id]);runDependencyTracking[id]=1;if(runDependencyWatcher===null&&typeof setInterval!="undefined"){runDependencyWatcher=setInterval((()=>{if(ABORT){clearInterval(runDependencyWatcher);runDependencyWatcher=null;return}var shown=false;for(var dep in runDependencyTracking){if(!shown){shown=true;err("still waiting on run dependencies:")}err("dependency: "+dep)}if(shown){err("(end of list)")}}),1e4)}}else{err("warning: run dependency added without ID")}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(runDependencyTracking[id]);delete runDependencyTracking[id]}else{err("warning: run dependency removed without ID")}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;if(runtimeInitialized){___trap()}var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}function isFileURI(filename){return filename.startsWith("file://")}function createExportWrapper(name,fixedasm){return function(){var displayName=name;var asm=fixedasm;if(!fixedasm){asm=Module["asm"]}assert(runtimeInitialized,"native function `"+displayName+"` called before runtime initialization");assert(!runtimeExited,"native function `"+displayName+"` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)");if(!asm[name]){assert(asm[name],"exported native function `"+displayName+"` not found")}return asm[name].apply(null,arguments)}}var wasmBinaryFile;if(Module["locateFile"]){wasmBinaryFile="privateer.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}}else{wasmBinaryFile=new URL("privateer.wasm",import.meta.url).href}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}function getBinaryPromise(binaryFile){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"&&!isFileURI(binaryFile)){return fetch(binaryFile,{credentials:"same-origin"}).then((response=>{if(!response["ok"]){throw"failed to load wasm binary file at '"+binaryFile+"'"}return response["arrayBuffer"]()})).catch((()=>getBinarySync(binaryFile)))}else if(readAsync){return new Promise(((resolve,reject)=>{readAsync(binaryFile,(response=>resolve(new Uint8Array(response))),reject)}))}}return Promise.resolve().then((()=>getBinarySync(binaryFile)))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then((binary=>WebAssembly.instantiate(binary,imports))).then((instance=>instance)).then(receiver,(reason=>{err("failed to asynchronously prepare wasm: "+reason);if(isFileURI(wasmBinaryFile)){err("warning: Loading from a file URI ("+wasmBinaryFile+") is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing")}abort(reason)}))}function instantiateAsync(binary,binaryFile,imports,callback){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then((response=>{var result=WebAssembly.instantiateStreaming(response,imports);return result.then(callback,(function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(binaryFile,imports,callback)}))}))}return instantiateArrayBuffer(binaryFile,imports,callback)}function createWasm(){var info={"env":wasmImports,"wasi_snapshot_preview1":wasmImports};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["memory"];assert(wasmMemory,"memory not found in wasm exports");updateMemoryViews();wasmTable=Module["asm"]["__indirect_function_table"];assert(wasmTable,"table not found in wasm exports");addOnInit(Module["asm"]["__wasm_call_ctors"]);removeRunDependency("wasm-instantiate");return exports}addRunDependency("wasm-instantiate");var trueModule=Module;function receiveInstantiationResult(result){assert(Module===trueModule,"the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?");trueModule=null;receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err("Module.instantiateWasm callback failed with error: "+e);readyPromiseReject(e)}}instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult).catch(readyPromiseReject);return{}}var tempDouble;var tempI64;function legacyModuleProp(prop,newName){if(!Object.getOwnPropertyDescriptor(Module,prop)){Object.defineProperty(Module,prop,{configurable:true,get(){abort("Module."+prop+" has been replaced with plain "+newName+" (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}}function ignoredModuleProp(prop){if(Object.getOwnPropertyDescriptor(Module,prop)){abort("`Module."+prop+"` was supplied but `"+prop+"` not included in INCOMING_MODULE_JS_API")}}function isExportedByForceFilesystem(name){return name==="FS_createPath"||name==="FS_createDataFile"||name==="FS_createPreloadedFile"||name==="FS_unlink"||name==="addRunDependency"||name==="FS_createLazyFile"||name==="FS_createDevice"||name==="removeRunDependency"}function missingGlobal(sym,msg){if(typeof globalThis!=="undefined"){Object.defineProperty(globalThis,sym,{configurable:true,get(){warnOnce("`"+sym+"` is not longer defined by emscripten. "+msg);return undefined}})}}missingGlobal("buffer","Please use HEAP8.buffer or wasmMemory.buffer");function missingLibrarySymbol(sym){if(typeof globalThis!=="undefined"&&!Object.getOwnPropertyDescriptor(globalThis,sym)){Object.defineProperty(globalThis,sym,{configurable:true,get(){var msg="`"+sym+"` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line";var librarySymbol=sym;if(!librarySymbol.startsWith("_")){librarySymbol="$"+sym}msg+=" (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='"+librarySymbol+"')";if(isExportedByForceFilesystem(sym)){msg+=". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"}warnOnce(msg);return undefined}})}unexportedRuntimeSymbol(sym)}function unexportedRuntimeSymbol(sym){if(!Object.getOwnPropertyDescriptor(Module,sym)){Object.defineProperty(Module,sym,{configurable:true,get(){var msg="'"+sym+"' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)";if(isExportedByForceFilesystem(sym)){msg+=". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"}abort(msg)}})}}var MAX_UINT8=2**8-1;var MAX_UINT16=2**16-1;var MAX_UINT32=2**32-1;var MAX_UINT53=2**53-1;var MAX_UINT64=2**64-1;var MIN_INT8=-(2**(8-1))+1;var MIN_INT16=-(2**(16-1))+1;var MIN_INT32=-(2**(32-1))+1;var MIN_INT53=-(2**(53-1))+1;var MIN_INT64=-(2**(64-1))+1;function checkInt(value,bits,min,max){assert(Number.isInteger(Number(value)),"attempt to write non-integer ("+value+") into integer heap");assert(value<=max,"value ("+value+") too large to write as "+bits+"-bit value");assert(value>=min,"value ("+value+") too small to write as "+bits+"-bit value")}var checkInt8=value=>checkInt(value,8,MIN_INT8,MAX_UINT8);var checkInt16=value=>checkInt(value,16,MIN_INT16,MAX_UINT16);var checkInt32=value=>checkInt(value,32,MIN_INT32,MAX_UINT32);var checkInt64=value=>checkInt(value,64,MIN_INT64,MAX_UINT64);function ExitStatus(status){this.name="ExitStatus";this.message=`Program terminated with exit(${status})`;this.status=status}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};function getCppExceptionTag(){return Module["asm"]["__cpp_exception"]}function getCppExceptionThrownObjectFromWebAssemblyException(ex){var unwind_header=ex.getArg(getCppExceptionTag(),0);return ___thrown_object_from_unwind_exception(unwind_header)}var withStackSave=f=>{var stack=stackSave();var ret=f();stackRestore(stack);return ret};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):undefined;var UTF8ArrayToString=(heapOrArray,idx,maxBytesToRead)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>{assert(typeof ptr=="number");return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""};var getExceptionMessageCommon=ptr=>withStackSave((()=>{var type_addr_addr=stackAlloc(4);var message_addr_addr=stackAlloc(4);___get_exception_message(ptr,type_addr_addr,message_addr_addr);var type_addr=HEAPU32[type_addr_addr>>2];var message_addr=HEAPU32[message_addr_addr>>2];var type=UTF8ToString(type_addr);_free(type_addr);var message;if(message_addr){message=UTF8ToString(message_addr);_free(message_addr)}return[type,message]}));function getExceptionMessage(ex){var ptr=getCppExceptionThrownObjectFromWebAssemblyException(ex);return getExceptionMessageCommon(ptr)}Module["getExceptionMessage"]=getExceptionMessage;var ptrToString=ptr=>{assert(typeof ptr==="number");ptr>>>=0;return"0x"+ptr.toString(16).padStart(8,"0")};var setStackLimits=()=>{var stackLow=_emscripten_stack_get_base();var stackHigh=_emscripten_stack_get_end();___set_stack_limits(stackLow,stackHigh)};var warnOnce=text=>{if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;if(ENVIRONMENT_IS_NODE)text="warning: "+text;err(text)}};var ___assert_fail=(condition,filename,line,func)=>{abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"])};var ___handle_stack_overflow=requested=>{var base=_emscripten_stack_get_base();var end=_emscripten_stack_get_end();abort(`stack overflow (Attempt to set SP to ${ptrToString(requested)}`+`, with stack limits [${ptrToString(end)} - ${ptrToString(base)}`+"]). If you require more stack space build with -sSTACK_SIZE=")};var setErrNo=value=>{HEAP32[___errno_location()>>2]=value;checkInt32(value);return value};var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter((p=>!!p)),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:path=>{if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},join:function(){var paths=Array.prototype.slice.call(arguments);return PATH.normalize(paths.join("/"))},join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>{if(typeof crypto=="object"&&typeof crypto["getRandomValues"]=="function"){return view=>crypto.getRandomValues(view)}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");var randomFillSync=crypto_module["randomFillSync"];if(randomFillSync){return view=>crypto_module["randomFillSync"](view)}var randomBytes=crypto_module["randomBytes"];return view=>(view.set(randomBytes(view.byteLength)),view)}catch(e){}}abort("no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: (array) => { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };")};var randomFill=view=>(randomFill=initRandomFill())(view);var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter((p=>!!p)),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{assert(typeof str==="string");if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;if(u>1114111)warnOnce("Invalid Unicode code point "+ptrToString(u)+" encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).");heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx};function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc(BUFSIZE);var bytesRead=0;var fd=process.stdin.fd;try{bytesRead=fs.readSync(fd,buf,0,BUFSIZE,-1)}catch(e){if(e.toString().includes("EOF"))bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init:function(){},shutdown:function(){},register:function(dev,ops){TTY.ttys[dev]={input:[],output:[],ops:ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open:function(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close:function(stream){stream.tty.ops.fsync(stream.tty)},fsync:function(stream){stream.tty.ops.fsync(stream.tty)},read:function(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}},ioctl_tcgets:function(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets:function(tty,optional_actions,data){return 0},ioctl_tiocgwinsz:function(tty){return[24,80]}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};var zeroMemory=(address,size)=>{HEAPU8.fill(0,address,address+size);return address};var alignMemory=(size,alignment)=>{assert(alignment,"alignment argument is required");return Math.ceil(size/alignment)*alignment};var mmapAlloc=size=>{size=alignMemory(size,65536);var ptr=_emscripten_builtin_memalign(65536,size);if(!ptr)return 0;return zeroMemory(ptr,size)};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){throw FS.genericErrors[44]},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp;old_node.parent=new_dir},unlink(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);assert(size>=0);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var dep=!noRunDep?getUniqueRunDependency(`al ${url}`):"";readAsync(url,(arrayBuffer=>{assert(arrayBuffer,`Loading data file "${url}" failed (no arrayBuffer).`);onload(new Uint8Array(arrayBuffer));if(dep)removeRunDependency(dep)}),(event=>{if(onerror){onerror()}else{throw`Loading data file "${url}" failed.`}}));if(dep)addRunDependency(dep)};var preloadPlugins=Module["preloadPlugins"]||[];function FS_handledByPreloadPlugin(byteArray,fullname,finish,onerror){if(typeof Browser!="undefined")Browser.init();var handled=false;preloadPlugins.forEach((function(plugin){if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,onerror);handled=true}}));return handled}function FS_createPreloadedFile(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish){var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);function processData(byteArray){function finish(byteArray){if(preFinish)preFinish();if(!dontCreateFile){FS.createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}if(onload)onload();removeRunDependency(dep)}if(FS_handledByPreloadPlugin(byteArray,fullname,finish,(()=>{if(onerror)onerror();removeRunDependency(dep)}))){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url,(byteArray=>processData(byteArray)),onerror)}else{processData(url)}}function FS_modeStringToFlags(str){var flagModes={"r":0,"r+":2,"w":512|64|1,"w+":512|64|2,"a":1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags}function FS_getMode(canRead,canWrite){var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode}var ERRNO_CODES={};var NODEFS={isWindows:false,staticInit:()=>{NODEFS.isWindows=!!process.platform.match(/^win/);var flags=process.binding("constants");if(flags["fs"]){flags=flags["fs"]}NODEFS.flagsForNodeMap={1024:flags["O_APPEND"],64:flags["O_CREAT"],128:flags["O_EXCL"],256:flags["O_NOCTTY"],0:flags["O_RDONLY"],2:flags["O_RDWR"],4096:flags["O_SYNC"],512:flags["O_TRUNC"],1:flags["O_WRONLY"],131072:flags["O_NOFOLLOW"]};assert(NODEFS.flagsForNodeMap["0"]===0)},convertNodeCode:e=>{var code=e.code;assert(code in ERRNO_CODES,`unexpected node error code: ${code} (${e})`);return ERRNO_CODES[code]},mount:mount=>{assert(ENVIRONMENT_IS_NODE);return NODEFS.createNode(null,"/",NODEFS.getMode(mount.opts.root),0)},createNode:(parent,name,mode,dev)=>{if(!FS.isDir(mode)&&!FS.isFile(mode)&&!FS.isLink(mode)){throw new FS.ErrnoError(28)}var node=FS.createNode(parent,name,mode);node.node_ops=NODEFS.node_ops;node.stream_ops=NODEFS.stream_ops;return node},getMode:path=>{var stat;try{stat=fs.lstatSync(path);if(NODEFS.isWindows){stat.mode=stat.mode|(stat.mode&292)>>2}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}return stat.mode},realPath:node=>{var parts=[];while(node.parent!==node){parts.push(node.name);node=node.parent}parts.push(node.mount.opts.root);parts.reverse();return PATH.join.apply(null,parts)},flagsForNode:flags=>{flags&=~2097152;flags&=~2048;flags&=~32768;flags&=~524288;flags&=~65536;var newFlags=0;for(var k in NODEFS.flagsForNodeMap){if(flags&k){newFlags|=NODEFS.flagsForNodeMap[k];flags^=k}}if(flags){throw new FS.ErrnoError(28)}return newFlags},node_ops:{getattr:node=>{var path=NODEFS.realPath(node);var stat;try{stat=fs.lstatSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}if(NODEFS.isWindows&&!stat.blksize){stat.blksize=4096}if(NODEFS.isWindows&&!stat.blocks){stat.blocks=(stat.size+stat.blksize-1)/stat.blksize|0}return{dev:stat.dev,ino:stat.ino,mode:stat.mode,nlink:stat.nlink,uid:stat.uid,gid:stat.gid,rdev:stat.rdev,size:stat.size,atime:stat.atime,mtime:stat.mtime,ctime:stat.ctime,blksize:stat.blksize,blocks:stat.blocks}},setattr:(node,attr)=>{var path=NODEFS.realPath(node);try{if(attr.mode!==undefined){fs.chmodSync(path,attr.mode);node.mode=attr.mode}if(attr.timestamp!==undefined){var date=new Date(attr.timestamp);fs.utimesSync(path,date,date)}if(attr.size!==undefined){fs.truncateSync(path,attr.size)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},lookup:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);var mode=NODEFS.getMode(path);return NODEFS.createNode(parent,name,mode)},mknod:(parent,name,mode,dev)=>{var node=NODEFS.createNode(parent,name,mode,dev);var path=NODEFS.realPath(node);try{if(FS.isDir(node.mode)){fs.mkdirSync(path,node.mode)}else{fs.writeFileSync(path,"",{mode:node.mode})}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}return node},rename:(oldNode,newDir,newName)=>{var oldPath=NODEFS.realPath(oldNode);var newPath=PATH.join2(NODEFS.realPath(newDir),newName);try{fs.renameSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}oldNode.name=newName},unlink:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.unlinkSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},rmdir:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.rmdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},readdir:node=>{var path=NODEFS.realPath(node);try{return fs.readdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},symlink:(parent,newName,oldPath)=>{var newPath=PATH.join2(NODEFS.realPath(parent),newName);try{fs.symlinkSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},readlink:node=>{var path=NODEFS.realPath(node);try{path=fs.readlinkSync(path);path=nodePath.relative(nodePath.resolve(node.mount.opts.root),path);return path}catch(e){if(!e.code)throw e;if(e.code==="UNKNOWN")throw new FS.ErrnoError(28);throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}}},stream_ops:{open:stream=>{var path=NODEFS.realPath(stream.node);try{if(FS.isFile(stream.node.mode)){stream.nfd=fs.openSync(path,NODEFS.flagsForNode(stream.flags))}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},close:stream=>{try{if(FS.isFile(stream.node.mode)&&stream.nfd){fs.closeSync(stream.nfd)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},read:(stream,buffer,offset,length,position)=>{if(length===0)return 0;try{return fs.readSync(stream.nfd,Buffer.from(buffer.buffer),offset,length,position)}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},write:(stream,buffer,offset,length,position)=>{try{return fs.writeSync(stream.nfd,Buffer.from(buffer.buffer),offset,length,position)}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},llseek:(stream,offset,whence)=>{var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){try{var stat=fs.fstatSync(stream.nfd);position+=stat.size}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}}}if(position<0){throw new FS.ErrnoError(28)}return position},mmap:(stream,length,position,prot,flags)=>{if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}var ptr=mmapAlloc(length);NODEFS.stream_ops.read(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}},msync:(stream,buffer,offset,length,mmapFlags)=>{NODEFS.stream_ops.write(stream,buffer,0,length,offset,false);return 0}}};var ERRNO_MESSAGES={0:"Success",1:"Arg list too long",2:"Permission denied",3:"Address already in use",4:"Address not available",5:"Address family not supported by protocol family",6:"No more processes",7:"Socket already connected",8:"Bad file number",9:"Trying to read unreadable message",10:"Mount device busy",11:"Operation canceled",12:"No children",13:"Connection aborted",14:"Connection refused",15:"Connection reset by peer",16:"File locking deadlock error",17:"Destination address required",18:"Math arg out of domain of func",19:"Quota exceeded",20:"File exists",21:"Bad address",22:"File too large",23:"Host is unreachable",24:"Identifier removed",25:"Illegal byte sequence",26:"Connection already in progress",27:"Interrupted system call",28:"Invalid argument",29:"I/O error",30:"Socket is already connected",31:"Is a directory",32:"Too many symbolic links",33:"Too many open files",34:"Too many links",35:"Message too long",36:"Multihop attempted",37:"File or path name too long",38:"Network interface is not configured",39:"Connection reset by network",40:"Network is unreachable",41:"Too many open files in system",42:"No buffer space available",43:"No such device",44:"No such file or directory",45:"Exec format error",46:"No record locks available",47:"The link has been severed",48:"Not enough core",49:"No message of desired type",50:"Protocol not available",51:"No space left on device",52:"Function not implemented",53:"Socket is not connected",54:"Not a directory",55:"Directory not empty",56:"State not recoverable",57:"Socket operation on non-socket",59:"Not a typewriter",60:"No such device or address",61:"Value too large for defined data type",62:"Previous owner died",63:"Not super-user",64:"Broken pipe",65:"Protocol error",66:"Unknown protocol",67:"Protocol wrong type for socket",68:"Math result not representable",69:"Read only file system",70:"Illegal seek",71:"No such process",72:"Stale file handle",73:"Connection timed out",74:"Text file busy",75:"Cross-device link",100:"Device not a stream",101:"Bad font file fmt",102:"Invalid slot",103:"Invalid request code",104:"No anode",105:"Block device required",106:"Channel number out of range",107:"Level 3 halted",108:"Level 3 reset",109:"Link number out of range",110:"Protocol driver not attached",111:"No CSI structure available",112:"Level 2 halted",113:"Invalid exchange",114:"Invalid request descriptor",115:"Exchange full",116:"No data (for no delay io)",117:"Timer expired",118:"Out of streams resources",119:"Machine is not on the network",120:"Package not installed",121:"The object is remote",122:"Advertise error",123:"Srmount error",124:"Communication error on send",125:"Cross mount point (not really error)",126:"Given log. name not unique",127:"f.d. invalid for this operation",128:"Remote address changed",129:"Can access a needed shared lib",130:"Accessing a corrupted shared lib",131:".lib section in a.out corrupted",132:"Attempting to link in too many libs",133:"Attempting to exec a shared library",135:"Streams pipe error",136:"Too many users",137:"Socket type not supported",138:"Not supported",139:"Protocol family not supported",140:"Can't send after socket shutdown",141:"Too many references",142:"Host is down",148:"No medium (in tape drive)",156:"Level 2 not synchronized"};function demangle(func){warnOnce("warning: build with -sDEMANGLE_SUPPORT to link in libcxxabi demangling");return func}function demangleAll(text){var regex=/\b_Z[\w\d_]+/g;return text.replace(regex,(function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"}))}var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:(path,opts={})=>{path=PATH_FS.resolve(path);if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};opts=Object.assign(defaults,opts);if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=path.split("/").filter((p=>!!p));var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:node=>{var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?`${mount}/${path}`:mount+path}path=path?`${node.name}/${path}`:node.name;node=node.parent}},hashName:(parentid,name)=>{var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:node=>{var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:node=>{var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:(parent,name)=>{var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:(parent,name,mode,rdev)=>{assert(typeof parent=="object");var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:node=>{FS.hashRemoveNode(node)},isRoot:node=>node===node.parent,isMountpoint:node=>!!node.mounted,isFile:mode=>(mode&61440)===32768,isDir:mode=>(mode&61440)===16384,isLink:mode=>(mode&61440)===40960,isChrdev:mode=>(mode&61440)===8192,isBlkdev:mode=>(mode&61440)===24576,isFIFO:mode=>(mode&61440)===4096,isSocket:mode=>(mode&49152)===49152,flagsToPermissionString:flag=>{var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:(node,perms)=>{if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup:dir=>{var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:(dir,name)=>{try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:(dir,name,isdir)=>{var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:(node,flags)=>{if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:()=>{for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked:fd=>{var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream:(stream,fd=-1)=>{if(!FS.FSStream){FS.FSStream=function(){this.shared={}};FS.FSStream.prototype={};Object.defineProperties(FS.FSStream.prototype,{object:{get(){return this.node},set(val){this.node=val}},isRead:{get(){return(this.flags&2097155)!==1}},isWrite:{get(){return(this.flags&2097155)!==0}},isAppend:{get(){return this.flags&1024}},flags:{get(){return this.shared.flags},set(val){this.shared.flags=val}},position:{get(){return this.shared.position},set(val){this.shared.position=val}}})}stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:fd=>{FS.streams[fd]=null},chrdev_stream_ops:{open:stream=>{var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:()=>{throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice:(dev,ops)=>{FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts:mount=>{var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:(populate,callback)=>{if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){assert(FS.syncFSRequests>0);FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach((mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)}))},mount:(type,opts,mountpoint)=>{if(typeof type=="string"){throw type}var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:mountpoint=>{var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach((hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}}));node.mounted=null;var idx=node.mount.mounts.indexOf(mount);assert(idx!==-1);node.mount.mounts.splice(idx,1)},lookup:(parent,name)=>parent.node_ops.lookup(parent,name),mknod:(path,mode,dev)=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:(path,mode)=>{mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:(path,mode)=>{mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:(path,mode)=>{var dirs=path.split("/");var d="";for(var i=0;i{if(typeof dev=="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink:(oldpath,newpath)=>{if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename:(old_path,new_path)=>{var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name)}catch(e){throw e}finally{FS.hashAddNode(old_node)}},rmdir:path=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node)},readdir:path=>{var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node.node_ops.readdir){throw new FS.ErrnoError(54)}return node.node_ops.readdir(node)},unlink:path=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.unlink(parent,name);FS.destroyNode(node)},readlink:path=>{var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return PATH_FS.resolve(FS.getPath(link.parent),link.node_ops.readlink(link))},stat:(path,dontFollow)=>{var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;if(!node){throw new FS.ErrnoError(44)}if(!node.node_ops.getattr){throw new FS.ErrnoError(63)}return node.node_ops.getattr(node)},lstat:path=>FS.stat(path,true),chmod:(path,mode,dontFollow)=>{var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{mode:mode&4095|node.mode&~4095,timestamp:Date.now()})},lchmod:(path,mode)=>{FS.chmod(path,mode,true)},fchmod:(fd,mode)=>{var stream=FS.getStreamChecked(fd);FS.chmod(stream.node,mode)},chown:(path,uid,gid,dontFollow)=>{var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{timestamp:Date.now()})},lchown:(path,uid,gid)=>{FS.chown(path,uid,gid,true)},fchown:(fd,uid,gid)=>{var stream=FS.getStreamChecked(fd);FS.chown(stream.node,uid,gid)},truncate:(path,len)=>{if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}node.node_ops.setattr(node,{size:len,timestamp:Date.now()})},ftruncate:(fd,len)=>{var stream=FS.getStreamChecked(fd);if((stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.truncate(stream.node,len)},utime:(path,atime,mtime)=>{var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;node.node_ops.setattr(node,{timestamp:Math.max(atime,mtime)})},open:(path,flags,mode)=>{if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags=="string"?FS_modeStringToFlags(flags):flags;mode=typeof mode=="undefined"?438:mode;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;if(typeof path=="object"){node=path}else{path=PATH.normalize(path);try{var lookup=FS.lookupPath(path,{follow:!(flags&131072)});node=lookup.node}catch(e){}}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else{node=FS.mknod(path,mode,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512&&!created){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node:node,path:FS.getPath(node),flags:flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false});if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(Module["logReadFiles"]&&!(flags&1)){if(!FS.readFiles)FS.readFiles={};if(!(path in FS.readFiles)){FS.readFiles[path]=1}}return stream},close:stream=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed:stream=>stream.fd===null,llseek:(stream,offset,whence)=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read:(stream,buffer,offset,length,position)=>{assert(offset>=0);if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write:(stream,buffer,offset,length,position,canOwn)=>{assert(offset>=0);if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},allocate:(stream,offset,length)=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(offset<0||length<=0){throw new FS.ErrnoError(28)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(!FS.isFile(stream.node.mode)&&!FS.isDir(stream.node.mode)){throw new FS.ErrnoError(43)}if(!stream.stream_ops.allocate){throw new FS.ErrnoError(138)}stream.stream_ops.allocate(stream,offset,length)},mmap:(stream,length,position,prot,flags)=>{if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync:(stream,buffer,offset,length,mmapFlags)=>{assert(offset>=0);if(!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},munmap:stream=>0,ioctl:(stream,cmd,arg)=>{if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile:(path,opts={})=>{opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error(`Invalid encoding type "${opts.encoding}"`)}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret=UTF8ArrayToString(buf,0)}else if(opts.encoding==="binary"){ret=buf}FS.close(stream);return ret},writeFile:(path,data,opts={})=>{opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){var buf=new Uint8Array(lengthBytesUTF8(data)+1);var actualNumBytes=stringToUTF8Array(data,buf,0,buf.length);FS.write(stream,buf,0,actualNumBytes,undefined,opts.canOwn)}else if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir:path=>{var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories:()=>{FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices:()=>{FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomLeft=randomFill(randomBuffer).byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories:()=>{FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount:()=>{var node=FS.createNode(proc_self,"fd",16384|511,73);node.node_ops={lookup:(parent,name)=>{var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams:()=>{if(Module["stdin"]){FS.createDevice("/dev","stdin",Module["stdin"])}else{FS.symlink("/dev/tty","/dev/stdin")}if(Module["stdout"]){FS.createDevice("/dev","stdout",null,Module["stdout"])}else{FS.symlink("/dev/tty","/dev/stdout")}if(Module["stderr"]){FS.createDevice("/dev","stderr",null,Module["stderr"])}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1);assert(stdin.fd===0,`invalid handle for stdin (${stdin.fd})`);assert(stdout.fd===1,`invalid handle for stdout (${stdout.fd})`);assert(stderr.fd===2,`invalid handle for stderr (${stderr.fd})`)},ensureErrnoError:()=>{if(FS.ErrnoError)return;FS.ErrnoError=function ErrnoError(errno,node){this.name="ErrnoError";this.node=node;this.setErrno=function(errno){this.errno=errno;for(var key in ERRNO_CODES){if(ERRNO_CODES[key]===errno){this.code=key;break}}};this.setErrno(errno);this.message=ERRNO_MESSAGES[errno];if(this.stack){Object.defineProperty(this,"stack",{value:(new Error).stack,writable:true});this.stack=demangleAll(this.stack)}};FS.ErrnoError.prototype=new Error;FS.ErrnoError.prototype.constructor=FS.ErrnoError;[44].forEach((code=>{FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack=""}))},staticInit:()=>{FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={"MEMFS":MEMFS,"NODEFS":NODEFS}},init:(input,output,error)=>{assert(!FS.init.initialized,"FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)");FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()},quit:()=>{FS.init.initialized=false;_fflush(0);for(var i=0;i{var ret=FS.analyzePath(path,dontResolveLastLink);if(!ret.exists){return null}return ret.object},analyzePath:(path,dontResolveLastLink)=>{try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath:(parent,path,canRead,canWrite)=>{parent=typeof parent=="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){}parent=current}return current},createFile:(parent,name,properties,canRead,canWrite)=>{var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile:(parent,name,data,canRead,canWrite,canOwn)=>{var path=name;if(parent){parent=typeof parent=="string"?parent:FS.getPath(parent);path=name?PATH.join2(parent,name):parent}var mode=FS_getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data=="string"){var arr=new Array(data.length);for(var i=0,len=data.length;i{var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(!!input,!!output);if(!FS.createDevice.major)FS.createDevice.major=64;var dev=FS.makedev(FS.createDevice.major++,0);FS.registerDevice(dev,{open:stream=>{stream.seekable=false},close:stream=>{if(output&&output.buffer&&output.buffer.length){output(10)}},read:(stream,buffer,offset,length,pos)=>{var bytesRead=0;for(var i=0;i{for(var i=0;i{if(obj.isDevice||obj.isFolder||obj.link||obj.contents)return true;if(typeof XMLHttpRequest!="undefined"){throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.")}else if(read_){try{obj.contents=intArrayFromString(read_(obj.url),true);obj.usedBytes=obj.contents.length}catch(e){throw new FS.ErrnoError(29)}}else{throw new Error("Cannot load without read() or XMLHttpRequest.")}},createLazyFile:(parent,name,url,canRead,canWrite)=>{function LazyUint8Array(){this.lengthKnown=false;this.chunks=[]}LazyUint8Array.prototype.get=function LazyUint8Array_get(idx){if(idx>this.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter((chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]}));if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach((key=>{var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}}));function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);assert(size>=0);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}};node.stream_ops=stream_ops;return node},absolutePath:()=>{abort("FS.absolutePath has been removed; use PATH_FS.resolve instead")},createFolder:()=>{abort("FS.createFolder has been removed; use FS.mkdir instead")},createLink:()=>{abort("FS.createLink has been removed; use FS.symlink instead")},joinPath:()=>{abort("FS.joinPath has been removed; use PATH.join instead")},mmapAlloc:()=>{abort("FS.mmapAlloc has been replaced by the top level function mmapAlloc")},standardizePath:()=>{abort("FS.standardizePath has been removed; use PATH.normalize instead")}};var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt:function(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return PATH.join2(dir,path)},doStat:function(func,path,buf){try{var stat=func(path)}catch(e){if(e&&e.node&&PATH.normalize(path)!==PATH.normalize(FS.getPath(e.node))){return-54}throw e}HEAP32[buf>>2]=stat.dev;checkInt32(stat.dev);HEAP32[buf+4>>2]=stat.mode;checkInt32(stat.mode);HEAPU32[buf+8>>2]=stat.nlink;checkInt32(stat.nlink);HEAP32[buf+12>>2]=stat.uid;checkInt32(stat.uid);HEAP32[buf+16>>2]=stat.gid;checkInt32(stat.gid);HEAP32[buf+20>>2]=stat.rdev;checkInt32(stat.rdev);tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+24>>2]=tempI64[0],HEAP32[buf+28>>2]=tempI64[1];checkInt64(stat.size);HEAP32[buf+32>>2]=4096;checkInt32(4096);HEAP32[buf+36>>2]=stat.blocks;checkInt32(stat.blocks);var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();tempI64=[Math.floor(atime/1e3)>>>0,(tempDouble=Math.floor(atime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];checkInt64(Math.floor(atime/1e3));HEAPU32[buf+48>>2]=atime%1e3*1e3;checkInt32(atime%1e3*1e3);tempI64=[Math.floor(mtime/1e3)>>>0,(tempDouble=Math.floor(mtime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+56>>2]=tempI64[0],HEAP32[buf+60>>2]=tempI64[1];checkInt64(Math.floor(mtime/1e3));HEAPU32[buf+64>>2]=mtime%1e3*1e3;checkInt32(mtime%1e3*1e3);tempI64=[Math.floor(ctime/1e3)>>>0,(tempDouble=Math.floor(ctime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+72>>2]=tempI64[0],HEAP32[buf+76>>2]=tempI64[1];checkInt64(Math.floor(ctime/1e3));HEAPU32[buf+80>>2]=ctime%1e3*1e3;checkInt32(ctime%1e3*1e3);tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+88>>2]=tempI64[0],HEAP32[buf+92>>2]=tempI64[1];checkInt64(stat.ino);return 0},doMsync:function(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},varargs:undefined,get(){assert(SYSCALLS.varargs!=undefined);SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStreamChecked(fd);return stream}};function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.createStream(stream,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 5:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;checkInt16(2);return 0}case 6:case 7:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:{if(!stream.tty)return-59;return 0}case 21505:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcgets){var termios=stream.tty.ops.ioctl_tcgets(stream);var argp=SYSCALLS.get();HEAP32[argp>>2]=termios.c_iflag||0;checkInt32(termios.c_iflag||0);HEAP32[argp+4>>2]=termios.c_oflag||0;checkInt32(termios.c_oflag||0);HEAP32[argp+8>>2]=termios.c_cflag||0;checkInt32(termios.c_cflag||0);HEAP32[argp+12>>2]=termios.c_lflag||0;checkInt32(termios.c_lflag||0);for(var i=0;i<32;i++){HEAP8[argp+i+17>>0]=termios.c_cc[i]||0;checkInt8(termios.c_cc[i]||0)}return 0}return 0}case 21510:case 21511:case 21512:{if(!stream.tty)return-59;return 0}case 21506:case 21507:case 21508:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcsets){var argp=SYSCALLS.get();var c_iflag=HEAP32[argp>>2];var c_oflag=HEAP32[argp+4>>2];var c_cflag=HEAP32[argp+8>>2];var c_lflag=HEAP32[argp+12>>2];var c_cc=[];for(var i=0;i<32;i++){c_cc.push(HEAP8[argp+i+17>>0])}return stream.tty.ops.ioctl_tcsets(stream.tty,op,{c_iflag:c_iflag,c_oflag:c_oflag,c_cflag:c_cflag,c_lflag:c_lflag,c_cc:c_cc})}return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;checkInt32(0);return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tiocgwinsz){var winsize=stream.tty.ops.ioctl_tiocgwinsz(stream.tty);var argp=SYSCALLS.get();HEAP16[argp>>1]=winsize[0];checkInt16(winsize[0]);HEAP16[argp+2>>1]=winsize[1];checkInt16(winsize[1])}return 0}case 21524:{if(!stream.tty)return-59;return 0}case 21515:{if(!stream.tty)return-59;return 0}default:return-28}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?SYSCALLS.get():0;return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___throw_exception_with_stack_trace(ex){var e=new WebAssembly.Exception(getCppExceptionTag(),[ex],{traceStack:true});e.message=getExceptionMessage(e);if(e.stack){var arr=e.stack.split("\n");arr.splice(1,1);e.stack=arr.join("\n")}throw e}var structRegistrations={};function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAP32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach((function(type){typeDependencies[type]=dependentTypes}));function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push((()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}}))}}));if(0===unregisteredTypes.length){onComplete(typeConverters)}}var __embind_finalize_value_object=function(structType){var reg=structRegistrations[structType];delete structRegistrations[structType];var rawConstructor=reg.rawConstructor;var rawDestructor=reg.rawDestructor;var fieldRecords=reg.fields;var fieldTypes=fieldRecords.map((field=>field.getterReturnType)).concat(fieldRecords.map((field=>field.setterArgumentType)));whenDependentTypesAreResolved([structType],fieldTypes,(fieldTypes=>{var fields={};fieldRecords.forEach(((field,i)=>{var fieldName=field.fieldName;var getterReturnType=fieldTypes[i];var getter=field.getter;var getterContext=field.getterContext;var setterArgumentType=fieldTypes[i+fieldRecords.length];var setter=field.setter;var setterContext=field.setterContext;fields[fieldName]={read:ptr=>getterReturnType["fromWireType"](getter(getterContext,ptr)),write:(ptr,o)=>{var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,o));runDestructors(destructors)}}}));return[{name:reg.name,"fromWireType":function(ptr){var rv={};for(var i in fields){rv[i]=fields[i].read(ptr)}rawDestructor(ptr);return rv},"toWireType":function(destructors,o){for(var fieldName in fields){if(!(fieldName in o)){throw new TypeError(`Missing field: "${fieldName}"`)}}var ptr=rawConstructor();for(fieldName in fields){fields[fieldName].write(ptr,o[fieldName])}if(destructors!==null){destructors.push(rawDestructor,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:rawDestructor}]}))};function __embind_register_bigint(primitiveType,name,size,minRange,maxRange){}function getShiftFromSize(size){switch(size){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError(`Unknown type size: ${size}`)}}function embind_init_charCodes(){var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes}var embind_charCodes=undefined;function readLatin1String(ptr){var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}function sharedRegisterType(rawType,registeredInstance,options={}){var name=registeredInstance.name;if(!rawType){throwBindingError(`type "${name}" must have a positive integer typeid pointer`)}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError(`Cannot register type '${name}' twice`)}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach((cb=>cb()))}}function registerType(rawType,registeredInstance,options={}){if(!("argPackAdvance"in registeredInstance)){throw new TypeError("registerType registeredInstance requires argPackAdvance")}return sharedRegisterType(rawType,registeredInstance,options)}function __embind_register_bool(rawType,name,size,trueValue,falseValue){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(wt){return!!wt},"toWireType":function(destructors,o){return o?trueValue:falseValue},"argPackAdvance":8,"readValueFromPointer":function(pointer){var heap;if(size===1){heap=HEAP8}else if(size===2){heap=HEAP16}else if(size===4){heap=HEAP32}else{throw new TypeError("Unknown boolean type size: "+name)}return this["fromWireType"](heap[pointer>>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationRegistry=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}var registeredPointers={};function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}var delayFunction=undefined;function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}var attachFinalizer=function(handle){if("undefined"===typeof FinalizationRegistry){attachFinalizer=handle=>handle;return handle}finalizationRegistry=new FinalizationRegistry((info=>{console.warn(info.leakWarning.stack.replace(/^Error: /,""));releaseClassHandle(info.$$)}));attachFinalizer=handle=>{var $$=handle.$$;var hasSmartPtr=!!$$.smartPtr;if(hasSmartPtr){var info={$$:$$};var cls=$$.ptrType.registeredClass;info.leakWarning=new Error(`Embind found a leaked C++ instance ${cls.name} <${ptrToString($$.ptr)}>.\n`+"We'll free it automatically in this case, but this functionality is not reliable across various environments.\n"+"Make sure to invoke .delete() manually once you're done with the instance instead.\n"+"Originally allocated");if("captureStackTrace"in Error){Error.captureStackTrace(info.leakWarning,RegisteredPointer_fromWireType)}finalizationRegistry.register(handle,info,handle)}return handle};detachFinalizer=handle=>finalizationRegistry.unregister(handle);return attachFinalizer(handle)};function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return`_${name}`}return name}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return{[name]:function(){return body.apply(this,arguments)}}[name]}function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${arguments.length}) - expects one of (${proto[methodName].overloadTable})!`)}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError(`Cannot register public name '${name}' twice`)}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`)}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError(`Expected null or instance of ${desiredClass.name}, got an instance of ${ptrClass.name}`)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,Emval.toHandle((function(){clonedHandle["delete"]()})));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}var dynCallLegacy=(sig,ptr,args)=>{assert("dynCall_"+sig in Module,`bad function pointer type - dynCall function not found for sig '${sig}'`);if(args&&args.length){assert(args.length===sig.substring(1).replace(/j/g,"--").length)}else{assert(sig.length==1)}var f=Module["dynCall_"+sig];return args&&args.length?f.apply(null,[ptr].concat(args)):f.call(null,ptr)};var wasmTableMirror=[];var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}assert(wasmTable.get(funcPtr)==func,"JavaScript-side Wasm function table mirror is out of date!");return func};var dynCall=(sig,ptr,args)=>{if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}assert(getWasmTableEntry(ptr),`missing table entry in dynCall: ${ptr}`);var rtn=getWasmTableEntry(ptr).apply(null,args);return rtn};var getDynCaller=(sig,ptr)=>{assert(sig.includes("j")||sig.includes("p"),"getDynCaller should only be called with i64 sigs");var argCache=[];return function(){argCache.length=0;Object.assign(argCache,arguments);return dynCall(sig,ptr,argCache)}};function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(){if(signature.includes("j")){return getDynCaller(signature,rawFunction)}return getWasmTableEntry(rawFunction)}var fp=makeDynCaller();if(typeof fp!="function"){throwBindingError(`unknown function pointer with signature ${signature}: ${rawFunction}`)}return fp}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,(function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}}));errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return`${this.name}: ${this.message}`}};return errorClass}var UnboundTypeError=undefined;function getTypeName(type){var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv}function throwUnboundTypeError(message,types){var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(`${message}: `+unboundTypes.map(getTypeName).join([", "]))}function __embind_register_class(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor){name=readLatin1String(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);if(upcast){upcast=embind__requireFunction(upcastSignature,upcast)}if(downcast){downcast=embind__requireFunction(downcastSignature,downcast)}rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,(function(){throwUnboundTypeError(`Cannot construct ${name} due to unbound types`,[baseClassRawType])}));whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],(function(base){base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(legalFunctionName,(function(){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError("Use 'new' to construct "+name)}if(undefined===registeredClass.constructor_body){throw new BindingError(name+" has no accessible constructor")}var body=registeredClass.constructor_body[arguments.length];if(undefined===body){throw new BindingError(`Tried to invoke ctor of ${name} with invalid number of parameters (${arguments.length}) - expected (${Object.keys(registeredClass.constructor_body).toString()}) parameters instead!`)}return body.apply(this,arguments)}));var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);if(registeredClass.baseClass){if(registeredClass.baseClass.__derivedClasses===undefined){registeredClass.baseClass.__derivedClasses=[]}registeredClass.baseClass.__derivedClasses.push(registeredClass)}var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+"*",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+" const*",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]}))}function heap32VectorToArray(count,firstElement){var array=[];for(var i=0;i>2])}return array}function newFunc(constructor,argumentList){if(!(constructor instanceof Function)){throw new TypeError(`new_ called with constructor type ${typeof constructor} which is not a function`)}var dummy=createNamedFunction(constructor.name||"unknownFunctionName",(function(){}));dummy.prototype=constructor.prototype;var obj=new dummy;var r=constructor.apply(obj,argumentList);return r instanceof Object?r:obj}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc,isAsync){var argCount=argTypes.length;if(argCount<2){throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")}assert(!isAsync,"Async bindings are only supported with JSPI.");var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i0?", ":"")+argsListWired}invokerFnBody+=(returns||isAsync?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],(function(classType){classType=classType[0];var humanName=`constructor ${classType.name}`;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError(`Cannot register multiple constructors with identical number of parameters (${argCount-1}) for class '${classType.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!`)}classType.registeredClass.constructor_body[argCount-1]=()=>{throwUnboundTypeError(`Cannot construct ${classType.name} due to unbound types`,rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,(function(argTypes){argTypes.splice(1,0,null);classType.registeredClass.constructor_body[argCount-1]=craftInvokerFunction(humanName,argTypes,null,invoker,rawConstructor);return[]}));return[]}))}function __embind_register_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual,isAsync){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],(function(classType){classType=classType[0];var humanName=`${classType.name}.${methodName}`;if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError(`Cannot call ${humanName} due to unbound types`,rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,(function(argTypes){var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context,isAsync);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]}));return[]}))}function handleAllocatorInit(){Object.assign(HandleAllocator.prototype,{get(id){assert(this.allocated[id]!==undefined,`invalid handle: ${id}`);return this.allocated[id]},has(id){return this.allocated[id]!==undefined},allocate(handle){var id=this.freelist.pop()||this.allocated.length;this.allocated[id]=handle;return id},free(id){assert(this.allocated[id]!==undefined);this.allocated[id]=undefined;this.freelist.push(id)}})}function HandleAllocator(){this.allocated=[undefined];this.freelist=[]}var emval_handles=new HandleAllocator;function __emval_decref(handle){if(handle>=emval_handles.reserved&&0===--emval_handles.get(handle).refcount){emval_handles.free(handle)}}function count_emval_handles(){var count=0;for(var i=emval_handles.reserved;i{if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handles.get(handle).value},toHandle:value=>{switch(value){case undefined:return 1;case null:return 2;case true:return 3;case false:return 4;default:{return emval_handles.allocate({refcount:1,value:value})}}}};function __embind_register_emval(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(handle){var rv=Emval.toValue(handle);__emval_decref(handle);return rv},"toWireType":function(destructors,value){return Emval.toHandle(value)},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})}function embindRepr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!="number"&&typeof value!="boolean"){throw new TypeError(`Cannot convert ${embindRepr(value)} to ${this.name}`)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn,isAsync){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,(function(){throwUnboundTypeError(`Cannot call ${name} due to unbound types`,argTypes)}),argCount-1);whenDependentTypesAreResolved([],argTypes,(function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn,isAsync),argCount-1);return[]}))}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=value=>value;if(minRange===0){var bitshift=32-8*size;fromWireType=value=>value<>>bitshift}var isUnsignedType=name.includes("unsigned");var checkAssertions=(value,toTypeName)=>{if(typeof value!="number"&&typeof value!="boolean"){throw new TypeError(`Cannot convert "${embindRepr(value)}" to ${toTypeName}`)}if(valuemaxRange){throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!`)}};var toWireType;if(isUnsignedType){toWireType=function(destructors,value){checkAssertions(value,this.name);return value>>>0}}else{toWireType=function(destructors,value){checkAssertions(value,this.name);return value}}registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":toWireType,"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(heap.buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}var stringToUTF8=(str,outPtr,maxBytesToWrite)=>{assert(typeof maxBytesToWrite=="number","stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)};function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;checkInt32(length);if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+i]=charCode}}else{for(var i=0;i{assert(ptr%2==0,"Pointer passed to UTF16ToString must be aligned to two bytes!");var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder)return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr));var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str};var stringToUTF16=(str,outPtr,maxBytesToWrite)=>{assert(outPtr%2==0,"Pointer passed to stringToUTF16 must be aligned to two bytes!");assert(typeof maxBytesToWrite=="number","stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;checkInt16(codeUnit);outPtr+=2}HEAP16[outPtr>>1]=0;checkInt16(0);return outPtr-startPtr};var lengthBytesUTF16=str=>str.length*2;var UTF32ToString=(ptr,maxBytesToRead)=>{assert(ptr%4==0,"Pointer passed to UTF32ToString must be aligned to four bytes!");var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str};var stringToUTF32=(str,outPtr,maxBytesToWrite)=>{assert(outPtr%4==0,"Pointer passed to stringToUTF32 must be aligned to four bytes!");assert(typeof maxBytesToWrite=="number","stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;checkInt32(codeUnit);outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;checkInt32(0);return outPtr-startPtr};var lengthBytesUTF32=str=>{var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len};var __embind_register_std_wstring=function(rawType,charSize,name){name=readLatin1String(name);var decodeString,encodeString,getHeap,lengthBytesUTF,shift;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;getHeap=()=>HEAPU16;shift=1}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;getHeap=()=>HEAPU32;shift=2}registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value=="string")){throwBindingError(`Cannot pass non-string to C++ string type ${name}`)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})};function __embind_register_value_object(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}}function __embind_register_value_object_field(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function __emval_incref(handle){if(handle>4){emval_handles.get(handle).refcount+=1}}function requireRegisteredType(rawType,humanName){var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl}function __emval_take_value(type,arg){type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](arg);return Emval.toHandle(v)}var _abort=()=>{abort("native code called abort()")};var _emscripten_memcpy_big=(dest,src,num)=>HEAPU8.copyWithin(dest,src,src+num);var getHeapMax=()=>2147483648;var _emscripten_get_now;_emscripten_get_now=()=>performance.now();var growMemory=size=>{var b=wasmMemory.buffer;var pages=size-b.byteLength+65535>>>16;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){err(`growMemory: Attempted to grow heap from ${b.byteLength} bytes to ${size} bytes, but got error: ${e}`)}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;assert(requestedSize>oldSize);var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){err(`Cannot enlarge memory, asked to go up to ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!`);return false}var alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var t0=_emscripten_get_now();var replacement=growMemory(newSize);var t1=_emscripten_get_now();out(`Heap resize call from ${oldSize} to ${newSize} took ${t1-t0} msecs. Success: ${!!replacement}`);if(replacement){return true}}err(`Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!`);return false};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var stringToAscii=(str,buffer)=>{for(var i=0;i>0]=str.charCodeAt(i);checkInt8(str.charCodeAt(i))}HEAP8[buffer>>0]=0;checkInt8(0)};var _environ_get=(__environ,environ_buf)=>{var bufSize=0;getEnvStrings().forEach((function(string,i){var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>2]=ptr;checkInt32(ptr);stringToAscii(string,ptr);bufSize+=string.length+1}));return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;checkInt32(strings.length);var bufSize=0;strings.forEach((function(string){bufSize+=string.length+1}));HEAPU32[penviron_buf_size>>2]=bufSize;checkInt32(bufSize);return 0};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;checkInt32(num);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}function convertI32PairToI53Checked(lo,hi){assert(lo==lo>>>0||lo==(lo|0));assert(hi===(hi|0));return hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];checkInt64(stream.position);if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(typeof offset!=="undefined"){offset+=curr}}return ret};function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=doWritev(stream,iov,iovcnt);HEAPU32[pnum>>2]=num;checkInt32(num);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var arraySum=(array,index)=>{var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum};var MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];var addDays=(date,days)=>{var newDate=new Date(date.getTime());while(days>0){var leap=isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate};var writeArrayToMemory=(array,buffer)=>{assert(array.length>=0,"writeArrayToMemory array must have a length (should be an array or typed array)");HEAP8.set(array,buffer)};var _strftime=(s,maxsize,format,tm)=>{var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value=="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}return thisDate.getFullYear()}return thisDate.getFullYear()-1}var EXPANSION_RULES_2={"%a":date=>WEEKDAYS[date.tm_wday].substring(0,3),"%A":date=>WEEKDAYS[date.tm_wday],"%b":date=>MONTHS[date.tm_mon].substring(0,3),"%B":date=>MONTHS[date.tm_mon],"%C":date=>{var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":date=>leadingNulls(date.tm_mday,2),"%e":date=>leadingSomething(date.tm_mday,2," "),"%g":date=>getWeekBasedYear(date).toString().substring(2),"%G":date=>getWeekBasedYear(date),"%H":date=>leadingNulls(date.tm_hour,2),"%I":date=>{var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":date=>leadingNulls(date.tm_mday+arraySum(isLeapYear(date.tm_year+1900)?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR,date.tm_mon-1),3),"%m":date=>leadingNulls(date.tm_mon+1,2),"%M":date=>leadingNulls(date.tm_min,2),"%n":()=>"\n","%p":date=>{if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}return"PM"},"%S":date=>leadingNulls(date.tm_sec,2),"%t":()=>"\t","%u":date=>date.tm_wday||7,"%U":date=>{var days=date.tm_yday+7-date.tm_wday;return leadingNulls(Math.floor(days/7),2)},"%V":date=>{var val=Math.floor((date.tm_yday+7-(date.tm_wday+6)%7)/7);if((date.tm_wday+371-date.tm_yday-2)%7<=2){val++}if(!val){val=52;var dec31=(date.tm_wday+7-date.tm_yday-1)%7;if(dec31==4||dec31==5&&isLeapYear(date.tm_year%400-1)){val++}}else if(val==53){var jan1=(date.tm_wday+371-date.tm_yday)%7;if(jan1!=4&&(jan1!=3||!isLeapYear(date.tm_year)))val=1}return leadingNulls(val,2)},"%w":date=>date.tm_wday,"%W":date=>{var days=date.tm_yday+7-(date.tm_wday+6)%7;return leadingNulls(Math.floor(days/7),2)},"%y":date=>(date.tm_year+1900).toString().substring(2),"%Y":date=>date.tm_year+1900,"%z":date=>{var off=date.tm_gmtoff;var ahead=off>=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":date=>date.tm_zone,"%%":()=>"%"};pattern=pattern.replace(/%%/g,"\0\0");for(var rule in EXPANSION_RULES_2){if(pattern.includes(rule)){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}pattern=pattern.replace(/\0\0/g,"%");var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1};var _strftime_l=(s,maxsize,format,tm,loc)=>_strftime(s,maxsize,format,tm);var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.createPreloadedFile=FS_createPreloadedFile;FS.staticInit();Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_unlink"]=FS.unlink;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createDevice"]=FS.createDevice;if(ENVIRONMENT_IS_NODE){NODEFS.staticInit()}ERRNO_CODES={"EPERM":63,"ENOENT":44,"ESRCH":71,"EINTR":27,"EIO":29,"ENXIO":60,"E2BIG":1,"ENOEXEC":45,"EBADF":8,"ECHILD":12,"EAGAIN":6,"EWOULDBLOCK":6,"ENOMEM":48,"EACCES":2,"EFAULT":21,"ENOTBLK":105,"EBUSY":10,"EEXIST":20,"EXDEV":75,"ENODEV":43,"ENOTDIR":54,"EISDIR":31,"EINVAL":28,"ENFILE":41,"EMFILE":33,"ENOTTY":59,"ETXTBSY":74,"EFBIG":22,"ENOSPC":51,"ESPIPE":70,"EROFS":69,"EMLINK":34,"EPIPE":64,"EDOM":18,"ERANGE":68,"ENOMSG":49,"EIDRM":24,"ECHRNG":106,"EL2NSYNC":156,"EL3HLT":107,"EL3RST":108,"ELNRNG":109,"EUNATCH":110,"ENOCSI":111,"EL2HLT":112,"EDEADLK":16,"ENOLCK":46,"EBADE":113,"EBADR":114,"EXFULL":115,"ENOANO":104,"EBADRQC":103,"EBADSLT":102,"EDEADLOCK":16,"EBFONT":101,"ENOSTR":100,"ENODATA":116,"ETIME":117,"ENOSR":118,"ENONET":119,"ENOPKG":120,"EREMOTE":121,"ENOLINK":47,"EADV":122,"ESRMNT":123,"ECOMM":124,"EPROTO":65,"EMULTIHOP":36,"EDOTDOT":125,"EBADMSG":9,"ENOTUNIQ":126,"EBADFD":127,"EREMCHG":128,"ELIBACC":129,"ELIBBAD":130,"ELIBSCN":131,"ELIBMAX":132,"ELIBEXEC":133,"ENOSYS":52,"ENOTEMPTY":55,"ENAMETOOLONG":37,"ELOOP":32,"EOPNOTSUPP":138,"EPFNOSUPPORT":139,"ECONNRESET":15,"ENOBUFS":42,"EAFNOSUPPORT":5,"EPROTOTYPE":67,"ENOTSOCK":57,"ENOPROTOOPT":50,"ESHUTDOWN":140,"ECONNREFUSED":14,"EADDRINUSE":3,"ECONNABORTED":13,"ENETUNREACH":40,"ENETDOWN":38,"ETIMEDOUT":73,"EHOSTDOWN":142,"EHOSTUNREACH":23,"EINPROGRESS":26,"EALREADY":7,"EDESTADDRREQ":17,"EMSGSIZE":35,"EPROTONOSUPPORT":66,"ESOCKTNOSUPPORT":137,"EADDRNOTAVAIL":4,"ENETRESET":39,"EISCONN":30,"ENOTCONN":53,"ETOOMANYREFS":141,"EUSERS":136,"EDQUOT":19,"ESTALE":72,"ENOTSUP":138,"ENOMEDIUM":148,"EILSEQ":25,"EOVERFLOW":61,"ECANCELED":11,"ENOTRECOVERABLE":56,"EOWNERDEAD":62,"ESTRPIPE":135};InternalError=Module["InternalError"]=class InternalError extends Error{constructor(message){super(message);this.name="InternalError"}};embind_init_charCodes();BindingError=Module["BindingError"]=class BindingError extends Error{constructor(message){super(message);this.name="BindingError"}};init_ClassHandle();init_embind();init_RegisteredPointer();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");handleAllocatorInit();init_emval();function checkIncomingModuleAPI(){ignoredModuleProp("fetchSettings")}var wasmImports={__assert_fail:___assert_fail,__handle_stack_overflow:___handle_stack_overflow,__syscall_fcntl64:___syscall_fcntl64,__syscall_ioctl:___syscall_ioctl,__syscall_openat:___syscall_openat,__throw_exception_with_stack_trace:___throw_exception_with_stack_trace,_embind_finalize_value_object:__embind_finalize_value_object,_embind_register_bigint:__embind_register_bigint,_embind_register_bool:__embind_register_bool,_embind_register_class:__embind_register_class,_embind_register_class_constructor:__embind_register_class_constructor,_embind_register_class_function:__embind_register_class_function,_embind_register_emval:__embind_register_emval,_embind_register_float:__embind_register_float,_embind_register_function:__embind_register_function,_embind_register_integer:__embind_register_integer,_embind_register_memory_view:__embind_register_memory_view,_embind_register_std_string:__embind_register_std_string,_embind_register_std_wstring:__embind_register_std_wstring,_embind_register_value_object:__embind_register_value_object,_embind_register_value_object_field:__embind_register_value_object_field,_embind_register_void:__embind_register_void,_emval_decref:__emval_decref,_emval_incref:__emval_incref,_emval_take_value:__emval_take_value,abort:_abort,emscripten_memcpy_big:_emscripten_memcpy_big,emscripten_resize_heap:_emscripten_resize_heap,environ_get:_environ_get,environ_sizes_get:_environ_sizes_get,fd_close:_fd_close,fd_read:_fd_read,fd_seek:_fd_seek,fd_write:_fd_write,strftime_l:_strftime_l};var asm=createWasm();var ___wasm_call_ctors=createExportWrapper("__wasm_call_ctors");var _malloc=createExportWrapper("malloc");var _fflush=Module["_fflush"]=createExportWrapper("fflush");var _free=Module["_free"]=createExportWrapper("free");var ___errno_location=createExportWrapper("__errno_location");var ___getTypeName=createExportWrapper("__getTypeName");var __embind_initialize_bindings=Module["__embind_initialize_bindings"]=createExportWrapper("_embind_initialize_bindings");var ___funcs_on_exit=createExportWrapper("__funcs_on_exit");var _emscripten_builtin_memalign=createExportWrapper("emscripten_builtin_memalign");var ___trap=function(){return(___trap=Module["asm"]["__trap"]).apply(null,arguments)};var setTempRet0=createExportWrapper("setTempRet0");var _emscripten_stack_init=function(){return(_emscripten_stack_init=Module["asm"]["emscripten_stack_init"]).apply(null,arguments)};var _emscripten_stack_get_free=function(){return(_emscripten_stack_get_free=Module["asm"]["emscripten_stack_get_free"]).apply(null,arguments)};var _emscripten_stack_get_base=function(){return(_emscripten_stack_get_base=Module["asm"]["emscripten_stack_get_base"]).apply(null,arguments)};var _emscripten_stack_get_end=function(){return(_emscripten_stack_get_end=Module["asm"]["emscripten_stack_get_end"]).apply(null,arguments)};var stackSave=createExportWrapper("stackSave");var stackRestore=createExportWrapper("stackRestore");var stackAlloc=createExportWrapper("stackAlloc");var _emscripten_stack_get_current=function(){return(_emscripten_stack_get_current=Module["asm"]["emscripten_stack_get_current"]).apply(null,arguments)};var ___cxa_decrement_exception_refcount=Module["___cxa_decrement_exception_refcount"]=createExportWrapper("__cxa_decrement_exception_refcount");var ___cxa_increment_exception_refcount=Module["___cxa_increment_exception_refcount"]=createExportWrapper("__cxa_increment_exception_refcount");var ___thrown_object_from_unwind_exception=Module["___thrown_object_from_unwind_exception"]=createExportWrapper("__thrown_object_from_unwind_exception");var ___get_exception_message=Module["___get_exception_message"]=createExportWrapper("__get_exception_message");var ___set_stack_limits=Module["___set_stack_limits"]=createExportWrapper("__set_stack_limits");var dynCall_jiji=Module["dynCall_jiji"]=createExportWrapper("dynCall_jiji");var dynCall_viijii=Module["dynCall_viijii"]=createExportWrapper("dynCall_viijii");var dynCall_iiiiij=Module["dynCall_iiiiij"]=createExportWrapper("dynCall_iiiiij");var dynCall_iiiiijj=Module["dynCall_iiiiijj"]=createExportWrapper("dynCall_iiiiijj");var dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=createExportWrapper("dynCall_iiiiiijj");function intArrayFromBase64(s){if(typeof ENVIRONMENT_IS_NODE!="undefined"&&ENVIRONMENT_IS_NODE){var buf=Buffer.from(s,"base64");return new Uint8Array(buf["buffer"],buf["byteOffset"],buf["byteLength"])}try{var decoded=atob(s);var bytes=new Uint8Array(decoded.length);for(var i=0;i0){return}stackCheckInit();preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();assert(!Module["_main"],'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]');postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}checkStackCookie()}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); return moduleArg.ready diff --git a/webapp/src/wasm/privateer.wasm b/webapp/src/wasm/privateer.wasm index d635e10a379569a8aefcc7e4ff216ece216adcad..56ceb06c90052dde6ca0ba5c24752fbdbe5956a6 100755 GIT binary patch literal 1947360 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

o)RS6v;|J(QyC^IJ@HF_f*d*jAT^vW$mw* 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

=CmY=QO7nIE0Lr-$pKFr8D4rv-A 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

Aj5NCr?1VBUdt!_ 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≺G+0Oc?N^uL%DSS)XLzHKIxW}VC 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 z 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≷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

Q{&zLz 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

;XLm@BfIV;cFa~W#GK?mR@M;X$>f*!z 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�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 From 0e77a08f3d419a729bb2844969d77cb6199c7d30 Mon Sep 17 00:00:00 2001 From: Dialpuri Date: Sat, 15 Jun 2024 09:13:09 +0100 Subject: [PATCH 02/24] Added gemmi CMakeLists.txt --- gemmi/CMakeLists.txt | 324 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 gemmi/CMakeLists.txt diff --git a/gemmi/CMakeLists.txt b/gemmi/CMakeLists.txt new file mode 100644 index 000000000..da147004f --- /dev/null +++ b/gemmi/CMakeLists.txt @@ -0,0 +1,324 @@ +cmake_minimum_required(VERSION 3.13) + +project(gemmi LANGUAGES C CXX) + +set(CMAKE_CXX_STANDARD 11) +message(STATUS "Compiling with C++ standard: ${CMAKE_CXX_STANDARD}") +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(gemmi_src ../checkout/gemmi) + +find_package(ZLIB) +if (ZLIB_FOUND) + include_directories("${ZLIB_INCLUDE_DIR}") + message(STATUS "The build will use zlib code from emscripten") +endif() + +include_directories("${gemmi_src}/include" + "${gemmi_src}/third_party") + +add_library(gemmi_cpp STATIC + ${gemmi_src}/src/assembly.cpp + ${gemmi_src}/src/calculate.cpp + ${gemmi_src}/src/crd.cpp + ${gemmi_src}/src/eig3.cpp + ${gemmi_src}/src/mmcif.cpp + ${gemmi_src}/src/mmread_gz.cpp + ${gemmi_src}/src/mtz.cpp + ${gemmi_src}/src/mtz2cif.cpp + ${gemmi_src}/src/polyheur.cpp + ${gemmi_src}/src/read_cif.cpp + ${gemmi_src}/src/resinfo.cpp + ${gemmi_src}/src/riding_h.cpp + ${gemmi_src}/src/sprintf.cpp + ${gemmi_src}/src/to_mmcif.cpp + ${gemmi_src}/src/to_pdb.cpp + ${gemmi_src}/src/monlib.cpp + ${gemmi_src}/src/topo.cpp + ${gemmi_src}/src/xds_ascii.cpp) + +#set_target_properties(gemmi_cpp PROPERTIES COMPILE_FLAGS "-fexceptions -pthread -s USE_ZLIB=1 -s USE_PTHREADS=1" ) + +set(gemmi_HEADERS + ${gemmi_src}/include/gemmi/addends.hpp + ${gemmi_src}/include/gemmi/align.hpp + ${gemmi_src}/include/gemmi/assembly.hpp + ${gemmi_src}/include/gemmi/asudata.hpp + ${gemmi_src}/include/gemmi/asumask.hpp + ${gemmi_src}/include/gemmi/atof.hpp + ${gemmi_src}/include/gemmi/atox.hpp + ${gemmi_src}/include/gemmi/bessel.hpp + ${gemmi_src}/include/gemmi/binner.hpp + ${gemmi_src}/include/gemmi/blob.hpp + ${gemmi_src}/include/gemmi/bond_idx.hpp + ${gemmi_src}/include/gemmi/c4322.hpp + ${gemmi_src}/include/gemmi/calculate.hpp + ${gemmi_src}/include/gemmi/ccp4.hpp + ${gemmi_src}/include/gemmi/cellred.hpp + ${gemmi_src}/include/gemmi/chemcomp.hpp + ${gemmi_src}/include/gemmi/chemcomp_xyz.hpp + ${gemmi_src}/include/gemmi/cif.hpp + ${gemmi_src}/include/gemmi/cif2mtz.hpp + ${gemmi_src}/include/gemmi/cifdoc.hpp + ${gemmi_src}/include/gemmi/contact.hpp + ${gemmi_src}/include/gemmi/crd.hpp + ${gemmi_src}/include/gemmi/ddl.hpp + ${gemmi_src}/include/gemmi/dencalc.hpp + ${gemmi_src}/include/gemmi/dirwalk.hpp + ${gemmi_src}/include/gemmi/ecalc.hpp + ${gemmi_src}/include/gemmi/eig3.hpp + ${gemmi_src}/include/gemmi/elem.hpp + ${gemmi_src}/include/gemmi/enumstr.hpp + ${gemmi_src}/include/gemmi/fail.hpp + ${gemmi_src}/include/gemmi/fileutil.hpp + ${gemmi_src}/include/gemmi/floodfill.hpp + ${gemmi_src}/include/gemmi/formfact.hpp + ${gemmi_src}/include/gemmi/fourier.hpp + ${gemmi_src}/include/gemmi/fprime.hpp + ${gemmi_src}/include/gemmi/fstream.hpp + ${gemmi_src}/include/gemmi/grid.hpp + ${gemmi_src}/include/gemmi/gz.hpp + ${gemmi_src}/include/gemmi/input.hpp + ${gemmi_src}/include/gemmi/interop.hpp + ${gemmi_src}/include/gemmi/it92.hpp + ${gemmi_src}/include/gemmi/iterator.hpp + ${gemmi_src}/include/gemmi/json.hpp + ${gemmi_src}/include/gemmi/levmar.hpp + ${gemmi_src}/include/gemmi/linkhunt.hpp + ${gemmi_src}/include/gemmi/math.hpp + ${gemmi_src}/include/gemmi/merge.hpp + ${gemmi_src}/include/gemmi/metadata.hpp + ${gemmi_src}/include/gemmi/mmcif.hpp + ${gemmi_src}/include/gemmi/mmcif_impl.hpp + ${gemmi_src}/include/gemmi/mmdb.hpp + ${gemmi_src}/include/gemmi/mmread.hpp + ${gemmi_src}/include/gemmi/mmread_gz.hpp + ${gemmi_src}/include/gemmi/model.hpp + ${gemmi_src}/include/gemmi/modify.hpp + ${gemmi_src}/include/gemmi/monlib.hpp + ${gemmi_src}/include/gemmi/mtz.hpp + ${gemmi_src}/include/gemmi/mtz2cif.hpp + ${gemmi_src}/include/gemmi/neighbor.hpp + ${gemmi_src}/include/gemmi/neutron92.hpp + ${gemmi_src}/include/gemmi/numb.hpp + ${gemmi_src}/include/gemmi/pdb.hpp + ${gemmi_src}/include/gemmi/pdb_id.hpp + ${gemmi_src}/include/gemmi/pirfasta.hpp + ${gemmi_src}/include/gemmi/polyheur.hpp + ${gemmi_src}/include/gemmi/qcp.hpp + ${gemmi_src}/include/gemmi/read_cif.hpp + ${gemmi_src}/include/gemmi/read_map.hpp + ${gemmi_src}/include/gemmi/recgrid.hpp + ${gemmi_src}/include/gemmi/reciproc.hpp + ${gemmi_src}/include/gemmi/refln.hpp + ${gemmi_src}/include/gemmi/remarks.hpp + ${gemmi_src}/include/gemmi/resinfo.hpp + ${gemmi_src}/include/gemmi/riding_h.hpp + ${gemmi_src}/include/gemmi/scaling.hpp + ${gemmi_src}/include/gemmi/select.hpp + ${gemmi_src}/include/gemmi/seqalign.hpp + ${gemmi_src}/include/gemmi/seqid.hpp + ${gemmi_src}/include/gemmi/seqtools.hpp + ${gemmi_src}/include/gemmi/sfcalc.hpp + ${gemmi_src}/include/gemmi/small.hpp + ${gemmi_src}/include/gemmi/smcif.hpp + ${gemmi_src}/include/gemmi/solmask.hpp + ${gemmi_src}/include/gemmi/span.hpp + ${gemmi_src}/include/gemmi/sprintf.hpp + ${gemmi_src}/include/gemmi/stats.hpp + ${gemmi_src}/include/gemmi/symmetry.hpp + ${gemmi_src}/include/gemmi/to_chemcomp.hpp + ${gemmi_src}/include/gemmi/to_cif.hpp + ${gemmi_src}/include/gemmi/to_json.hpp + ${gemmi_src}/include/gemmi/to_mmcif.hpp + ${gemmi_src}/include/gemmi/to_pdb.hpp + ${gemmi_src}/include/gemmi/topo.hpp + ${gemmi_src}/include/gemmi/twin.hpp + ${gemmi_src}/include/gemmi/unitcell.hpp + ${gemmi_src}/include/gemmi/utf.hpp + ${gemmi_src}/include/gemmi/util.hpp + ${gemmi_src}/include/gemmi/version.hpp + ${gemmi_src}/include/gemmi/xds_ascii.hpp + + +) + +set(gemmi_third_party-headers_HEADERS + ${gemmi_src}/include/gemmi/third_party/fast_float.h + ${gemmi_src}/include/gemmi/third_party/pocketfft_hdronly.h + ${gemmi_src}/include/gemmi/third_party/sajson.h + ${gemmi_src}/include/gemmi/third_party/tinydir.h +) + +set(gemmi_third_party_tao-headers_HEADERS + ${gemmi_src}/include/gemmi/third_party/tao/pegtl.hpp +) + +set(gemmi_third_party_tao_pegtl-headers_HEADERS + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/analyze.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/apply_mode.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/argv_input.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/ascii.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/buffer_input.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/config.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/cstream_input.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/eol.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/eol_pair.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/file_input.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/input_error.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/istream_input.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/memory_input.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/mmap_input.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/normal.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/nothing.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/parse.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/parse_error.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/position.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/read_input.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/rewind_mode.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/rules.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/string_input.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/tracking_mode.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/utf16.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/utf32.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/utf8.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/version.hpp +) + +set(gemmi_third_party_tao_pegtl_analysis-headers_HEADERS + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/analysis/analyze_cycles.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/analysis/counted.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/analysis/generic.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/analysis/grammar_info.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/analysis/insert_guard.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/analysis/insert_rules.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/analysis/rule_info.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/analysis/rule_type.hpp +) + +set(gemmi_third_party_tao_pegtl_internal-headers_HEADERS + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/action.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/action_input.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/alnum.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/alpha.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/any.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/apply.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/apply0.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/apply0_single.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/apply_single.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/at.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/bof.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/bol.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/bump_help.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/bump_impl.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/bytes.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/control.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/cr_crlf_eol.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/cr_eol.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/crlf_eol.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/cstream_reader.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/cstring_reader.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/demangle.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/demangle_cxxabi.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/demangle_nop.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/demangle_sanitise.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/disable.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/discard.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/dusel_mode.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/duseltronik.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/enable.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/endian.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/endian_gcc.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/endian_win.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/eof.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/eol.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/eolf.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/file_mapper.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/file_opener.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/file_reader.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/has_apply.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/has_apply0.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/identifier.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/if_apply.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/if_must.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/if_must_else.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/if_then_else.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/input_pair.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/integer_sequence.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/istream_reader.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/istring.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/iterator.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/lf_crlf_eol.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/lf_eol.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/list.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/list_must.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/list_tail.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/list_tail_pad.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/marker.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/minus.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/must.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/not_at.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/one.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/opt.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/pad.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/pad_opt.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/peek_char.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/peek_utf16.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/peek_utf32.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/peek_utf8.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/pegtl_string.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/plus.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/raise.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/range.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/ranges.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/rep.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/rep_min.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/rep_min_max.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/rep_opt.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/require.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/result_on_found.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/rule_conjunction.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/rules.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/seq.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/skip_control.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/sor.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/star.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/star_must.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/state.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/string.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/trivial.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/try_catch_type.hpp + ${gemmi_src}/include/gemmi/third_party/tao/pegtl/internal/until.hpp +) + +set_target_properties(gemmi_cpp PROPERTIES PUBLIC_HEADER "${gemmi_HEADERS}") + +install(TARGETS gemmi_cpp + LIBRARY DESTINATION lib + PUBLIC_HEADER DESTINATION include/gemmi +) + +install(FILES + ${gemmi_third_party-headers_HEADERS} + DESTINATION include/gemmi/third_party +) + +install(FILES + ${gemmi_third_party_tao-headers_HEADERS} + DESTINATION include/gemmi/third_party/tao +) + +install(FILES + ${gemmi_third_party_tao_pegtl-headers_HEADERS} + DESTINATION include/gemmi/third_party/tao/pegtl +) + +install(FILES + ${gemmi_third_party_tao_pegtl_analysis-headers_HEADERS} + DESTINATION include/gemmi/third_party/tao/pegtl/analysis +) + +install(FILES + ${gemmi_third_party_tao_pegtl_internal-headers_HEADERS} + DESTINATION include/gemmi/third_party/tao/pegtl/internal +) \ No newline at end of file From 646bbd7313b2b9dae2d7423c1da254c9d76ad75e Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Sat, 15 Jun 2024 09:46:06 +0100 Subject: [PATCH 03/24] Add gemmi/polyheur.hpp; Modify include path in privateer-json.h Added a new include gemmi/polyheur.hpp to privateer-bind.cpp to enhance polyheuristic functionality. Also fixed an issue in privateer-json.h where the sajson library was being included from gemmi package that may lead to 'multiple definition of enum' errors. The correct include path is now used. --- src/privateer/cpp/privateer-bind.cpp | 1 + src/privateer/cpp/privateer-json.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/privateer/cpp/privateer-bind.cpp b/src/privateer/cpp/privateer-bind.cpp index d1ea03abe..615f2d9dc 100644 --- a/src/privateer/cpp/privateer-bind.cpp +++ b/src/privateer/cpp/privateer-bind.cpp @@ -7,6 +7,7 @@ #include #include +#include #include "clipper-glyco.h" #include "clipper-glyco.cpp" diff --git a/src/privateer/cpp/privateer-json.h b/src/privateer/cpp/privateer-json.h index 05245eb5a..cde837936 100644 --- a/src/privateer/cpp/privateer-json.h +++ b/src/privateer/cpp/privateer-json.h @@ -11,8 +11,8 @@ #include #include "privateer-error.h" -// #include "third-party/sajson.h" // Have to include it straight from gemmi, as otherwise it leads to "error: multiple definition of ‘enum sajson::type’" errors. -#include "gemmi/third_party/sajson.h" +#include "third-party/sajson.h" // Have to include it straight from gemmi, as otherwise it leads to "error: multiple definition of ‘enum sajson::type’" errors. +// #include "gemmi/third_party/sajson.h" #include #include #include // for FILE, fopen, fclose From e19b151d32808d614be498f784b517cd49c6ecf9 Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Sat, 15 Jun 2024 09:46:27 +0100 Subject: [PATCH 04/24] Refactor CMakeLists and remove unnecessary code blocks In this commit, the arrangement of the files in CMakeLists.txt has been significantly simplified. In gemmi/CMakeLists.txt, the static library gemmi_cpp is changed to a regular library and globbing is used to include header files instead of listing them individually. Similarly, in the main CMakeLists.txt, unnecessary code blocks for testing mode or ccp4srs have been removed and some modifications have been done on setting flags and file paths. --- CMakeLists.txt | 15 +---- gemmi/CMakeLists.txt | 130 +++------------------------------------ webapp/package-lock.json | 79 ++++++++++++++---------- webapp/package.json | 1 + 4 files changed, 61 insertions(+), 164 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bd9df6cf8..277ec48a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.12) project(privateer VERSION 0.5 LANGUAGES C CXX) SET(PRIVATEER_CC_FLAGS "-O2 -w") -SET(PRIVATEER_CXX_FLAGS "-O2 -w -fwasm-exceptions -I${CMAKE_INSTALL_PREFIX}/include") +SET(PRIVATEER_CXX_FLAGS "-O2 -w -fwasm-exceptions -I${CMAKE_INSTALL_PREFIX}/include") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PRIVATEER_CC_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PRIVATEER_CXX_FLAGS} ") @@ -21,11 +21,6 @@ add_compile_options(--preload-file data/linkage_torsions@/) set(CLIBDENV $ENV{CLIBD}) -# find_package(zlib) -# add_subdirectory(checkout/zlib) - -if (MODE STREQUAL "TESTING") -else() add_subdirectory(gemmi) add_subdirectory(ccp4) add_subdirectory(rfftw) @@ -40,14 +35,9 @@ else() add_subdirectory(clipper/cif) add_subdirectory(clipper/phs) add_subdirectory(clipper/gemmi) -endif() - -# add_subdirectory(ccp4srs) - set(PRIVATEER_SOURCE ${PRIVATEER_SOURCE_DIR}/cpp/privateer.cpp) - include_directories(${CMAKE_CURRENT_SOURCE_DIR} checkout/mmdb2 checkout/ssm/ssm @@ -115,9 +105,8 @@ add_library(privateer_lib # ${PRIVATEER_SOURCE_DIR}/cpp/pybind11/privateer-pyanalysis.cpp # ${PRIVATEER_SOURCE_DIR}/cpp/pybind11/privateer-pymodelling.cpp ${PRIVATEER_SOURCE_DIR}/cpp/clipper-glyco_data.cpp - ${PRIVATEER_SOURCE_DIR}/cpp/privateer-bind.cpp + # ${PRIVATEER_SOURCE_DIR}/cpp/privateer-bind.cpp ${PRIVATEER_SOURCE_DIR}/cpp/third-party/simdjson/simdjson.cpp - ) diff --git a/gemmi/CMakeLists.txt b/gemmi/CMakeLists.txt index da147004f..248b0b374 100644 --- a/gemmi/CMakeLists.txt +++ b/gemmi/CMakeLists.txt @@ -17,130 +17,20 @@ endif() include_directories("${gemmi_src}/include" "${gemmi_src}/third_party") -add_library(gemmi_cpp STATIC - ${gemmi_src}/src/assembly.cpp - ${gemmi_src}/src/calculate.cpp - ${gemmi_src}/src/crd.cpp - ${gemmi_src}/src/eig3.cpp - ${gemmi_src}/src/mmcif.cpp - ${gemmi_src}/src/mmread_gz.cpp - ${gemmi_src}/src/mtz.cpp - ${gemmi_src}/src/mtz2cif.cpp - ${gemmi_src}/src/polyheur.cpp - ${gemmi_src}/src/read_cif.cpp - ${gemmi_src}/src/resinfo.cpp - ${gemmi_src}/src/riding_h.cpp - ${gemmi_src}/src/sprintf.cpp - ${gemmi_src}/src/to_mmcif.cpp - ${gemmi_src}/src/to_pdb.cpp - ${gemmi_src}/src/monlib.cpp - ${gemmi_src}/src/topo.cpp - ${gemmi_src}/src/xds_ascii.cpp) +add_library(gemmi_cpp + ${gemmi_src}/src/align.cpp ${gemmi_src}/src/assembly.cpp ${gemmi_src}/src/calculate.cpp ${gemmi_src}/src/crd.cpp + ${gemmi_src}/src/ddl.cpp ${gemmi_src}/src/eig3.cpp ${gemmi_src}/src/gz.cpp ${gemmi_src}/src/intensit.cpp ${gemmi_src}/src/json.cpp + ${gemmi_src}/src/mmcif.cpp ${gemmi_src}/src/mmread_gz.cpp ${gemmi_src}/src/mtz.cpp ${gemmi_src}/src/mtz2cif.cpp + ${gemmi_src}/src/polyheur.cpp ${gemmi_src}/src/read_cif.cpp ${gemmi_src}/src/resinfo.cpp + ${gemmi_src}/src/riding_h.cpp ${gemmi_src}/src/sprintf.cpp ${gemmi_src}/src/to_mmcif.cpp + ${gemmi_src}/src/to_pdb.cpp ${gemmi_src}/src/monlib.cpp ${gemmi_src}/src/topo.cpp ${gemmi_src}/src/xds_ascii.cpp) #set_target_properties(gemmi_cpp PROPERTIES COMPILE_FLAGS "-fexceptions -pthread -s USE_ZLIB=1 -s USE_PTHREADS=1" ) -set(gemmi_HEADERS - ${gemmi_src}/include/gemmi/addends.hpp - ${gemmi_src}/include/gemmi/align.hpp - ${gemmi_src}/include/gemmi/assembly.hpp - ${gemmi_src}/include/gemmi/asudata.hpp - ${gemmi_src}/include/gemmi/asumask.hpp - ${gemmi_src}/include/gemmi/atof.hpp - ${gemmi_src}/include/gemmi/atox.hpp - ${gemmi_src}/include/gemmi/bessel.hpp - ${gemmi_src}/include/gemmi/binner.hpp - ${gemmi_src}/include/gemmi/blob.hpp - ${gemmi_src}/include/gemmi/bond_idx.hpp - ${gemmi_src}/include/gemmi/c4322.hpp - ${gemmi_src}/include/gemmi/calculate.hpp - ${gemmi_src}/include/gemmi/ccp4.hpp - ${gemmi_src}/include/gemmi/cellred.hpp - ${gemmi_src}/include/gemmi/chemcomp.hpp - ${gemmi_src}/include/gemmi/chemcomp_xyz.hpp - ${gemmi_src}/include/gemmi/cif.hpp - ${gemmi_src}/include/gemmi/cif2mtz.hpp - ${gemmi_src}/include/gemmi/cifdoc.hpp - ${gemmi_src}/include/gemmi/contact.hpp - ${gemmi_src}/include/gemmi/crd.hpp - ${gemmi_src}/include/gemmi/ddl.hpp - ${gemmi_src}/include/gemmi/dencalc.hpp - ${gemmi_src}/include/gemmi/dirwalk.hpp - ${gemmi_src}/include/gemmi/ecalc.hpp - ${gemmi_src}/include/gemmi/eig3.hpp - ${gemmi_src}/include/gemmi/elem.hpp - ${gemmi_src}/include/gemmi/enumstr.hpp - ${gemmi_src}/include/gemmi/fail.hpp - ${gemmi_src}/include/gemmi/fileutil.hpp - ${gemmi_src}/include/gemmi/floodfill.hpp - ${gemmi_src}/include/gemmi/formfact.hpp - ${gemmi_src}/include/gemmi/fourier.hpp - ${gemmi_src}/include/gemmi/fprime.hpp - ${gemmi_src}/include/gemmi/fstream.hpp - ${gemmi_src}/include/gemmi/grid.hpp - ${gemmi_src}/include/gemmi/gz.hpp - ${gemmi_src}/include/gemmi/input.hpp - ${gemmi_src}/include/gemmi/interop.hpp - ${gemmi_src}/include/gemmi/it92.hpp - ${gemmi_src}/include/gemmi/iterator.hpp - ${gemmi_src}/include/gemmi/json.hpp - ${gemmi_src}/include/gemmi/levmar.hpp - ${gemmi_src}/include/gemmi/linkhunt.hpp - ${gemmi_src}/include/gemmi/math.hpp - ${gemmi_src}/include/gemmi/merge.hpp - ${gemmi_src}/include/gemmi/metadata.hpp - ${gemmi_src}/include/gemmi/mmcif.hpp - ${gemmi_src}/include/gemmi/mmcif_impl.hpp - ${gemmi_src}/include/gemmi/mmdb.hpp - ${gemmi_src}/include/gemmi/mmread.hpp - ${gemmi_src}/include/gemmi/mmread_gz.hpp - ${gemmi_src}/include/gemmi/model.hpp - ${gemmi_src}/include/gemmi/modify.hpp - ${gemmi_src}/include/gemmi/monlib.hpp - ${gemmi_src}/include/gemmi/mtz.hpp - ${gemmi_src}/include/gemmi/mtz2cif.hpp - ${gemmi_src}/include/gemmi/neighbor.hpp - ${gemmi_src}/include/gemmi/neutron92.hpp - ${gemmi_src}/include/gemmi/numb.hpp - ${gemmi_src}/include/gemmi/pdb.hpp - ${gemmi_src}/include/gemmi/pdb_id.hpp - ${gemmi_src}/include/gemmi/pirfasta.hpp - ${gemmi_src}/include/gemmi/polyheur.hpp - ${gemmi_src}/include/gemmi/qcp.hpp - ${gemmi_src}/include/gemmi/read_cif.hpp - ${gemmi_src}/include/gemmi/read_map.hpp - ${gemmi_src}/include/gemmi/recgrid.hpp - ${gemmi_src}/include/gemmi/reciproc.hpp - ${gemmi_src}/include/gemmi/refln.hpp - ${gemmi_src}/include/gemmi/remarks.hpp - ${gemmi_src}/include/gemmi/resinfo.hpp - ${gemmi_src}/include/gemmi/riding_h.hpp - ${gemmi_src}/include/gemmi/scaling.hpp - ${gemmi_src}/include/gemmi/select.hpp - ${gemmi_src}/include/gemmi/seqalign.hpp - ${gemmi_src}/include/gemmi/seqid.hpp - ${gemmi_src}/include/gemmi/seqtools.hpp - ${gemmi_src}/include/gemmi/sfcalc.hpp - ${gemmi_src}/include/gemmi/small.hpp - ${gemmi_src}/include/gemmi/smcif.hpp - ${gemmi_src}/include/gemmi/solmask.hpp - ${gemmi_src}/include/gemmi/span.hpp - ${gemmi_src}/include/gemmi/sprintf.hpp - ${gemmi_src}/include/gemmi/stats.hpp - ${gemmi_src}/include/gemmi/symmetry.hpp - ${gemmi_src}/include/gemmi/to_chemcomp.hpp - ${gemmi_src}/include/gemmi/to_cif.hpp - ${gemmi_src}/include/gemmi/to_json.hpp - ${gemmi_src}/include/gemmi/to_mmcif.hpp - ${gemmi_src}/include/gemmi/to_pdb.hpp - ${gemmi_src}/include/gemmi/topo.hpp - ${gemmi_src}/include/gemmi/twin.hpp - ${gemmi_src}/include/gemmi/unitcell.hpp - ${gemmi_src}/include/gemmi/utf.hpp - ${gemmi_src}/include/gemmi/util.hpp - ${gemmi_src}/include/gemmi/version.hpp - ${gemmi_src}/include/gemmi/xds_ascii.hpp - +file(GLOB HEADER_FILES ${gemmi_src}/include/gemmi/*.hpp) +set(gemmi_HEADERS + ${HEADER_FILES} ) set(gemmi_third_party-headers_HEADERS diff --git a/webapp/package-lock.json b/webapp/package-lock.json index 08c984c54..d330dcd20 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -11,6 +11,7 @@ "@tanstack/react-table": "^8.13.2", "@types/jest": "^29.5.6", "@types/node": "^20.8.9", + "detect-browser": "^5.3.0", "jest": "^29.7.0", "jest-puppeteer": "^9.0.2", "moorhen": "file:moorhen-0.6.7.tgz", @@ -4684,11 +4685,11 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -5756,6 +5757,11 @@ "node": ">=0.4.0" } }, + "node_modules/detect-browser": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.3.0.tgz", + "integrity": "sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==" + }, "node_modules/detect-kerning": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-kerning/-/detect-kerning-2.1.2.tgz", @@ -6987,9 +6993,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -7085,9 +7091,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", @@ -8033,10 +8039,22 @@ "node": ">= 0.4" } }, - "node_modules/ip": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", - "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==" + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ip-address/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" }, "node_modules/is-array-buffer": { "version": "3.0.2", @@ -9379,6 +9397,11 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -10151,12 +10174,11 @@ } }, "node_modules/pac-resolver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", - "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", "dependencies": { "degenerator": "^5.0.0", - "ip": "^1.1.8", "netmask": "^2.0.2" }, "engines": { @@ -11837,15 +11859,15 @@ } }, "node_modules/socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dependencies": { - "ip": "^2.0.0", + "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" }, "engines": { - "node": ">= 10.13.0", + "node": ">= 10.0.0", "npm": ">= 3.0.0" } }, @@ -11862,11 +11884,6 @@ "node": ">= 14" } }, - "node_modules/socks/node_modules/ip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", - "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==" - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -12902,9 +12919,9 @@ } }, "node_modules/vite": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz", - "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", + "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", diff --git a/webapp/package.json b/webapp/package.json index 448f904b0..823f1ee68 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -16,6 +16,7 @@ "@tanstack/react-table": "^8.13.2", "@types/jest": "^29.5.6", "@types/node": "^20.8.9", + "detect-browser": "^5.3.0", "jest": "^29.7.0", "jest-puppeteer": "^9.0.2", "moorhen": "file:moorhen-0.6.7.tgz", From 10741f02fc3676733d32664bf2d73076ddc39271 Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Sat, 15 Jun 2024 09:46:59 +0100 Subject: [PATCH 05/24] Update source fetching for Clipper and Gemmi Changed the method of fetching Clipper's source from "bzr checkout" to downloading and extracting a tarball. For Gemmi, updated the version being fetched from 0.5.8 to 0.6.5. These changes reflect more updated and efficient ways of acquiring these sources. --- get_sources | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/get_sources b/get_sources index 84ee46e39..19b8d8497 100755 --- a/get_sources +++ b/get_sources @@ -16,7 +16,10 @@ if [ -d "clipper" ]; then echo "Found clipper" else echo "Checking out clipper" - bzr checkout --lightweight http://fg.oisin.rc-harwell.ac.uk/anonscm/bzr/clipper/clipper_gemmi/ clipper + curl -L http://www.ysbl.york.ac.uk/jsd523/clipper-gemmi-wrapper-20240603.tar.gz -o clipper-gemmi-wrapper.tar.gz + + tar xf clipper-gemmi-wrapper.tar.gz + mv clipper-gemmi-wrapper clipper echo fi @@ -40,9 +43,9 @@ if [ -d "gemmi" ]; then echo "Found gemmi" else echo "Checking out gemmi" -wget https://github.com/project-gemmi/gemmi/archive/refs/tags/v0.5.8.tar.gz -tar xf v0.5.8.tar.gz -mv gemmi-0.5.8 gemmi +wget https://github.com/project-gemmi/gemmi/archive/refs/tags/v0.6.5.tar.gz +tar xf v0.6.5.tar.gz +mv gemmi-0.6.5 gemmi echo fi From 1dc5bab6e69cb177c429f0d65d421086a8be9d9d Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Sat, 15 Jun 2024 09:47:34 +0100 Subject: [PATCH 06/24] Add browser detection for Firefox in fetchPDBFile function This commit adds the 'detect-browser' package and uses it within the fetchPDBFile function. This change handles a unique situation where Firefox fails to work with CIF files, so for Firefox users, it fetches PDB files instead. --- webapp/src/utils/fetch_from_pdb.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/webapp/src/utils/fetch_from_pdb.ts b/webapp/src/utils/fetch_from_pdb.ts index ed25082ff..37a4d3deb 100644 --- a/webapp/src/utils/fetch_from_pdb.ts +++ b/webapp/src/utils/fetch_from_pdb.ts @@ -1,3 +1,5 @@ +import { detect } from "detect-browser" + async function fetchPDBFile(PDBCode: string): Promise { console.warn( 'The CIF file for this PDB could not be found, trying for the PDB' @@ -28,6 +30,16 @@ export async function fetchPDB(PDBCode: string): Promise { console.log('Fetching PDB ', PDBCode); const pdbURL = `https://files.rcsb.org/download/${PDBCode.toUpperCase()}.cif`; + // FIXME + const browser = detect(); // FireFox doesn't work with CIF files, get the PDB. + if (browser.name === "firefox") { + try { + return await fetchPDBFile(PDBCode); + } catch (e) { + return await Promise.reject(e); + } + } + const file = fetch(pdbURL) .then(async (response) => { if (!response.ok) { From c97a595b434336a53cd8398d4b832149ec73f58c Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Sat, 15 Jun 2024 09:47:55 +0100 Subject: [PATCH 07/24] Updated blob --- webapp/src/wasm/privateer.wasm | Bin 1947360 -> 1948826 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/webapp/src/wasm/privateer.wasm b/webapp/src/wasm/privateer.wasm index 56ceb06c90052dde6ca0ba5c24752fbdbe5956a6..76474897602ad5c559932940cabc4d79ef129276 100755 GIT binary patch literal 1948826 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�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�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≷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�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

&kR=wrW)t|JEfjbE`c*d}85)Ala zOt}u)=&y2U0P_hm)RrG{FFbn0192mY=%B6cxK}G!Q_pi>K<30ikRyqEav3urOB`a% zR=Tkeb|je1v4v8VV@M*nQ9~O54i`Z#)6!H!^Z^bCVXbmcw-qY2o-dT$3R=sx@^d?# zjY-`wH#JrMPPNwEYV~ckL*$6j%;$S`TYskA#?DlJ|122w4sj#;pGC=q2n4b$Vbf8>(62$>k`Qb!B5%mECHK-XeZ9Ed_rMfd5IZfz zN{Bw0pKND}>|BQ}v79pIyk;;40~og!z1`Q;>8YH;X!n10CK)+0vQWb@l-H1&I@c9x znMynR(%XWH5{-|2?Olk3$9Y|dW~t&3l;_fxc%aKi8iu<^!7YnEGoqo-c_+)|S@Xv_ ztMWHxCmp(>L($_MD0%b_p|0QhlA`sFtgHM$1a|5fbroYMJ27U)JY#&3Q5`I;vuKXu zB2?753>QZRy8al&g+$0UQ&8T+u(I47B*l`i^Agv%NP_|~r{jLabYXjQ7jucZmaX@m zH;J9Eh$7e$AL+PfGffeI`0PR^t-i+JO|Yi6WVA$um+Zp9&TlI`r-Wg_&U8J^S37gw zGC6zDv=tge!-4`0Ts6-J!L`G`|GoR6Zd}6mmNgC;u@{ec|KrlmFP}fVGTV zn5!t;Aa&K*mfN_SrP>Q4v0!d{8C1kvzU9>R0O zS6>|X3fow|QeVnn_4~Coe0Ar*S8OBsN?6Fh8pOtv!&hG#_zEQ#UkQKuYBmmEz*oF5 zJpNhnC9M1B%(gL*6h^)jKlf)XPFn?t`Xkt`f*VERtKlFJOD3Ww;-~z?vi{ z9Dy{Xv-4h|TC5ejpi!J>Tr3kfS}VmZFfQhqSKpqhy2n>@Be(y|BQ4x z&@4^|+T3{$N>?#OYT0}A-r*^2AB|`6

;#;?m}fU_9gPW93s#1>?Rhoe_*@lb4tY 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%0Dmwgo6IH-|N|DU{Yv(Ob5 zq0CtP2BEXLvx%W#qs(YXw1zp5Qam^G*FhDBpaE#teD{j|QPKI?uA4%yK@3 zRfLg}HPxmPF5~ia%^n(FaXbS}K=UuhbcR5$!Ojad9)Kb0jb;htB5XXXpLTZpa8@k+ zmjN^cI04`03BC)yX`%G{ldHkxp(8=x&Pl)S4cIBI_YKqf)T+F>I6VS9>0f}V*e)~J zrM~t%YmTVDncLr8qp#OwFXOhnCi^E`5YFrJWr7f4;qew~SO4nTWtm#$c0CIIO?HMw zjiKLb!u3ALritl;tb$Y7KLIq}nxF}ImBeII4zlXLD9S&`j(T3v;BIkiLvv3tb3TEa zPhM8ODA*?jkh7CRloz|ji}dHkRFa9eC)RKJW-VxXL2K6w!eV;Nzc0#WgizI_D%6`( zyh$q1`R{C#CtgKCo<0i8`gU$NL6-)qxQ;;*^#mjjx))(e-@BE;t_RaErGTiO&Vc}U zz^0A~s)n<11VOE@;$7gCLL2pmC|sQ`Nj^fz)>{2;0-Z9cpkvW#M?sO-Dx#p)F)!K8}Tw@2UJwhC(5iNyF=vbqK&e6SfkP!*Kb;jNto_W+i@g4G$ zx60VfQ^i58X~2$xTEC%MPmZ{CIpWq&D&!Sg|1T9Daq9xnUI_$LVz#6QYKZjDgCueg z5P~I;Im+m)7rrU?XTe;FG}-+Lr?4)V#Nbij|C;BvxrfYcXo8_^RN~jfmD~mtN)AlL zqJa(qpR^eQ1az51twFVECZO&?0Z^HggM-UaGIFT16Y@Z!zDb^N{Fwq(fr$XWmGm%m zeM8^Y`BUEAGMd3-GzhdaJxi(d*EmY#?DQ84#v3WHeP9(bf|FV;nWdy^Pw8PZQC0Wh%IX-ec0ToMhN{xy;>AcD+^0SL_yex2P;e1QGd zkSwYQgnmH+JXS)72>Cg=K~gat&{|$roN#KfMKK@T>ga=L4PUrEv-=E*!i!?1pK}&@ zYVE3M?JBR`MX@5D=hrx_ct{;2vS~IUWTTCY1)V;3)PLjM(IaRxgG2uPTyF@5>K*pM(j% z#Dcw9M2*J0cw2RhV;ZVqW5+63!ZKtP_3w79PNFU*h^Q&3q?Qj@|FUB_65s{Nj>XrO z&aajn@h!*^(Scnz!lQ3$ADw6(rOn)QGs(Uo26cK4JkG(pdt(PD?A;YNr{0t87Kj(;5HvLPM*^$UpPsJDpAdl1doIq>NKc@Y}-27a(*E{ zbr4OpnQ@w4VYQE@QX8(^wc7uJfD|f2ubaO9)8DeK2jjUw0I&);SJ-+$ZP|MA*49%b zTaS!<*m^{5B?gAA2S{ibRAOurn`s%oNcznJhZ=G(4P#f>X#`d%PqOzw~B);Z1RCyAZ*ip-pI+=y|sKx66Wbf?7;s zi%&1!PZ@5fVq5|sHQylE{viLqO|p1V|J?Rvs1%vl>OFC*MGIs(jEkxw!D`2C0EoQ} z5aOtb5k%g()wc8YxZTqZww~4 zbXxtHPOCrB*J=Q!Z8fZleF_T%?cT2uF!gKxDt~5n1TrJ)D1v}_o;V#1kIZgQFYXaA zdGb`mES~H}kw@704eAIfF5>cKepafYvtmHQxJ8n&hmoh%Gs<@@+}%@lY3}(TVhRGjx?2S&_qXNCczW?(J++#mZXjRp#o10bK5li| zxc||(?c(g$_Ti-NLXT6pmng{fq9E5~-=WJhbLq1}NEGv{_2lU+;j9jKj!LKOoU&E( ztBT8RT-ed63eVT&nfbH5%)6NWlWMqw>3?)*ZcLYv{SVT;F#X@9`!w)N+z>uxD6W_exrCj~PY&^y;{ygbl2BZvZyX;K26 zm?y;)jLuK;Z76ZgXErZI=#n)G7<}R1U}s{^ZsqL$Xn8hhW%thQz63Ms(aWVCF3jTHfIxREo<3>=uAsR-KMG zV~xHYk9g8&oyxVyF8oz{7|LM2lKH=0z6^+WUt_Mx42WXkm-oX7h~{K(Y;+_C}cFF8G^Y|Gw)n9Q!Dx+=#$zCqP4#% z(XQR%?xv{^p=0rhQ`!4EExqe8wIqRIw|I|RTDfj_8H4r>!BHP0WA(zWv9G+qQz^;f z`MSHTcs}BYNd}v_N&os9EVTZK{n8W!e8vv(6ck{O@WX zUEMr-M*HYg^XRGVqpEoXT}bQZX!B@41v{WGKhV~HvFZyd3TAL*7&lUhhmE7{K-fZi zQXIYNLk8f;mew5;qpAOg9k#x>G&pE0u~f4)EkrDXVAahL7tm1a9$M`+f}L5VU;P{t zXpV^mDySro*t4jF7-MuO3~K>rvG;%QT3bHSYn*i~M)3&N^vAQCX6u!-X5UMrgus40 zdnsy|{C&hJ2#X~QM*u(xnbof)H;=9Ygk!sxAKKZFs7j4&VyenNlu50(>=hKUi zr0acL>j#w|p>e3L$?iWuIt8!!$I5d+4zh=^Q)(r4zkm6~w_hR+{};Jdtm=4)2BKZe zvJ+|-b6)@Czy7@m>U~6ps!l|Pg16ETIL2)quK>SjvO(gx9>^5^Uj!O!HOa$<;ZwoL z8=x~n%YQ}Z4$=586`gHdlm`Psv=JoKloWQ>g_-mc^C+I!oz0Lo@; z=Bq}-ZbegF8)x&4)VP)_jJCCLTK=zwxcIK@z=DG^}D+^_l)nG5s>2 zswN@=7|7d9$t}Dj3F|yqp$#o#F+f`P0l$qOUu;{)wxut1J|Tf9J|Te+y(@h`^uy!R zH(=UcA!~)@jjmmjk-%=BLfO-WwYCeQ=zNR~uqc0EqvSJAj>A@1ZL%BL!pvsO){Ri% z+kg^@9K($$7byxR;usD=vQIDqyB96$Y;cgtnMMJX!lxqZ_3&0Z(B0N^^qOx?k_$>Y z=~lIMo~|gVouf~L|14T1wTtM4JX`uNmljsshTz39)$}wv>5e?!4$?&1w`a%a9=UD$ zx5a$t-_8#|>#Ez|S$}2c7Gh3*S#V_W{N4C_2CuGmQqe4X`>^0=wewTe;b&$4{qcG8 z=F0E7JC(WegLhXuZ<|lk&j-Kr#Wb{2O`G=*|JvPJxO&2YIBl_C`(KdsE^WW`@OR!l z;dS$!$!uqGY+UWUwQ05fpVjKm(^A+?Cbm*0gkw#5G>H} zM!35s-36e9X~HS)z!WUaOpqshaFeoMCW}Ke;iGoKSAdi=4x1Iivg3HK|D1h6^KO76 zXF0wngjgp%`OgL(4l=5CzOAgd9QwBMN-k_ZA!DLCHr!161^YBbMzWv0%Ji{{FI-_k%L#iW zVp@eV4a{^}IHW^FM_Zo;GU4IAgb5c_wLUunW?Lu~dq#L9RVTFMJQ+)&AQO{}@6?u0 zUc;4@?GjR%Gc7~CNz6-4LN>Enb;@Ng2Y8a|+GAr*|D zZ(>@EV3olQ`@mL_wKpm7&{-?+qtom8F~fXxy8e;-O3tb|HqPku^y*`y(8Q+^*THHZ ziMr;be?J6C*w>WiAVag%RLrmd%qX;HCXQ6=A^|@9hm@+-5dl3;hSSMF(`2;|MV>%OjKk8=FXJzC50YFnD$}e%UCOM#bl zqsHVpg2hH?z~L6PNHU8aCM+td?c>#!P>2M;s?2bR1|k+!&rhVo?Y8O= zRG(94ot#E;+6HU1Qj)7ptf4m7Z}VivY{Z$aiWvuo!%D2XMQpMkBQ*x(`A(7# z8W_h6&NnsTiYHQSI3)(yP1!1@R;v_+O3c`v*kraSHF3p31sM-A-$pf+SC{@pZ1QHc z!!iYd+{VUo8yjsKicMbe8g!v{vFbI*#p`m_Yr;E;la{pYkX22RW8P#|Rva2|7OwC# z#U_tKxloSZ`C;;v<5sT@SNt5zcNE?Un5HxVMHnkSd3ath+yEW*hLDen`|UGvTyRAg z7BjyW+SN87s^2K)x0rmjJlwP_b%9 zQ&8W=I%9<~1N8b*u7^b($jBumaHen>$~77=P*1@2^d$6-v7%G9g?ZZv^R|U~+ktr? z#BCZ!qML~v1Thepf(C=csB5#5>mk%7h|EM(scZt>l<3)XsLrA06o529I&rGZ%er_4 zjDZpEp<$dYmnnvUlN-u9e+6KNgH&7I9rtL8TqrG{m0p@Aec#NHbQC98^mjH1yE|aX zr#K8c;W!LgOPN?|%8UkC(*b>I=nTPoBL@R8;~En<&TmxKYNAUMEU1@W5Crv^Yl_^8 z>cXKa4Z0cv4-)|}fQ19$U+RP8XQg&oqaDpDpbX-CxFO79mL|-^Q@4a!>9Z4I9vw)S zsTAa4FJZnyKAnApxnt`+uNQpWgqhgx#L5pZ5oTC9=+X3_lZE@9qk2=jsn2Vs^GX@l+3Aq0dMNpb;mG77@n$U;>vixbP<8gz=h z-FOU?+2Q(Th}*8x+*TtoA?VK8^TBGJZ=1{kswvGtou`Sn5#B1gJPjWwAZ#{QK$bIr3k}{B zi9TYXBPyAMigZGxA)QUH%pI{fc1Sfm;9ycM;8P`$>J*$C#2WItX=VUAD^sF+4B}}B zHvGUHSxF+m`?7WoLui!Vw|SNTF6aoP72|Irt=i>+q#mTSpO8)_iHtJG(5t<)bW%68 zbV4?%P+Suw#c?ZQXiMIF_xw5c>vM<_nD-BXljfVuMrPwhVI?MvK{Ri`qn-kvax^Ya4G(+!A3emhipP^gD-WN$wmtTUdAb2 zDC!eL&Q5c*}tgU_H`s7m*RYfhBEHPl#i)%*>b_aH-Xn&fT8ToY>bfqpRD_N5 z4CJ_2j7|wB=0b?tgw>N8qBkyc2e{oHnU(BlN993_R-iy+JIXouG_UXf?Q(iYG2_g6 z4Yjyo-(j$XS-y4)NT_oH60inRfEg0V5wPfG1yGZO%6?Fpi3G*yyh?^;DE}S=&Wz7t z9NMv%MKhR>WE-L>9_^`RYf^SoB}1;-BG^pCw$yVujMVYImX6XAc2#y+>kr8A;6p%{ zoJ`r|Uk%u@rM|kqGEU90T#4anKa>w*(E+!Gc4fgkZ0%7pU7lHeC=b{e6|5Uec-M%!_7AyZ*+G~~b`JyJDY1;N10kEVq9Z^5+{sokLOEOcl?Kg#j zBKx+ohtLmXW}U>UDQB6KFx;||k*zra-MZ94IRw$3smHfy2|#rU@RUlh7e%&Y;v)Ri zMHQG8rXWd{^%!q1V(5qnjJ>r~pI+wC5)rJ%0JNoRvNE1=ESlCbJ{?^X>R(W`F}}IdTvj1I>^C^0nF3HvCi>k31dV&0{c@1u|45iYE4nPkRUnV z+&zvfDNi@OBl4O&T6K<=QE$;IAjr?wL@wk;YhhVl7tVPhCbUVjtO@r?gx!6oZ4wqM ztTXiqozV)XI^n>0_n_O?uKqFcQf%0_Sl?RKS4%J|zAAk7U#DhI{7p5T_i^r(Y>HhpSk_if#LD3%>Dp z`k-(G4jn63c-fCJ;#RNUD7J1Z{wanhHrA42L(=EI?3kc%vfd)Nc%hBioh=fk6^LaO z6R-K*2AYHRsDoG=lKc2|3y8LXuxrXW*#%>M{G%WK4@34T)yH006)#UeDId>YPO~~x z5Uu)*<~kaz*!;+{DR#3#Q=cp%udIe`eO|RqFTHB2G-dUP0?@m4ZLF)y=d$h~)M@sR z;m;DJo@=i#Mr$B=Yc-&je?b?UUj|CnG;7aJz4c0pHhpB%fW|mmH&U1b`sgyTD`3Qq zNxpPTHTwSfb`8JAY@VTh6%gemO&+}acIr9RV2iFg5ya~@9s*7Vw~fuIjk z%UsJIcm9qR{pmGrnel87H5-s}ZO1QE6%Y77k%l+h8OQ*5el#dh^U_FQ|h$ZQaEaYkUD0 zcq}G>bzB$c`Q=*{|1|$#axU~>|4(r`&BT1{Z&JA*Z~du4pK_!{V7A0!eF2o=B8tBi zK_5=l6F2~$kaV#XVh_Y$qh3W2Cm$^%D=M_G*HIR@hpWSu35YgqML^)+y~2_QZj2DR;FD&RAWLEv0*UUT~m$rbH4zAA2!j$4-PLDOK{ zLstL72XYQq=q zJZPn|*LpHF%Skg7z&Qo^tE!VtK9|Q?*?3k~Bt76X&k%*n!O6m?|B3;d^@Q7-bWOeqdoj`B|3F2PX}kt)bIBj zFF-b1&o(qW%zC#Bq|*EEF$6$16a#tgX6-K-)NT8B=tBeQu20{EIJjbN4=@XCOn-Y_ zdqU~m!~c=CpaC;qVF#W@|)o&#}Q{Ykv-)Q=}^%Wy=H>NLfj|cU80=m#87FQQ? z^}Q{07vpL-mjdV5TsoTm3qEKN(6G`j_U_+j^ej-upO!7G3*|28r?x7Dotg~oT@ITn z$rZkjAi&lWL0~7!pC~mm?TKp1s)wn-cJInzuuKSsL*|9{pcA0)^ba^)P~ho}pg7g| z)L97jsi(PLQ8-!LDBL)34rqDD#wio0L{hZGp4vY3_w;C~RXtj&i`>GXQ1ApYNipwz zm^GpSqQGOEvRs4DM0#H%XHML>C3aBf3-Vhbx=qyW#t5cRRx%--p z8bGxrI)<$1mB`K%va<>Vd=%maKv(UsrmrS2NO=Q<4Pl6lxAP3yrou|0DP$ounFA&E zv}xQD0-K*G#~=Dmq)SpW{7(WX%93zBwh-jgU)l0PKu$5yU3pjv%I%F#7S@27_Q>u7 zxy(_bb1_`@j)q&V==Q0IMdd!BaX8dedXZ{iWtMD!&X0b zr!C4;sb140qD>{DO;2X{2v}H$;kR6lgg2>T$6efM-e&`(3Fv+Ax@S6py%KYHCW#Oq zN*l0QQ&7t^*L4`7Y{u|lv=pk0hmEb3VtpY%uBbCD4t5RlYpLEqv&HI5LRzDsqw z;>0I$Mnwhr#kJ3#Po2F5TI~X*v0___5W9LEEb0h=61qpc5Lr1OlAV3w!w617_Se4f za0N>Y9j0KUiS!vIV@*+i&H?BoukcMRJ0B;E!XrZ<+vr|SU5O6pFhFxkG+b=@x-x9%eQiaj?9mm+4xa+%Y2`KC|1J%RETqgm(B6{S zQbxq{FoomNgG4phRQM2j1l@$3$X7WMLiY;rBE5abyYVz-#POX{;4t1AFEb%3K2b;O ze>pO*8qE%?#pw#eWy$>;24x-HsCsnwa`m6v~0Xk zm8U3nC}*@PLei3vut00Yif(+kArwJI9%z0B8Tt3k&mbee(fovrbZO4eKij$-`0avP z_+yNGA~$ql;2+%T$EJU5(mA816@RB6N(sAsA#GD)(ac)nxGY?o0))iEDkZqZh7v&) zN1O%A4%|tbI4kAIqTE^)1!OS*QN+?F-85Mv9H^s3nk>HArpY1<#tE?|A!hjkp^xrC zJM_|~FQ^quz%h8N@`?BsE5qzdgcD%sCySJI1wVykMT?^_hG1RcRk|0>LPT9~Q}vif z2_3RnQ%usmpbK_be2IqmwidsvOKM)=feNixXhaV9gIe(m<1lMRS@2}jcK=F!>{ar!($kbeI0ep36y-LV{wn*`f}~ZdF(Y#ZT7o;1_;u%)H4VT|pYxC4B5OtvA>om3Fd?a%#xK8}{3Cd3srSOlVYeC`TpJWNpj-qJX~)|GKQKRDNi>Ct|;+D=>1)x$4S4 zS2UJ8^&`H+Hg;Lbsm&D~=gy3oAxKe>1Wb(|g_?VMR`%7qJ3yqC%F({tqDzY&LQ~a4 z^y9<(dUy;MY&JW>^epIDk;EafToa#SF3}orE;s)nOb(wOaHsC#~E_Z|_ z>~Pgl2}PXjse4K~VX56O{^>-3a9L5yjp}H~T+7YmRF%Y`G%VC=8VX zpF^J<>Prx$e65h<$=R2PfxvB0rng*!Jx<>si#rl& zN=CfG?)6F9{^)WpHh= zYd4t5g|=QXNX762QMk9pD#~Amy3AZ+Efh0us_V#A2ZuN!2i%9EY9#xzb%qe$hdY6U zDY|V*2;cwCt6UUIJrNZEw6GG;O!+vDfn!jai`0XQ68X4DiGrV9iGrV9iGrV!D2R{{uCfGtOdh!U z#V)Qs1a3KDnsN2>;A%JhjPUU1W=2(Qe|Y=Mn3}Lt6~RuLOW4VAP+%vaE9GkcM3%6# z=wc_6lO!Goy$t*VCD&sPo0BvD6Z|RUgu*X|5eLts#9fYVQdudgAb!QI9*LMh`eLsg6XY zl@hC^>rqF#uF15ymE#PQ;Oe)&L#kdN98ZLB{aQKpSh_wtj9pOVus;Uq@Z`1QZ~;L| zhyAFV*fEO80RIdZ<1LAwE#wrf%3Im!h`3C)c4T)XcAdvNNSZLz*?Kab|62*AWX`K~ zSn{~Z7CnaTjTdS#7C5JyK%;U~IAH)qsKcyb?W2L>TRR4$*`{NQkdh{%JIVZw-6=6& zTc8%q*FQ7qYl-=;PDlvr z3=^r#{8lv-oCP$+T4PhZY)Pje1CH?)6s^6c4y3#YcC9H4vx$A}NClc0n7F1%HlhYt zc5b0aNH`GG=)AoM?A*hW+K2{WE09HjzPE65QU!HIV@);^H>6Qw3uy0wg8dqdg*N!r z`1Ebgv-v>YK&k-t7;~5pw3!MB&=mv5oyWZ-A>Lclj-v8vU=!SEd{oe4qn2bZv?eiq zUg8Dhmm@;_PN;%aKz^!}{TdTMnld(kG~J8DKTMgZ5>uwn%ttZDBS{vcka41C8jz+e zb)v~*&^KiRWD=V~D?1F@=?Yb|cO6dNwh@{5QS4VSWY#d_l*F5MiNKJUTpHF?Wb%^Sr#lW;hwk#%;6=Q|lCLRs~$w)6Q zZuNM&!h20`qycMQ*{`UJL(Cc@y+{Bl*C{m)U9qfCst~?HQ5+{l(Lw3p2tnYI?v%h) zyB3U#)Bu7q;y{W8akk;VTn99fdO?cfx)nu7qB#(%qbR0$C~f~BqRQuiNI8+{kVWlI8jT6O%iEF>c6bzHK5u`!tvkls3U4|(xJ;fq{=GYS*QbXx!XIsGBYHqy^4 z=Ierh4?=2`y5X&%!l_5q*inHLV^w2AG|OnTxZoK~%K1!M+&F1*Y`@r0lO6}YWQ{|F zk8z+gc^v#Sm17)1f!Ky%;-brm@M|B%4xlC#05Oy{g|ShfGEK{5S1Fh&-gK2J8g@*a zh`ULWsvsE>6D6o>+#rV?Jgg@zwJ?Q3Z;GHdil}1%du^3XW6g1GSXn95+A0souiD1N zGzQVoCFR|~Ne#11F(komv?S;-=WA)fKxnnlS%$qTMSQhSc*Z=OoENO^Kp20vTD*Wp zhg98)&%Bc~)0-BiVs}7pKWifmhOrc)wj;4OU#Mtbd}BudeCUly?A3CuKmW#MvA0+V zfW<-p1YIQnu37A*g+?i(HH@_9%9+zM^ki3tFMA^fbb6tb{oW|wNZAznRRcqKJ!m@? z7%wOox$n?$^bc~EP2Xfzq7`WKC{CwD5-BXTMh7P}UdvvSv)5mmVx+g~EHuV0t3)NS zm}*@vT$zL+vSO1f6S^T&n!;itp1W~nj%7NL`*qw>NCb}9&_E^Vr6?q8KoruhOm-s3 z6AFc72}2uXoyc2PW)4N5y+W7Pm6;@d}NWL|f6ZhOsTH3LShnO=9FBF#THtKa*N>WA|B zk2a=g`|>mC>9}77fS@E$9`NP_;i%6vNw`c>Dm~uaSBc&ByQ5 zp&1TkXl?i5IBaeA;dE?m_wCQnv_Gn;QN zwdlk|#b~(%qZQ{7t|WddDia(OKC5>+d$VDrPGnL{f7}P*^rJ}<%0|UOLM(p!-dK3My&|OSg?Z!9otiKr%vdVN1pfVhr&urgxMx@3H8EJ)j@SzP^Gy9)j>^b7qHq4 z`m8p_m0n^7E{(MUybPc!m}0aoq@RO3Fhwfe~I@A>0;2PXQhq zt4u&@RB9BL!F-}mH8B&Cm>tQC)(*G7Tv6Q>r!sCTAZC_VV)U{IpjlVL*vy794;8Ag zLBsoV#^NK-WEEjyL_J65Z?Xp0B5T$0*|uebtuu@jg(=4!r#or**bLWRURT;>GA1oS z{Yi%U6+%Ux@Laa8Fn;t4q!WwP1L^RNIUs*iXhF#0H4}jDwG$aF!hO&i_7y;Tnt*1o z)pxvMF#XdM&Ke;TBH9tonqoaAL0h*lz%NgAr)TQ-eX1lPK0;xm?rvMRYC>VVbx%=O z$AT78Mzkq_sqdw9UPS^jzsSQ>JE+j3^S z=Lhx^Ff0YC6CKLfB2ay0!ZMVMr3}>~jr*U{5-x{+(oskrKh+VcHyx_bCrdyNP6L{bV5~r4Mv74`0&n%QbA*+C%8+LqNymI;;G}Up+o9QzYhVS)z-<$ONcxh| zkGO&OW?+81NYbY>e=$|o=VWJqJe2YArjlDbCR?9cqm!aiQd$w*bxF0{tH(Ilujhw> z#pGH~38RMwX*D)c$Lgay%1~i zk;D0ViU?j65(NE+O^Xezg+Rl)O%cID3w;@-PnYT3`_5TJS-bVu2|hK!kWm}Gz$?a~ zpJ9R3Pe+S5be9o?{jb{y!DVJonr7;`plHpajYabYfs`1ziW=o?vgbc=y~6ODm~`l4{89nQiQ>NlGsw*FP{rx0p-6>4)ubX3r8IxCCQrNEg2 zjLdh(saui@3n})zM;^2yEFilt3{#LWaC0wNcYr!xEYX{&Mp0E;$68ch%J#mR2e;O^ zoloAP6H#GvEku%e#a(1}`6fI|m1Vf1a$0?AR}K0(eH_AAfCEdVK`b zNpreJRzHgI<;P_~eJ%gDf4r#w;!EXa@`;mwss6KcFVo_mq8R)bxR< zhfhhUH%4)KOBeNS2UU!EkeaN1J&My_)GO;R{Y`^bQC36M#mt2;-@;CmNx8VGp@Nsh@RSSh#sFS`4$5B;v2Fu#S_R4q%;v9@wClkP=|{^m#Gc_KxZ)SJQw8gEGvZFlhD?~fGqBEe%MMQ9G0Oc*vF9gKo4T1ie{ zkj3_Kjg`fdZNxHeOy}lkIGd1J>L)u12lT{IDY|yNfZ$_0!Mdjr&o>iGQ^qMxzinBh zq(IU1B5?e(+V8ZLUSUvWnNYXuTm(~KTG3{MPps%B$A!a^`^{g)S1L^O)c}M3BM4I7K`XsP%b$_DT|$0NJu!VJdDU5I6}+1afFtN<5+~VswO@e>>3j#%`QSA!}FpA zQJ8R5en=Ra-YI-Wbz(1@{ljUr1EC;?a zDVgd$%3&YJpkDkgT?!B4tR%4-3=1qlRI*VDnr1Nxn!iwvQj=7Ld_GDd3Yzd8Rn3tY zXyU=Xlh_DSp<5R#rRJ*KS!I3bX-(#W$p^=w;}IRwuZCDg$Fd{2uMtC;g&0sbI)n%k zX?c!S7@0`evyq4=4r>M)sHxzt1x>b>Uc8s=9OCd})mxu$Ns@YE9A zR-C5#%H5k1xFFi80kE{wKyUQTXM~nFG>*5Pdp4a3H6{KMDP23yw0B9+0L<=ZXA?}2T zlKySoSlD7pO`-Oe0S=bG?3n~+;WfXrjI8;6-j)4f3SJb+{Pq8J-Kc#b4XfQ35x>wU zupy(g@e85WglQgZZeFy*?Zht(4vJrRbcy(DnK_bjljGxz?e!o0{O|vK4lETD`SZC7 zfIG6}i#L#z-;{r3%1?pc&p4&aApud*Sr^H+S7*YMhR0nZ^4l^&ZvwL2` zqz0D|aw^b=;*fsLk3#A?3`)iWD4%w-sy$tn8f~HkQyAbN8bxPB)36x1hgTrpu~6wp zFRwV@{6^SUbH?B@14(|*XnG$5fsuc(!<2C_@^!QLzfR#9rva5>;fu6o06QpT{G`BU zx*8TH<(Eoy6>wm&X0K4v`WSGv#0Wa&m<`h@g@{7!z5S^_W=$Bo!UIh7K(;W^$`u+C@Gvui$S>6 zrBjdYp;P7Z*p*T#g-sS&iGNEX60*@ET1c1Wd}<&ds{PLSdt&@EXn&8OOiLA>b&{*o;P3U zym@HPn;*KPBg5}`^JASix8Kn&eZKRK&YL?IZ@w+hvHb!Va5_u0%qa}W+qEWfkU(?J zSkZY1;FZsbM);IH{yz-!agtQ~dgkUpg;xCf~Oe2HXOheepPy6Y{%FO0ms=|jY3c*oUnv`mwHR!FAvF3tuIiD zFFa4}yCI}sF$3+BCgfJ}BCO?sPY+Y*^O~o5^LdNCv4Hp_!8@S9gKy`A`JFe#}jcc+P7oF3%s85)vKuAJ-#%9>L zv1V)22{sPt`^t3f((KrPIhB=tk-F13u6 zXeAPzNT4*B{!)4AstxFh{nsMLuxeKtGD2{2Dyww@RfLqn-nq^SL*>$ApqkA{lFlm# z{Pa^fFNC`gZg?|6Rgv<}O*sEbuYF|lyB9lBT_#uYH?aO^%UOoX#d-;(bhYdlYRYV{bTpvbJ*t<0RwObz=gGtsAG*& zISq9j`Ar&@+8MCY)SN^c?@EaaK0|$&)N5!cI{cYA;?W82#N@S40)@xuw5E6mc1UU_ zosXC9z~rXC9Fx>XmsnoIo3s(>yZ7pMWs$)@S1OK>n9i6|Y3 z7-iqK$JRvZ7%83zCHkFpg=65aTphX3%9C>_N9>F z_4;b^TTI`MB;5r5@0;eU+gaxB?`4vOe$aDuSAv@YJJ5q6oO^o6wg*e_q8|KDelV7o z#CNkhGxC{|qiFe`6gSItQIaVl!B%AB26s&WQu??;>rep!7UA6wWKnf*LpHCw3(hQK z{UG6ptdHtnz3YwR1|eXDA^`3Y_ol84W<)Jx1T*870IfE8+Z@U>DxGIHJ zgIJm#N8-ZmtZ5VYyiH`5`UfNMq^U-lwAh^AowW5)Oxl&Pgt>hEmhkS<68`K1Z~c~L z##WN--G6{3{C{3>31f5C5*B9^23l`08DTg)Q7cX!vWWHuQ&OREj+tL8;zCJX-WIk9@4(e-F&q?bLf`XDf@Ezorz<08>EqaX0 zq#e<)JJcbYMViqJYlbTIuQOCpy#SEf-a|}~!Zy4>Vn3r6U{9cAaKfN81g@Jx}b5s}ggdD51abLz_Z5sLSq7go>=X2YEVb!ei zMJv4AEw0y}=cOh-MiXGisq7y|b?$4PwT2O6jyi#ABukfnzd$X#Fl9FDOZ&x%oODN_ zV?w&ba92r!6b1k(&g?>khv`_5Xj{j@GFFWzh#MUYj%3=lg7!ud45oL9u&ru(Lg&I*W@g7vLh&224m%!*9gEUK*R2|< z+brrXr(4yww-(A*foodQl73%k=B8JPYh;rjF5~D5G0R@-Qx>c;OCo;5D$PHEIEz&% zMQAP?R_kLgfdz@6=nxq!3h%a+P-lDUWAM3#Rl@YeD!EXKEMlN36*9PuThkvJn*KZ! zp;7lqxNbtcZ$$wXsAZxq_Yy6b%Z;L?CHGe`ml_LM#bLXkH8LyF0p( zMJoiW2$=I~p~{SL61T5eYo>rf$`PD+@CxI_L4pB&v(92-BlD}sg<6vwrQt9@8`QsI7;g~;4xm4)em zR;A7H;EarxbiJigkjjQg#efo#>YIAa>+~n`=zSY?Az? zIm$fb*4#2ifp;ech>{(Rbo!oE3C3HdtKfPsANx`IH>Zzhhm$ag zA}BV>1&d*`sbFVCl)5)Lf%+nCGCl)1r3$EV&x$oOlZGf;q-BIwViL|wU_FgFyI{t6 zwNA)%z}{Hdb=gfIcF(WxAyz=AG|aZqN+`wQ2?LIG;P8Z_-BAHFdsc@hu;o1tPbhtO0v=?(tP_Mr7~HKF>F@+~dTov`5307q z49>QJ#1>(a@(Ci%E0X~J#&oI))BVb7)Eod(f9!#u`SR%HP!NsoVuE6aBR8qMmh+VGD!ZS zc_S^MtT>D?EhL03j<{G4EaLoA!Ab+ebSZ>c7dBa9gz9QkK7)fxdj`kWG8!H5 zy%`&8JWE@kQF8_dpR6l?SZIWwJkUsAo;VlEIvtEJ3XKY%!BLesqL9&a!me_HHHYiM z#l!v=c;LC87wI^Rjaz108kA|0)cnRp&(JHPlhMU85t~)3yL7*0-&N0TJQpxwp&&MO$XAH zCWl|btwBSgCazuL8Gn<5pf#1ro)_OrjXLNfe!4 z)7ERP{Vs_j=aBHgVp>b0_MVQ^kf@Y|})Dr0>lhH<6ko zM0$)wN?+^{Dft1bd_R%WiPh3@0uKzEeMCyL-z8Ga*g-@JX0ew@**%qrl(7TNqC=!& zMtX?U9t073c8S!`Mv+9M^o0Y7l)GS#J~okZ#CosaFGy5hwD?*>qC~?sZ`hx?4|S)~ zULaPhl>%gTpeyw~2qPmvQP?qCUBt{K&8)9M&U(kSf!M19;gby5Q_eEr0nK23NDl8t zA=8X+ica^6=9AxvI5wY-vrtA5#2>qm4uzx3xSYtBQRP?U$DWxx-h$^RB97t!4UP?B zd*$~+^1IYHN4{An1+L;bBe|YFj_V2c9PH7qr(yjszxeh`8Z~Ylt|!NvaDoe%f{2O( zkXoU~sX17Unu8UX<4KRBWJiw^y*;t2rCc%)I17E|`Q$gagU>4>Lez!gtrJ(0*HS&4%* zVY9IR@k-UWmXc0$%sEn)b$bD8MVKxi0${XEvP^{4_bhCmI?hHg$rh2;AVM+7&ZQhwva{Nbh7>5_!3!UyMhjoM4asl*nGTUAV^1Y| z7;Pk%(`e@00bIO-LCondLc;`e_~*U@G&AB{P4Bb%94@Dy!%WshzWR$^9pod!!b-JP)GlN^4>k#lIyPTtjBrXd+zOfT58E{bu+4S zbc3(#ZrmioYGjdg1zGAw9^|#6tR=vi_z(SIcT0m>mRV+Du)q#DgogtLOaj3KgMoqI zUpZ#xZOp`Bp}B_d7<8?(X4=gwqm<=FzP&UFqfR#gF6z!DJ_@+eY45qcXJuU;tf?8nx{ZB#+RKtjNEY4(HQTHuzHay2R$Nsye& zNCiO23@6mn>#$SX(AG=CgPHYkPC9M#-Y6EXHFhED!a*F`9)%vL;m96M*M_NUG-bArR(&_0IgSMr{^O%3wImdVkov3N2POibC`O7AnV?SpZ5vSQStt zWFL5RuHc(QAMzEe0uoM3AGiknAA7&#RFGsV24K2YtTh#^H56zx3hb0d zWSPpA6q~5IQyh)V8WyVx+Sh=Jdd+|&hnW<+CWxcRMGS4JDIKPXgWg&}B1~5oqF7A( zmfPC3Is0Sz*NI2@S#5s54M~t;FEwy2jEEQDu3h?-fB26zaETSz;Iw$+>m(I1jgpF* ztYWx7mR0bsBNK@n$c5aj=G$U5hfBF#&FIX_3LKcVUw2`_w0esc4`O!M_u+)COy=Cw zyzOW%f=>@Zi+0f!0aM1a4&>JqX5cE^=!$@LU6jl^^NIj|MyFC6^e?-!cv;+?*KycO zrK+8jhJsE1fwmcH0^9ifpDq-i&qsI5N_F?e84rLk4?ddd34iq{ELlI1>k)tT2(@0| zd4{#~j4JpDd%T#iQ`yJ!m>A704-b!d`$(=zKANv580b?!TqNzG52C}vUk?s{oyBXA z`@4re>q4W~_*rtXcY&cnON69)5H>#0P^05gzya1~wJbv|EyI=sSY%6rN}Bpw(^rOTrD3Vh)E(|x{_wF|xZ6rgea!dIM;WF!>?3k}C8S;U2JXdEc44mSfWn?t! zv09?YQHLm|kh-TpagO036O4nj*)(EnNu0tLq^%Po_`4mOZc+cy((GH%!=QTqsZ)e0 zZ&ZjT8c5N$ROGDX3+G2;>eDq_Q)w13nKa#&uk?JxJUOu`8(PpzdxE^1kMEL2W6NMQc}(c={7OBRzqLaW`RXf=DAQ|P`}pvau|hMAON(<7 z`;fVL+$xO+EzT{e5Gl-GP#*tW&R{=GA7odujmQUW&y}Xh`e0Js&;$c z1<%`Fc$0Y}0q}AURf9hdx(aSy-f*s025E*u2l32cfEVZ6D*SLz=vOS@R-+|_);=Qe zdX++J6TMMI$<-bbMyj<(%}hC;tm9e71h=!cuFOQy1>6~22`D0JHM=g~hb zO_i;>f9n{rto7%HL$s}FABYZ(-%pZ*Mj^rRr@A~XkjE5>bKO-k!Ay+kVYGg2IM z_<2$s*ii8NhVl?JB*nq9B+<3v+gwl_&NO<1e5U5z)zEcg8rvZ~6p6Jk{kEki*8RyIg}bEJL~n^NWX+=>~Q)^GmU z2ir}l9L1~|!9749Q*04sr+n2+iB&mOr#f*3%>H>gf4v9dQO7k*Np}x7iz03BMH`*{ zfaBt%x-=poQR_?S^=FvP>Nf*3WYbgGKLi}e#w|tfNrt$|G<= zd1Ve#ymiNR)Hg^9L+Mpmd*QBL7{;Q)9kz#9{(Xg$<^2WQ@PszE1=ffjD)1rM5Lpy0 z(-M0S0dFmM0%PAA05Z>pRShZeMa3>adRLB}43R7CofaLJaUN+q9o`98v5%yf5xU&$ zRI{27iS4TS&BCgzyrtdOTHV@@HWr=AVn3PyAriRAT>Y_2v4Jc|VqX7;jsZo=oGB&d z7#=!zDy6`}}L=uc9(BxBD$7ahb#*6l_vNRtF3k4cKEwmXwlnaQ_P zB;H5-f(^ZzWx@bN8$@I=w5~Vv?y4^-K!i+bOEd3_muPZEPMhe#K{M|eRd7d=ZP*5k zh732N2lqt<2%Opm+_;T~qOFZ&!@K@%z^&_ueYYBhTu1WhG?6l0XIHqo&a0~KHsCf? zCT#_lx6N+Vgz#*kT6V;-GVMNKt3Ic*SKO5$)Cl{QYSfoTeyoKgVk0j&kTYz~ z1aB|vu-N!I)$ydvyh4ySAqSzx#{7J1sze4pUM#lK6ca7Htb~_)#hY^d{f4HNw@?de z;;HO=QVsm5dDvQFUcF`r zgbMFt@@u*QIZ|P<*{j#wYsz^4r=1-Y^)Q0;pphJ+qaZyW)(CZOnI!k3zYX>4v#qui z_){J`)Cqu8yil4Ombr!atnL@$QI%{m1eM@}gTn(P0nH1_z0WQ85C}l4lggzDf6Vk%9!I|L!PpRi}=Tqry{+`#^uZ@xQKcKW|(QLV589X(xF*dXnP3%()L(! zQZ8)0B|>1cCVdLlGF;!*_9k^t`V{LHjzFRk%1-J?pF)omh2zRxF{;JSkP%E2CA&~% zDL_6`fPA*=ZxMRaTJI?U{U&mj{&%!JchtN1-E*XqMmEa3LJ^Q@5ruI1*u~#T46+oO z8Ue?I3fz*^G)%VYL<1P4+*#r*XnVcE-OtjZ08bgOVi#hgbf!tBQ@7}^XmpqwMEROs z6odLrJ~LJGtj9{qI=}*ugh$kyMpr4i04h2FDg+=Pd6k43mMPIyl1v%#$%FdOIxZ*8 zj(|p3f>Nf*ud!zG+dbabusB<%$1^r{G;8!t=z?jHa+_A^`^rzZIL$8oy*)d6XLgiT z$$lYL@~P~3AtZ6nqgF}DTKRYB+kzJ9G_g;o*iBn*GW2YtQA+B{dqBa6aTh1Nt+V{p*ruU>z2n zx5Cjin;#8};kG;$+lf|hi&k$#t2ZG`^BWD^qt)mVBK@NaGAIEQxQFCYopQ@VZ4KR4 zS**hVbcC^_)O!@`_~;m=9znyYj#Be6_MWHx9E1$0n*=*e7duzHAz|3g;vgndJ7t40 zb|Yz+4M}(UGnoCyE$sp{-kZ&*;q?8~>jo<7}pUNJU>h zdpF&Y=A&N^>(46zn!b~YL+!dUv{Bdz=e**KcwwVc0%aPSGC^qI7_mmxQ3btuyXb&; zY(O(A&w)p9PZBxKjT74!4nUm}H&UjUMW)7{5+TEt%8q;ZHx+E#@w~+DD)jf*;lSJTb|HY3uz5fIcf9dVt zvOym3aZ{L%sNqKz-lSxUR@x%Vg=F&*IC@|)HY~7kUKJKN->w%HRBKq!Zi0ox7hqwZ zw)%y%&r&vas`D2C4mdAXzp16LnU=z)mcr(4c3U<->UE%{NX`f@$Jw%p=Yc#DvTiJ- zoC;1_6=S_%Q2^5s|MCojs|!CzPTs{fGkmOi4(q^PIgU8-o|bu0@`;-v0FY(m#lhYv zayG=`ScXi3<6#16#CLEv5i9Sh5L31|mKKL!^Q2uIlB7V~?&4tiN_2$Y(&lp(vn%r* zMnId1JnlrBeAe348p{A}+IqsaHj&3zkm<>Wb_$T^y%Vr!Fo?dp==Goc(<0H!;2NFg>KgDE?eNVuE+7o2%p1bCm@o0$)oL zDCG`L6D)TF!y;GJbaCX$TyDGN+3;`arfjwaLY8zOd8g3!|}4n_=xa*ygU<-0QZv%Mf*VZ)$UIrA<^g zwaLY8zPQsSrUVVJ(`KO5!8XsR%{#hno>^`4j+HjC5UNcsZu7oQo5^6;8;?`DZc z=D=7*2JhY7X5;lr%i7hZrge4Of1}fOvNLwtUN_$J8t+TH<2~PPn0G6!YDb4!)zz*3 z?M|!7G}&o&-H0Dls}FTseQ>qahdQl->&bdKu=P^y+lr~@U)pK^OApNQy7nJd`>*V_ z|L|)2uk5rx5M%MEb@iyfqSNYE9B6eNtRGXWPjp*-Y_-)VR$7&fRAbfEt$tnJX|^$% zUIVmWr*^TLcChPps|`Pyue2<~s#@07Eq`mYERxaKS!q|~nH6+^WW~mRd2|b|AsCl}^5O z*-3Z^#9gl4fvyW!k#$|M788Hoh!w!VApH^qH>#UO{n>IZ;X`an3;_AAtajSCo0~3F zHzi@?CJ7riA$QXR%%P+pEjjK+Po!9<$|Utg+znN^H*g$FI-Ihdq`o0d59d3ueD$h{ zQ|Qzf`vSz$=4=-xB@G|aF{Hy;NQbk(u8e(1hoz*$S)4&qr!os-~b9l-~i3B!&uou z^~gvNwP|ph(U)!Y1*y^~Ko8Xxi)T#BQkvzUES)JxK)kxOWHQYxo9cDdD$j-=r&)r+QNfv3tD4<8{2_ndnFl!;+f*Jg0J!Z zWh(Tb*;ltb;cR;G3jKLl=7-`y6+BXa*M^FGG$%b7*N^4%o5O6gF45(Nj4{X4wBKCK zE)mbQxXFH8a*)YMDE;P)4L431c?-M=y3b3$My>HD$j^^lM3*V6n@H;R+{Mg`4NPH6 z30vxNj()|bP^6ag#*QhD9r0a&}J06GnwFWI5DL zC%qt8nDTEllz$j`9B)!m;paa9?I*|c^I7Pil=5Q2GjGzcp#8&|Q{rxd_79t~S}NdB zaQ|d0Gi*@ytD$JWK`~o`!lCq60fkAnjc#Uhh!n!p1=J^)!6yk7+4U^4VN{G(QZmR5 znT9qJr``~!-VmpDq@O9p8w&(3R_L3G`AxAxdmTqe8?4Wp)B3!r+PPE{-beqLp~(Wl zNDFks4`o{QbHvRkHIrDOtU1VBJB(Z*etfzy`+1%Dax5|-I8CIz*l0V{Amo!>B-WVt#=~YZJS61YLkoGyv=P&>Pzy$HMDqK zEjBhzx2RLA`Ov;4z3a4SDC{cGv(WLH{N#eai-gtE+L?XLPP355jdsZ53hmJD3FJ*& z0ZBXDoc-jX2s&=`p3ade#WkO#feWPT!cA@=G$vda%^{jr1|hS!MLZ`hpXypsHzTPfvS9nvw+mgSUX-N)>${11^&0r`mPVX_qnDn=_6B@y+mBLVJ|%3 z5<2U)b=Gk+cX}O- z63s{`HSW$E2lKV_Htx>bxHE4cyXI}&?bdSM*hqq&-*ikGzM?WQlC#@i7lQXsXZI~O zuQ-Jap?=9$K5i&c6J85ubSV)&xVx#SYb*CYfV*+I@$LD=_(bzsKFUNJA_JV7maW`v z|BX)D$yR<1ZKt5z;PGzwe79lQ%Db(~My^(Mb*q2dtyYY;3F2KlUd(fDAO-RM$F1dq z&QP(TFI$}c^1zX6ZWCeCHUQOfi9;eFOavatp{4i(cDeE_EEIW_>lp;xKC&1{=#}+Q4@5<{ zR0?E~_CrK9(1@dN;(+jeXy|)ZbQV7BfDU*d(i zRblo7S1{45CseQBbHx5&lm;|;bk;Tr06t&5$`X_Ky&mu)t->fq5X3|LIz!Y}p zu7k5GXTly`0S!b#k*H{f3zHu^ix_xJT)SXc$&KmX`$(jRbz=8A^UsQjJ>dd^Z2ru? zSB8xOeJg`?5$6oCF2MaCrkCx}@!fUN9v$Bnr)r8Ovw*chqg-cU0Kh`zrbR{jPJlfj zPzg1d{8n6SaAM7wLVd6owkIdcRr7YNtP4Y*?n|~zc+@~&Yjh_T=uq#xF4Gi?L@{40 zWJ|beb4{+gR+r!O_cn`djvnHMm0-19Y?Odb9a-3KRzJx_b=$4;|Xmdood&o@iTQ3ow)L0=SyFRIXaxLaGW_tLTUe5_58gQE0N@9C11!T%acKV7{S=eifnOxqvTI9n&=5Fn@>R z152JgHs4^3YGgwvs{{jcSaPBIe6-J&n!A6#O?Qy{aDP$pHpqlPv~_vz1E~oMRE0!U zKgJnKyr*wk;Ke)+O>~z56X!DuObbFzGSz@pR{*0}HFDPk&t=pz&3X4S=IA)y+x(T| zWz^x#i~Qxk7UF*3`GX_yVo^XJs8C7bmmqMba?CRvqf_$mJk-OO#*BJKs9bh zIbL|2MAvJab(-ptK<5TuqT@#lv<<6H^G%}+mEAv&l;p*tfv%1*@rHZS{$Pjpr?Ro> z&>JlFG=WkNW1t41;n?sLKsN84)7uiQD1Y^3$wJliaSxCD2nLf5z7b~(k(--E`6{e+ z#sd(@10t2Z>KJR<##Q;4g9Mp4AK;UVOL%6?a}b>v9SlJjqWFD*T-0qb7LuT&C?qm9 zz{)eCaoDv4+wuZSo(spPs73Di&T}qqmZ|~Q{34D6I#3bcxgrq773t?#C=vbgnLw^h zT#c@#6M&|FXF$3fEqumBOE83xLdq+qf(Yk{*%Tq1Qzr2o_p32c_=o>Aa!B)pMUEy? zpostipjjj}#P7G9okuOs?#f66MaoMiE7OJPIhEaN+YFt!H5o`64WSV_OjDXpct($@ zq2oyyN>3yU(+RwCddClWH5$)cu9!Q826LhO>Ffov3DJvFP3RqqLLM>zn}*Jv=U!Qc zc}%4hBU3R&-STr+h7u1{Gu$)On0SAv;&fN?%&F)I7kA{&wj+1OxM?9wQwKX@M53xw zYW_@j_@`F8cBbu`J9auddslXL`i6qMLWp<0YdM*+Fzq(c@2 zyDd=U@JIOyy*Zt|A(xejg@20M=xS0UInE=wp}0$+qsOLFuN6^wUFvaq!d@H!6a7{1 zAOVf?N|$ag-k9IX{~Cv4VqV1m^y1ABeV*vrN`qwG(;yi_RbJxFqx`RQ08&E`HYCU| zA7;}Z&q-G2_2OOc1;R?9pRKb=iWSTPc~drrh5S)+X$ig9wrrx+>L5?XDFR8R5dp~L zAVc-jlGb58(3Y+yf@&Y4kfO(vJf)Acgl!;2Vcf5wO{f1%$pR9m_hAy&%fFp85 zauA-0wP_T<0KXJvP}p<|kOZ#b?B~hjskbZvY6$|??46+mwWz;|{c88Y0;qIl@z9d^ zbVOZD00huNpalfJ6u5gOXv;k#t*xy7IR6OK^4BnU%2xw>(>})Iu{FvhjzGKU3tY0% zDE%N*Nlz-KH}F`!sc}5M?y@>ukSe4qE`kJ8_e@TcH|X@y25tm#Kma;$<5R~k2i!Pd zbf`cNc!1yr-t@suam{J=X}|TQbLW@^KXc52?;Nw>JI5^e&M^zVb2^(c;uD;}rVr-o zhha`ZV>L4&lw@rR=Dqs7VO}_$J20TG54dAtgENXD+ zhrgnBp#Enc1DO4j@Zm{56V-vmLv_*tIXX0qQB0%@4^8DJGR0qn4TPssDkK1m7)sTZpc7O4`f`&dn(dW%|y5XobdR@ zpqN>*}Fqxs?)R=e0Tsl@~T&wX?oBp=kYfZjrJTkvJE*cNIKtH)O2DJfm%B*h34pS(f zjq?m1?{_T0Z4C?RH>i_Me$bTF0Kl7t^HqC|dqmPHXf0XO*tW6+g=Ly~Q?qjXa~=-v!C1QcLObyQ28_C0RY+ULkZ))n0^SR?9Cuy*1T z92UUaC2Pl|*nOBye>YcFNVxu|P{0*wfv)KSQJ3GZkt@@7lEGSW4oc3K!g&73>9>5a zB4_Ft#pLsw{_+fBdRxX3yl5yI|FK80YKW`pkEznJ{T52r6QySLF?iQDUlC4$Nx<8- zw!+NK1${HjbmFVnO3vbHl%z=4CRW}U#~eIwj&be{5;4}ZX4rO(76*=DE5O?qc7n0& z1UJx*qzBln)>cyHb*o~H9U%Q~?F8v}YbO}UP5`kL-yc;sgrG9DoxnvcpCl86>;&2} zg2Xr>(HDdVYqAE#YSMZ|R->HOEk-B& z4jb<%QFa-_#Xvl8{tT!})j8@PhdDxr{JF-3@ImZ@QX&ln7nYapZ4u_;l zjsf?m<&-dp7LX8S>xVXsnsY!e#U$6Cn=qMuZ)qDR5C!PU9RZSP|E-;=#*6q7R(XfH|1y$d+4CChptq;@71WOy1BXuVD6?Bvx<-w4Z_qxnEg1vmHL zQ4=!gcs$nDK#OWaX#xNQN+zpNJAt)iy$Y>VF>%JM#ip@pL#(DZ22JW0b_Qq~7nB-r zl$5>4L~)*5_J_CfZ4ePbWaO6UDBn8K{XGfze1RtfD zOAFCV#R@Qo@;tyF@bn~VBAbH8VQq;GkRAYE$S{XKZ9NPe3Ztv)b%E%ShVAjtAB_iU zZkYs@7yUI40E8aaf^g5qE3&12DJf95U#MVf`h_y=X8A(>BGh%YU&AB}sl7veC|Vjj z^{=v*B2!Ey`zAhwGDknmuFROqkccEE?;sJC7M83IHlI~!A8@Y-uXLC~7GVlJuOdu= zsS7`fUNdpq?cR!96X!e~eG|v`F>y3NMrZ*j_r!TdV1F%uG^w6AE9fK-Gk`q5a(5U& zd}{q&2$o`E+*8LW3|A1bnYfNG1v$Vx8f$a(i7!w}_w@-ZS<|QH;99XjFdJn^leX-W z>P^VxP^`Cx=Or{DtO*MHJaA;94Ba}@6E&?Gm>7=P&kGZj`I7a*FRZN0@}{UC#0z8Y zW``DTvbd(AhSLr;BxLE!s-ht!ly9gZs*%b=5oNkf)Np8OSahi2>e1PBWl3oFy=n+( z)7GoibMX?@el=>yuuTmIe1)ubIx{tlUk1vO8uET1BG{7XMIj(;)2^k)hZB)CR7dh z$5HQ>!^BJ=iI@qObYwRQjQ6+j6{JDzjj*~ai=AL`b`zWL0-OQDP&EZuJ1^ND&=iA* zE%Apc7^!8dLKneN30XiaWFmy9ZA?so8dynrF#7uVqb>q@7Kk9@i~KRI1|$OPR`9mW556u;k-5B#l4*DU;hN0{_=U9jz<(Ugy(e6^!%g zM{ZTBqIwoB%Gof``SjvmlMB@(aj%I&yC=JtQdn;x4MlGQDmY_=1TgK(b7!6qcJg2& zeu1rz&9_9~h0(AGkkvD_Fz$dCo;Bq9@Fa5NhRBgjGjh-3lv?q1q&CNHlaKpx*iD6- zLl#!i6*~t^=|CTz;S6FQf|`-`VjzR3xFDoS;((Az%dzaB>G#25;2?|L~ub4^p~dn?kY8xnduBnJT~rx2(WQR#E~Z$)5r`tz6LfZJ{jIcF5vD|-LJr~pi4YkHf+(Wa_q2*%P~Rj@o~)W_r?`Y7Kv zpPs!q`{q2I;lk!7p76IxpkG|5iiA|Cjm!y1HJZI8M_v)m^}WXNLdTMRWgE-kg#m*K zi#&)6A6^)stFY+C)eFmTMq!CEsc@A|$4DvqbpuyWsV<+WKlpv)i`-7Xkkdr;a79u; z7hl7bizF$i{&@~KSGn@^%1&|2@ekApR3Ueyt`Ti6uh21kYH?qYg*JpYdf?*)Tv#H_TSvbJQ>*BV}fx0&$Cp!aLE3vW9cgAm2~g z@4Hp+dsQ}7H&;YQTT&H#39~Kss~&KWR`nPqW?Q~m0wur9Y~vTzbX5=DOXPyxw!^|N z0=pf(+UdHPpUwFM0?*_vB*4JuxCAeFPE{xr{p{*U!WX zo>Scng}ynl0$md;xVd2ku+wU*Wd$uC5Dw1eS2s5Zp$Xm2`eHQ}w?^O*Pf&~Gr@&WX zo}eBc-XgRuc)}KQHcp`+FrT_I3ldMj3luydI1wLIL-Pc+2-4fCqb+TN1*Q{(E_+|( z`~c;K@2=4Rq58jAX6E6hG3A5JW)Y1@>nWB@o$Vg z>33`7Nx%0Sc@QSGB$DVFT9u0)H1cSIQF>Ak8HEsP<(CKfWCMa6L?poURSUNA2>ePO z&ZJw3*AJ}#E(!t&DJER~;x!?_aEKFQ=Nl~k)N%j(7-NMf4V=~KSTM{R2}aPQ0~J-s z5f~HqD3N$G~N)1>ESA68sn|aw4h@-LJN*8?bA$#r^|h$$c^a+4xg! zPUlC3cC3cj8GSThJcF!?I%<%fSwFDfDT$4x8X>I_(J3w=lngrBK}kLE#&u7#Y$^Gr zYIK>^A)~t`Y^5n0GbOj^`q*@irz2WC(ump{mfesZpoHO_Dy|5+!xM8EbijGEs1tx# zwF6&jzJI>MsEYC&6TBf6l1*&_MlqL=cQiIL7MBenou-Iz<1TO|u;s{o4s03nG2$pc zRDMffkLf}S$j+azHVMK>aiOH15$D8gO|hbFZRa&Au24nMNX@-LiIgoVd|Ohuv5qN~ zEWg;YHD@uq7p&TnLnenaFs%sPx>(4+l#F&v*W)~45h~E8PSG{xR2B;XTX9fKAezXl z;1;2U1n|QU#=sO^0~d&(D2kWrd~P>^p(;;;+4men7&h{fO8-yJb%&Ilw9 z12OGX23M0AS>hbe+PsR`a#+qGk|MQPqI*Kkyf)cD`-HG^_Kl-k5Ty>2()z@s`bkiv z6)^u^3IkD>ctMw9+}$okhn~#Uqc=8LsEOj>6aKbi*U0^lzZy9a4*%m$M;xZnA0nb^ zXxA#E&YlM(5glhn4u@!DiZGb|&XII(K>eowOoo7s`psN!sK153H_r0Wx!T_L%mgj& z!w%@;zwzTF9-`#a{I48ry8j^m-&Ex@L^g%olkX6uY`*lp8u~Zie+^$A?|kWdefbO5 z(&ldGOW*6upS+ef&vd@@y}tbVUnEWY?{C!qf%}^or|$o6?w`{g=N+9deXlS7@D~pG za?RWVbUvNgp4+o98vn($6szC<$IJ--|KNWa)okwM@1p(}zK_38e~4ru^z*ja&}H-b z3U5_zxBg2rPNrQ-a5 z`6Q44!)^zN`3myf<)M-6CeG#djj^4#9VQ`CFgSE|j$&9zb_}_+w|T z{^0>^*N5-;HqIlUpNIDK0JiJPkG=I8zPww|^@OmGO!xZo55DUfzI=~lspix8;csuP zzl&w1?w$m+x)*MJMi;d2?S2|R^y$C7hEJdBei}dY>3go>)8FWR8b9>uGuQCx`@5gU z4}JPG*YN4n-B06(KK)lGyZ{BJ{|PX8eRF@Sz_gy8@a478ldBf1pZX0g{HN%M)?8K3 zS@uLc{?}3cUjBc}pEOkF%nFtH&F6Z7eKtf!Mf3XY6cmy9%k^J5Kx9liRV;|i4^mW! z@HvdOkI1}8*reh?WUi<>y-!vm3%Cer6o$AIo|( zj0@#m85*FhJkmIMzVkRjD;b~A?qv`dS?Pc6Yj^-Yf3aczp;qS^2 zUEM(>JUijL_BcdkOp^l=sp$^rNSq(6wXm{#=xjDcCrC9uAEA1u{Z$ob`TcFVCicTw zJG0ECWTdkzQwq2=mv_hIzy$yG_x<}{f7eHT^t*rR50*G_Pn3OWTpo-Ihm@-Fhq+Ad z%EZFBfQu^??1C|L(-<@Rb?2n+41#G`83gD(z28RU^JR6-uq|mW)^Ma$p3#J-5 z_ao&zdu~p*?%pk(_aZqgrqqAr~+zO5hA2nzvIv_o4uLF#Ko*n`BW7w#r|L1~ z^q||`b7&81d2Zz7O`xYk-&ho~cv8Po=ndPpk9qGzPirOSZFk>wR@u=Z;0|C9wgw{H z<%NTbM_+|M!m~ODA%(x4G;$x#E-}|EQ%oQT`0`yST$=^0<g$k zkZLd;ne|OC$DspjPihy~02;H!jLXR}dny+!dX7eqjNZ1ZQ*y2MMYi{&M{pfz{re0? zFHOj`#>UI(%VSl^6e7~P@bXHhzoYQa-j{v%O2ET_BS%6&fjwVZ$fZt!vNe0nF% z#xkQ~V%0&$^{Cs7zi$YIQAw( z%_~eR{eZ_R=zoRtGGOAz*9fgiil*Z^a*U(H!Bda}WWYlf*n7{fHmZtq`MqurzeQNV@B{a!?K!i@)128wV#t? z@DV5;;Rw@(&_pW-^O+;*<-pZXl_5S)Bn5E!xOf1~GrSY|JS)$ETWOTm+4@H51xa;6 z!T+MrF4e#|BJ~gTlAH1vOgZ2g=3MV3lN+%V?h?zML-@I5$xo-Bcw|^Z^t?qtFEtQ` zmjvO&OLipjlT9OWtO5?{K-Ny#swrE!EZ)2*%Q4mm%ARVfk-levzBb{YqMYY`6+Qq)BF;Fy=J-dKi4GqyG~I;(H$ zzNk7c=G_;kIxo&%nhPSQm+!@TEHvdzNJA zxZc)mV-0_WF!;Um(DZbCY07cAMK(LMB*UQZx#a9T$=SK&?0gp#ogU*4h!a=`(fwnX zf$V+iuX#{*bU;|Jm8IzeSp7m&EF5v)BBbDdYImO8>WYiS@`?ylVbGx;;W)}V-HiwGe68(DD*8Dm~f?R8QAcu3=HBU z24-;z21Z>;D@h#e!<I6RTfxHU@sfb7@G!|{${MC#BN2&-{r>yj zf8zsq59GWGCN`{pk7o=e6+FPj{^>jZNJoDJ7i+#p{mfR`7%k&N&=?lX)iGKSAM`xLWi$Ob!9W^Ib7Lc__x|lfrv0-JPm3f)2 z|6gKe;@H7Z&jPtj@@X)>Gu1&RNd!tNe2)urMrjnjdtYH7a2|&xmzNQX&Ki3NUYOTU z^L?r{&H^0;Z)M6}M3$kv+PssTwt2O2XK`K>$sa`TwC1Vj6)!4YfnN&)w5kI8#7~Q; z#gaG#BMuAmDu6G;iI2~{`9XYH2rIsfV_1~bGKy*PKE9l%S)6x$q#Xblq48i;5O zcC-C#v)S92@D`cDoPW%3YdM^v+ORbdped5ANrDN27uNKrJ^{wVf^0aC75WbA(b||T zX;%*kcg(?B-h)An6?QGW=WQb>a&b=oCjJ5rc)dz`NI|Yw<{7WUz#%_d)`VXLW-$X& zYb8a=-|8RCI5Jn-wb4A$hvyd=nZkL;#Aa#NhBE{ruduek23)b;FqB7|DOe2mkDHcB zB{Uu(O4FvBL%v)l3QSKR&uTMwo7yy#w{4=+t4%I$^EPc#N^Ra2ja@^V$f?Uzfo{{% z`m)WFD{byZn_S%H3p;JT@S5A)Rh!LmC~k9CBFnPPy_GgO2SwxL;x=F0X)_&%at-5z z)GUufahqpW+q`3?O>(=bO)hTpKDQ|hy00Cj5(^+F9+*wSBV0d+p)ALg&OK?SFQFL} zOjO9|^^m9&caSp(lnSI;iZ)H0QFHw_^cUi%alTxCULordqRjtUI!^@EIin3>Xx^P$ z6s&`G-%ZhA=fP;m5L}>X7CY05@DI^TK3wLAK(AiC-5UmL0qqHK*Xfv&dGTKBJ zO)%tcxgsp(rU1%LqB?1sd?;h9`lA)mr0Y~HC9~!OyWOT&L~8T4XzUu=Ofi?8Hnk!; zZE8g<+w_XaFgV3Hy&@1BmnVH+eU!TzNwXe2Zmow-i&_s&ivT^8!|C_t7DhuJgKxFw zEs99rmC2X8j`F09EKFqRYhC3j?C(0@3gLImkgK zNYuv)F-qc<#aw5(esz3WQdKMI2 z;ZSGF)Rdh(ICo?t3)NqmN((uP30-FN1G#cEKmd0(Hkf&!DbF;Br&>TGRS6nVNo+84Jzy;0k|Cqrr!#=8{%A7$ZKH}PIhT~SbT%evA~St+u)tZrcncn%~oF=8cOYxbTE zySS=7O$~AlyL1H^w)3K6lo@vD3Rx`BKe0!4aJ3~b%Y6UzAZ<&NZKfwNiTn_gWTC{& zty5n3CUC;Dk77^y5oV45y(vv+MS4@3DTxeLn)tLQ&DJ!?N|M^EQP7cQPnupc*93Bz z3vzlv7vZ$cu8Y&pp30uzF)PJ_n z0;M(`PN%z{EdTI4=iTlu=b7aM5;n+b^PAnRnnL<&{7c!HSvgW|q@ly$@Z&fSj!Jd8 zP`gKN`W=#h!amiTx&XYfxe@}orC3Qw3X~%I0--&N6deqZcO(xlA;R*I&ng!WGFAP*r8b-GDnI(tg`l1HWw=$1EA!=_DC<;ZI)>%6NuV3n#l z8(XgCile(@q<)Tsy3(xlOnK47)VC@f%}O8FnGLJ)^zRpu=of4gK^cm;f!3{He!i$7xDWWln zmsEcBkyS2`6kC(#O}HVB5QG9GP7ft*fIVQZ9{73isOGu7 z>3)usYXCrLrazh|hf|C6DVYa#)o+_zGRoJT#Oe6lS`tg#<>b=rGdX>|{w}s=$U%_u zVKH+&d@B!`bPSh4i}Ly@a$UW$SvdA6c%w$_?uzZo3{ZV(mZm=khT$mxUl2jdb3%Jf znh<364TD9liQ~K3JlADcQn}xKqj(4jb9oF_%L|2}&JhwbuCs4~smc$4V38{c;PgV6 zM-dI|_5GUdd5()cuaC^$w}pS58Sjx4=-L~%HCHlN_4WMf8D3+NN zog}OOeMV2iolN(&{5_$&0-a7mE9*D^cQXLUx292S@|m5>^^;roDyaZt@oamLe4!-z z8W5upNN8+3D+4ygy^E2Cy#ka5WKRMXiL|{y`D);qAVQ_^FjPD+P+JAEdY8ME{=11? zIlr}4uB_kR^xu-PNPnmQ3}}D<1aNwKg#_E06`wkI1N%m77sOw&~bpvf&(w2Hj>q` z*m-=Q1;jbtHRE;+Ib%(0NVGW()|(TVMXx{+CCtSl!Jg~g1fodNnZEIQ3>;V~AM}Zu zy=NvBR=*nvs({Z>XckHVM->pisZ6QqcJ1~=TJVT8%8!>UnmEc3kFYSY(>o;`U;_$M z2<#+-fO{TC)1q3BMkSvMe+=cZA-;q)TY?){50|he=pSiMvP)lY1mAtVF+y$93B!~l z($$w9{F$!I3I#f|;{FrtuhASjEBY+8vodBzd~jA&IL(R+_s>e&YE(@BrtO7{T9^#2 zqJvsZd`0T2Kt=d1C?bSZ8EBRbC;r8f7m~U-S5Yi&-I=~~$mY`God5NeY`j!)FME|D zc*}GFeZzEzy(_!-UZ&MS{oD9Z3U4T?KTE5IXIEzLgtu$swVEtv?^miTI>{tMK}@$k z3j(=AHxv`fBi3>K^w*@(aFK{~ zfLw`NASMZqOUNWtmiIKSAmBHZmxBvjUzAigsO)aFajZ|<~! z7-`(*_3igA3T<7XHAX3MIt`L3i72obOIp9on#NMpKk^2Tg_dI(dvCmfkd|>(Hf*Vd zYr(K+exZ}}F4t!~5%r&Qdsepsd{KY)rFwEd!-`)-iDAb8neV5I5aHR6i^u9vD9{v= z^!Fi2vv=|52NYHo7^|VUJ~cI|pRY;G2pUy7Mo2-O&%Q&I z-xWzkO}f+c>j)Xj<<(fV<}rZ#_}<;W?=o+49rQL~jO>~c9yC&kJ|HetBfbv-viSg| zJ#vkF;Wi3fz4-_#nQL&TH2d^`=_^8rP!8P~S`D-Cq=RS7lKUqJz-M*MqVfshg621#cu%Mh|6D567UVKk5a;xEYmt z!>Ew+^$jBjCRC$QMY>vgOefL|aHl>8W^$X;{d*U=cU1`@peDetU+>ujUaPaoc%-;& z=N_(>Tr*ty51xFd@Z_!hSto++T(=1J#z~STW(-ctJGBVSbH zxTLazi|$tbIq;zKmJbelo%7xT$8k**#8$Mn1fr}D^&tMOEO3$0gD!zQ?w?CZ)X_?@ z>?O!&`al`CFj1=8U!2jGjDPss>6LE}Jm?hQgTr2{O80jd{VguqL4d$oKQq2uUy&HA z(NqO-<-g(s<;t3SZI>1uE-+ixul0Hww(ALLQ|XlHxJd}Z(#ea+UqL={DjY&SYOESC z1Sq%Z#)%*$4S%5KJYdo=CN#CBjI|U*`xsMrIrx4C*NF+BHklOxdy5q8k5ec#&>fbe z(I`hSEs@;WyV|mnPf&7aRnhW}_6i^VD%fjBDDd>P?2e4f|;NNq84y?Rlx zH^qpPP5+NkF?fCcRTzc9_+BTw7fqnHZkPXRzh;Av`FK30pTPI&jHCzos3dRxQV3`? zjYgd;8g&fXt%(E4yXqJ^fu0%~E0E2%$W1C32f~13;y^|HbC$n~`uDsToNdp{Umqiv z6!qIaW*E_qo5O|zV18|iy^OeisBqDEKE`(zTSlMWE+9Ur3r&t6AbA}vV9b(lKS`-f+1|G|hu(nztFz;i_kNl7m1_x@SJbdy4GrFSJE^=PSjrjsxmEM3W= zWSc@dhrg5PNegU@#LZ9;g~fHHG7BW+JQBl%b0T-EEXD9&FWIwp4BxCVZ7v3a8 zM=6{oUEX{12S96f^gI$g7-89!v@)M$SBZDa&+#-xQieiV8d-uf_k*WGYl-=?lbS_C zC9uQ@!GX-|TeL9z8~jTm!nYE9t{?ZF016_G;=m0+ywE~u@WP{#R_0+j@|hOqUAp7n zRmSEe_vfLCZHK@u#-?bh<9NvFVR5cuassWjZk`4H7aD!s>vCcki7nh^_UY&8iSQ*-njd|WDjoT&o_Hv=-q zPI}+iT3&o+5AsI+r0kYrQ9|>vu)}CBJAvdpE&VK1VC#Y1=T?o!&C1!-ph>Kug{yW< z2&H_F>C0j5w8~j(rxfPUPW!xVrw26Jcp-(cAC_1GLy?|zVA-mi64ij^B&nReuyiV9 z04(Tu?MO`)5XN7?V2xZ-;+NwC_~_6paBLLJ{cvoadwdf_M5&xnr*LCgC#o+^F6+cR z0b4&fH=XCMbCl-BsCGzoc?;^5F0$u#MQ^^=>Xycn)#{edqjxq{Bz608I6D*~lFi=7 zzMA@9{--0ezq=`3m-t!z%pb;+HGvy^_>|mvRi=O%=qI>sSDe1b{iLU9J7t9w{6i?$ zvCTG_KE+LC;rwXGjbOfLtK=)3Dv}!^Cf*UMFf8skgFt(IxI1>Iwh~DMKPfY~?#?P*&SSvP92S>y>1X6K0iRx*O?(k*KLOQ*-^k5j-BX3 z(75<(+Dsa}OGoa=Q8qjONcS9eevh*5kI|^$=U_y7ZCq7PYlAECuxy-U?ldHg-gjHb z?VMp$)RW6~`DL>o;Z!J1<{=@n0g@!paM=w$^D@+awrvv2Y(}%vu5v{#+s#$Or=(qQ zr_=7UJ>GoXa6!>dv(NT$*ETEivxM@qJ=zb(>=yM0ve}Qao(|5kjM&TepY37yv~OxP z{a2$1C>76bOvv3ORIskZ0Y_Ib<(;{7A0Dx+7xc5}_R}?u*|Sb3QS9k2 zO2-n~SC-(GlTF}}q}3Ea%4?8H8lPTUgdea3rH~C$kTkShab?bFMjz`BW|t!evr!Y9 zaxpo-Pr> zfTzU-9{zfnCoN-HyFXs(_AMoJcr7e<*XSa_j`L52GdYk^%{DSWX|KMGGQZ=F4(i`A zWh#M^Gz*(-^O8@(7Y88zN#kDy3a&5&$kP&x2leTOu7$%!4aR%b&#mfBmct(daO*^X z^14NUbu~?|yQUAsWNO3aL;=qG(=dmz!VzSyA_-QPMpvN}2mVQR+o(VCM!P#D`-GJm zHO0YDyNK;BlaV7{0-@40M!^PZsEF{!U?ef2c(j z!*u9_kj+5|*cLo;$VZ)_7J1+k;9cj6%nOj>DhhI4UTNvI4$0s>IVc5ypx3G)>`};3 z2IF3FijSXU0x|iy!a-BFx!Uzr94R?RS2zcUM4sqbP{7nf$#k$=q7I{ryb_sJCyQ<; z^IM2XWGf-C2p)v(ZFNj5Jje-vVau?H`{tN(iPTiR2#Kdjrp0ImO zPMAl%iKNl^G*9N3e77fOGB{=Q1~4*fp{O*EC^5lFgJSqgq+us=|5~u(u}@`d!liE? z<{OIrJx3&G?+%p0r`JU)q@unk~?xvYFaIrT#}qN>Q*c;}$b<7mx7 zO@$3Hkw{}Mq8%m}DcND7%P|!DLaMYZ$=n^gIQz#^uA@0A!Mh^fr?Zo8Uk_+lJHk+| zXX3z7MC6D0=Tc3{{mw z&{$RC8%+wF;++1aE^z1$+s*fr7}-2&Uf+|loHJG*MG7UPNsAIp1a0`8b2hiSlU)C2 z2<7GUB-J;pzlxK_S#QHq?1b>Ji#~iF!Cv9LAe?{lE%PC(lLjS3P&*(09N4n{_7bF6gCge3C?p3#;BTiTL6BHB_=x-Gb7zN!sVQ?wY33% zK?}ir0z4v_06&|py4(S>aD#7Y$BK6$G4rer2a^gh^j-WMQ5PW7B#xL9)(w-FEMeRu zw*u|F{&zq8n?HR=?&Bvl#6UV*b(&NQ20OOVcHj8GT66i_9B(7u9Lo+x`zB z2#U7w@UTqy&XeQ1HFfdKQ{rcyFyCo%;%!U`7@3+x(KH~n$?luB!C7eOQ|!GM3#$+8 zXtF5#(rPR_<2@!EAo9sboo%|RC60J{cU;c8WVsiYDlQ1JqPa-0x&T03veCKX9Q1Rn z6Dq3l?Cone+Kgx4@2xHfnF%s&M9-W0tS2D(ddgJm6hP9CBq3Iot+n6x@YUS<^I1DJifJ7!H% z&yEW)CPng*1E%AAPPVP?=O^QHoE7P=5|Mz~ps%){Baf*mmEhn=V5U_xb>E;_RC))i z?YtI4(4`4_0|H8eycjL@hsdl;^&JvHSujQY^WXhXp9f0S@8+u4h=YDzinl}MMHI~2 zl|D$U9rP>x)dLa`>pPSl$kH9l$Q9Smm|I3aSvopF=9gowT~B625;)fOz_A0A|3 zRUVk@Vn#jR8TIr5I2s@9u6!Uh0%`V)@Q=IOi@iHV!QDNbPb;+rftulItB`@9NMYuN zH;M<(b?NE1dN_!lsSvy@L|^TDXGk6h0?=|GGCO-9r3L~F)a6bMu&k)TUFI}#Eh^Q} zj_g1UJtGSSfSfElQH*OY%ITeS8Xh7QZ5yBp6D=93hlpf&(u_zORfS5BFtdF+U{)a} zm9rp_HAw!n)oX|)~IzE)7X+E{<29f?%g({t%v4ulT>KT)(!TOcvV77cp8bN>X zz@c{Q@7;Bc)LzsjJK`4C=&{b6%e<)Se#?tjf!lNMKVJBgPDY!tp%Cn>?+=R zIYPTcl)W4qQQJ1gMmpCvfh{jcBst8b{GiSi`5L*Zk*}GQYl2nEjijnsONd8`o8Me3 zVn2%@Yg*PU6#*>7aFk;D4WGCAt4os~#llr+2ew!NZ7l{|3|XLnK}*hZ|qBMY5>5B1fXr{KA-YYq+7N&5Wi_qLm_$YC|$>UmKYV zaqY3rQzHZM#}$_`VoPpasE~ZKF{d9@dSYm-`xW1b$m$$65m~tC5c1J9pSC2WWGqlQVxTWL zR5F!!{2C#!`HAk>(W=O>vyM#J|)3~j=W;gp9CM{8|4oGON6!EyO?{~)Uv zq~u)n_O+K8q`O34qGtyO2`RL>7mBz#v`R~>VYu8SCY(w7Scf;W>&BbcYTcPudTD_2 zCY^0QA9Hbl$_RwM;%!Fe*q;p#HgAh}@V3sooM|v&4oZQ2D(G`!NbF5*5_k3{MhH;S znfl4th?m*wNFkF>_$^)^BSas~9Ew5bVexlmU#yny%D#vT`RX5{%qdtAC=f{t zn95(9n*G#oWgF$2Eq?Z8D;S1dS?5yTp+TIr_HGJychcSmv-ex-sg|#H(<^|6h-ume zNkk2>G|*$K&Rj-wfDomv2P~R8XE3ZNl#kQd4v;LaAW@QPfumt5&KqfGq+swvITrp+ zcAp%U`ke~6y%>YCI(!KqAZ4vdk~96slYFxkXisNfq)wqCX)Vd>#r?6Pc_t8}x{Hzrqa-M(%G;W5rn%`S`@rAl_nyZ)rr72 zrNBr_!)-v$C2jKIMGiw#)7mUtm2uwQuzvlkE7VGbgJR?Yp=&x^ijXNygZc-_23YDY zCSrwdCedM9m&vR}85c~&;3WE8$YG|>%DU9=a`_wUp{mxAnW>Bjs09*@e{OaF85335 z6e3u*gLLTdFcC?)=YSRhfM6>55(v+Wf(baCeX#+&9?obl&QOIeZ)y0v0$&dRS+;Bt z#^Oyckh>rr0owra27PEj>{J*_5KlfmK&`XYn1l=lj2I#`0AR3ay6~wrYe?~ElolCg1dXIOPsWfTDAh%3j@GZz7 z;Trm34eo3;gk_g!mL&yy$1gK)>`G_xq&gJMTz}T3BeOzQyYx?9mKnRqG9QO1%ejk(WiYxA!^g*r4bv$3+42r6Sf4XcYKUVO6FdR zJN#s{>9oE+i4C%a#RG05x28I;D!bh>Xa4fnZpq{wpClx_CSDAY%S^a-iiLOVL} zYC(b<`gbbJXYZBGNYKDwSK6NL4OCyx7B3lr`g+L**Bfbov1&j{6$4`?=!I?bymksC^kNd? z_*9|S$PxPWUFPCT^cq2OAs<37jx*(G%zL+q&b!r?)5I4X8{MP&fS( zo7AOPQE8jd$pYe$N6+Hz4)7d|o;B1HxCwL?2;J0T_;h)e_JE9fI`Lu`| zzs|1{&;kxOg;GZS}H2V+#*q>hS`Sp%QVe%R-;9(<_&w&v8_>& z`bQs#kfg^fMUlxKUNs3`Rp*v4EhfTS)VE1}8rD>eW7+D7`5C(m#LueYTu=aSKT5?S ztkU~Y$eY4+Q=|-FRR-3CTq}IIfB0&{7D2a$>o%oYXva+>v|e#Qk;biBsJnTnAy42_ z8eL}wq(x|P7AKArBci@o!#1>?3D6XYh9BRAoE><#V5u@aLBx-5&|pAlZ41LgTF~cL zX+iyu5$2jQ?R_L!Bea+mW_2oz!NVFSpq_ztV5saYIH_fPq5SRT898%9+|bX8Bduey zc)erSF12C}0hsd)s)Ah8s~{yjArb?DoFQ}bMOwv*Dv+2UHDzqz4&c_JWl$eh&=$r= zX-~`+{;10*UJ8FLw{beP z+B$`Vc57Qt?;{;Esr>e}zHDQE>oU#5!?9bqj~;^h5`Ek_vDm5{n!|V1#)*rwUyy`E z<{(_?>bW}Qz6VYY5R@RqZVp(ve3erk_N&s`rNhWHzj4wN&%_?nBS|uMtNiWd@jFZ6 z%(No0FWp{Fm~#J8B+Jg7P$Q=0%p%j}4ymtHczcOgLmeV33~m-Tr*ODvPF3ysB@tSM z2ka6yY1vlAI4ML8_V`h?$U4&0nS|!pAEsdocsyb6^q@m>G!?0Wec6=1a3rW&x%FTTRSHn!rQm zTOAUuNb_bq`9!C>G)3!7wJoK+vnEvdN=dNuOc0ecx6SnY(yS9{%+88TW}e4oMB#sXo*g`-L4gQ=$eO z*4KUYdb-xxU5D3gcm2PLlmsMp?~CxoE;+czzGND3i2AL6Znp}QQS!M~2RbLFQ28a4 zPh&B{7z%wIy<>sTO`1}((9*eeeS7?D8)TD9Br_4USRAlL+Ct^At5uSz?eCp5$B#6< zQyko~cPZ6}T-{jjFvnEtrG~mIdaYDJolFwDZ9)Z=7WsYZ?0$Qv5naCLNG;d+pL_!F*l z4ah{siu&DOo%(7#36Sjr&pI3?U-;Jb(^3^xxM->u|#lKu<7+uni{d{BL4AJ@gh=}W#yaao#X1c=oB=4j!VSzRSQPDlV z?7K4dz9#huy`xc(Fo<61P>}e-suNgur6Y*(y-eO1{k6&$Y+{i6wyg2I?chBSK_Vu; z@g0P@9s4XRP0}rIZOnFH4O4eF+>guI1qRx4HNtKUwkV(}e~k>U3h%`TDh-(`osIi+ zHk?mbs~+bQC|8Uyyr)=b8R5O#GCX_DHaj#J?iasAxtzcprY8-|iWI03U-5)W z0fTr6)p1^0w>k>5*+rGfBVy%}K~Udz)QC^fHL}S_#!%+x3$@uD`wB2+!|Gh=Nv1H@ zDQXS-@5CHzCOw@!glTd-t%ur`H^n3^2z2Lm8{o*;A3X%>_XxP>W$5G;RD}vj3M3qA zC*T)70U{nMzi@yz22xMJ&XxI=VMt^Zb1Fmum~4Dy8mK_iutS3Y5=%Fe)=mRIj~c1G zGYV*7JV%*o2x?5i(jFv9LR5iP1}E&eK7t|H9R-7TnBgt&$P)bX%P-jm5kS~teq?Jq zL4$$A#)s8Ws+cfu+%sIT)mX|TiKp;YU?^BEa8oxXG6I)?bv+DoA(Oy9s|$c>Sj{{M z0$rU=Da=T}P?M)|LUmGS5?(Y=*K%19Y{A6gUSsHhRhuKJ7O&wGI-fgi8!uZFmo-Xl zjugWyFzz!p)z4B}Y+S)D0J3EoE1lU$A6M*^RaGu5ld^VWf3ES2|U0`+y*N z@gNk|mAU@G6>S#uIdIWIIuhMe3rfDLIz$TGl5Oq-dLyW_5b#+|eXstS9|GeAuA&<| zM9ykaHM!!+1!&0BE@EDiVnB{HbTlZCq9ABf7=~?}i6RyO@0F~fthf*lhN2OIPjNOHu3d_z2 zrId3^^X8sJq!I~n0>%;N05@1JMyQ**aAx5ggL3+bkf@o6(kSH@y9sClMUgX<*jv%a zP3HLyk%fDfuKuvEA^~-Fbi|pOGMV&g=p>v>4#|YH_I)yCY6~G&ZHXk))(+iKg35j6 z)#XzV1od1j8hUIRO^mGqi=fd*0kRy9z&L{_na<>xZlOdCosbXjDA?ALYqhE1qZ9KT zP;#3OKOu6x(~ym;k!zrQ{RDewKf(4QD70!IrC#@mYHwX&;DaC-)s(6AXhp(cITldh zO2UL{gf$sZ24NOO&F~m{TE*45yD=shf4<7KbXnU8ADx>v+`2g0&}Cr{OC%^Wi_#F^ z4$6EqDD&)usCi47`FR5n7i%Au`g{}Gd_9zT)}hQtTgogiuqiX%XVVyrXv69T;l&}; zSUZg&!w0ExhZavS0H9&D9kh5yR=NFjIGR@YyL&-86XE8Kb7WR6enn~k%9p`ixprYv-rsIQtbvGvus$Dx*h7Z`#|xA;EtcGLuR3Beo~l{=7zw8Hj5nC4 za3aK6fTev9eOp1MKR1qDiHM+U+{302$dHOKdPZ?YxEz?aVR+{;v_d5y-GqOo_^O@9 zMUWh7tEjDU>z!AMGl%Bz5e_gdWx|?XkFy>+D)0Od?>to9VQQJwO9GI?5RN%8#icZ& z&hP}AkfBbBzCg*LK#JuUo|uo2sR=b$=Z2>b_&bn|8h?FnAW;3mf4jk{EB_Dc1KKZf zYD0ebO>lwOf-T`J&RF^3QNOnqWL70a0N*<~K=>tbg!l*h;WsOOZZKi8=i(#p-~Bnk z6k5*ybm9o+Vg3H!vP0hf=Wxi26w6$!3^^jV#f5_>LYA}N+PVc}r}zmim74Q1?ViSu z2wv`ji*3XWchGgiS)wU;7NRLrEkC!xn&8gvf-Bm4#%W!k?fqu*jM$237yMB~Q%Vvc zmOW@G4#CJRD)KXQubxhTRYKzZ-9SP*vgJ*W5k5uel<}=X?x1BW99JZwn9WK;ZjTCP z>%WIfR3d|vwCfRrDd3Y1W3|(Hi9722VtB%@g_J&zH9TH@p*qRs7(73Qbua+Ore~iI z)&W5W$88V>+wa1S;tSWPMeY>!&GdV)eht5?z#bAPzh(`CIESs@9pK41AXi(z(hFES za))Yjz@h7R#9SsTg~q@)Vz*4z&SG>$P$qCpfr-3Bj)f1C*r7$15GVQ|4q$cykyNPw zvjp$KcQnc(=yjh=zkhkG-T#k)CgOhBvMciTAA%vYJhh%o9Twc3&InJJywzRaSI6yr zQ+U`kt+VwP*KOYf-ZqCT2pq}k7_ra)9 z3T%@MjmA^We)(WRaHdRQ0W`@e#}w}vykOKkCS$cOdy5S5Ml4?OE6_Rmg-1?&g7+f9 zPAcFCT!b9)3)FhWRipkYf)Q<*&0kP7{^yibTsZurnCp=QohIfQatvLHMksg@36l?r z`!CeCPi|zJrq&fl(7YNfoJ(L~N5IGeyR2Z8r!{pDbOjC7UwMTVkkb%Vx0;x16?MT> z3>{j(+Z_Q}UFvtcBOudO09CE1^7IY8idr>(?Kbo28GBsV-?qyI>upsHUjmvcKb}Nk zfh#1lJtR`W*g7p!p)CQ_ubd2;j8#xmcQ`i`h>B#Lpsd4y_QM$&LvqG?I19?D0m&nC zaah2-*#)z8swJ2=5}5x2K`iPbV7!8p>mp3Hke5$%5lVlixOoqwaD?PIgIV zA}J=EgL-l4$luJmbaCZJ_eI~m3+JM%4eb?C9Zp6NUJ(O(JK!G&b7Jnauj_I1n!6@t zX6Lm?u}BH}ec$U(!(6a~IBiMduX3|1d5oi2F*`bD6`BO;jm+#?1c8a#=gK1Y7nEo1 zA6{N@tXBP(pTW7P52@5Kwj4sqGU1+60CXUw@{hiE)MibfR|r7fW+pqk*WCWl6>C87 z12kQhWLO|+le@clni1Wjl{yg5!H8*pe?flO$6uUjg_aD0s6a7P$`U&2?P!q2QT>(j z2M0Yw#g@+)^W|%>*ot04GDH+fO-l)F8aDG08E`Re7}hdJ;e^pa5M=k?*Eou}UKl=v zPRkuCM-6KmQA5qqH@sFa%rbRVFR@`ev`)!PAucZ}0FUBI?&d-)$JwgHw#*7k+r>Ca zd(;2`)3zXD%@>f0JunB?02GDIicJg!kJ#U&-FSuvobffmKj7Rjn=U+t5IYI6n25AV zs)2`2u7l(B!9zBx>xYNKde_1uJUXAiNC&Gke@!E`Eb|vN((o!s=4BbB-SoPylkPbU ze(U-odDhjmaoshY25XxveR8mYnQXamu!a@d6t{_(uJDJu3FqmSpRi)&-tT_4C?m@e zWI)<;u6O?ULd1DJ-6ngDB!anWP#JBdWsO`V4oqOZ_gSfF`sYJuIMBvee8rF}D2p&yVMq&}^Fiq4>7LD@*ZOL5SejBuh1gnC0~T#8q`A$F1lI`bX~?mUpOaA zjS&B#OBD}K#)UWnJv=bVmh=`&Rh{&ajh{($|s-Drvi5Ic18WCww_4=Zz1QA`S5HZQnEGc~WUDzE` zgDXOdRJBA61S0xU#X}_>;vMN$0}=g;;p*WokN^=CM*|{)k48jb$J;VL9~@)l1d(|Ome5McTRkWY1hv7q~iR!Gj2i&eB~8F^XIFhB2)q{6kzWlG%7ls%Lj4I^(8c+IsEYzfjzeX#Emf-GH6oKTfO1iW$~c4v zHzE*&`oG;uqI$06S|%S%{p1Y0fSqFc=nh$5@TPimvii~Hp9hN>3sVMZu0}5*p)DR1 zD+YAdj_dB*rw1XPtbFo2d;-AG@k6l9s1d=Ilh78l#NLrGIUzz!4{xS9C>m%aB7v+F4DJkR~nKX0r1N-cwIY2e&zC2q$u7Kz8!NS=vK zfLNXwhneuq@;qUm$1v0rkeu>b`NXkv#bV^7e;W=0chp=U5_ zJ+=eN*h56@H3EAk+E|!o?F0oI*w6Q^IzR5c=iYNAcV8gB*5f|s)~QqV)?06V>sxQt zsY=2YO26iJ_*5R2qb4C4!u>u&f-=SFQaX+z=w3J;c9czL7p!X0RC66NJG-WM&XZzM zP)rpn{+RZzFs(J#QLvVG@#vTiq07=S8(L~dD4Zt|i)n}qXWi>&_O-^tqT0Std_2oj z+Z0k8Wbw>uKy)o72YY^;H>N9<*5fpk}v-&0H!wYKGHJVto%xmpU0e z7Pu|3;&=2a^I*ELTbnLh-GvYH^y?~j+2by6PBS5|jqX?IF5BFNFYG19>)qu|?($YH zCj$-ZJOJWxLw%Sq<;4Fc?btLmAN@=scKd!=40cR+V)7_eyI|EA7K|iY)3WlC@sQu1 zRx3Z;epyT#X?j^KL1QLqkbwm{oJw^#*j`7!)ebROr&fAt~)bBFP@c1f_ zi_31+v)x^*pL>`jkG>fEGX4y=LV{WyC*WOdKgpif7#o`tTwDQJurS@(9%0Vq38*nfP_toai8ULUD|XK-PXMWj0$DizP=< zIYv%ejHBYvl;Hlp5&{!i8v{@tmBXr`$#=H2^f}uxK>lJTpR~s&4jAo}3@>4CWX&vd zQ8S$b?`X9w@6ei3t>mRFZuyemBe|+Qk|&vX(;mrqO(eIIMxwV1)FzH;mFXJ_Z({No zoLbKpnW74L|4fm7OXW!pYbrBC{#0ueuB8lk( zR7cK$0D40U!#lOHo}YciY!)e4-^ zlcq(x7EtmrYjNYCA4}u0L4&Q5mQ6?-yeGSMGmeN?PeVZ^K{L5rZq-Mgd!rMtwwX;s zS^7r!zAf&wy>7J(SOu0Nl5~VR6ZMloC_fw65Z7vRo!Q7QYZ4V(uajtVJ+hA^B7!SK z9A`-tv@u-&vpD1G%ry~_%vk~y)NE7SFz#~Ds_hVie$|#)tY?U>x&64;l-_Cisuk|6 z<*%by#FirU06wA17!W1zjM{jT5F4*%69N%@LZLLLggSR%wSeTSNJlT_(3pfvv9X|YxRf?~7Fr_l9NJ>ZtDly%ZJjZRIgG(ef-%RT9wD7I;aHJ1 zLHNq=mV(KMSJX9cz8deQW%y)usw)%+$+pU|Y@@a>@`P5=xyr6%_Ueo=UV33=Cjcf3 zDlQ7t;Sv_Zwrcs8VMiXewQM-H;F?U>vk1F$psh*@S}Mm9Y{PN0{Y|PEhEqavLAa1! zRg-<)KpNZENW>DdI<(ifCa-UGuPes1b>f1pX_GAmboJ@5%WGpGYFHAx8#Gsw0Eh%$ zsURJ=P}yw+gT~~#gR5vZ8uJ)@@yx};d1G3QE+VnX#<)O<0+ioFrA?PhL0PR>%?K{R zw=kyiYpt{6%?RpcD;(*Hjgv5wC-Q-Z3q(-Y!5syRSeUQvMM%NwWOvhWM<#-vCLGzs z;?(jp!ctTxEYU5dPUlA4i!^6zg3=4L3JNT+=t_c84Bi3_(Lw4nNFP zZ5=b#uUF`@=A+-xCX>4@5?_M|u?&<(du(7mIn!;+LqsuvvZ1^kn!?~yfX1fAAen}{ z?kg@M>O@(8H@d zKWS(Tx^`R+Zbb5oL6>`$aMCFPy0kck(WX5F04OBxxXjNZnVDa?-TX?5rUYbuxHyEf zn4jYL`lM&G`lQIM^+`RIWO#Mer&4LUJk1kB;ea4B8kPr;x*Nq>1}+{S9jHGf33-Lm zng#1fEHDLFcVjEIZhJ*(gQ)3(SVs5LFn+@U_6>HaywhE-cbB)g%bVO~kGt${rLN~0 zbp=It23KKnFepyV(B*O$ea>A%cj(fd$(PAa`_q8>H0C z!5JGuqU=S~%j1JHemy=oqoyM+Cg{i*&}rM+{DU);ARQx}VNFRh%83uoAYp3MADrP+ z1rC+!2GTXxzEX7@asv%RWokP(<2-Ri#|mG`6;?>s5uFO=8?WH{1lJj^Y+BEkJ!4{v z=fM)SFhAh`iOOz_5^xjPXHL}Ekg~<}L=6+)HiJcOwJ#b$ClM4H^*T`l7n9br$f5;e z0=8erm-o_6)cAGQppxz@l`aik4QAESrG6&>)o~`kDH)roU1#gcfnBjDMtOF}2n~ot z!@Kt~=0XqwLgaKIpg`dhnWL;y+D#&I@a#(AO@B{)*FYocFSulK=eJ}PrbtPeMOvcMhE zXe5Mi^9_FLMe-Cn*7%ZaJ;`fYq)zcsfrjAD&~0t4EP*EyK`Tb#nh3^41j1}fH8K^u zed0rmkP$DNJVhHR+Eloa)iM)_r)VOHPSSD>H8(Pe++@`WA7N+*&p?-OBaMxmP#c9} zeGNAh0VV75E66$DT(5=i>tVeU_)8?O=0#n#givX!g#q|p^h{%%2xn9+Q@RBDRMBlc zK8^MXsq%mdPQW3Ss3mP^Pg%%}dr>U^c&>th?kT5DGI2a!oGpAVz#+SlC zKeBK*q_X~otNkCoV`R?rTzxb=&vSJkjs6Zzx?^P2OP|FtGOK~-?id*jk!2C10(OMb zxG{TXRuY^!MuxuMEK9A39UDt*P2-q7P7yJC*c)ybH6iXWB3cZ2ycrwf@}_2u&ckXJ z#}81YuA9%@;1hhUsIHSPJ4%m4f;2WZ0L%;qvPUAx>;Ny;O3A$=OT{XH66MOBZxZxW zVtgfh*8Lobv_WgHHpE*yP`_CGtUD0BCu;lGBWnix~FmHPs z*A^f!Mv!Y3fUrX>f#qb)0iF(ZHgoQ>Z8R}1#nv(eF50F|R>q$xnVQ*aqeSl_+Y0S` z2U#kOkNmAINe)_s*{Atuna)>II78GFfG3+3Q=72`5=@I>@r)2HoaSaLCM0ES@@j}- zIdwDeIVm&vEcJwii40W4I1yNKf)bqIRsVW*DscO5SFY*&DiT4r+P*GsLl>K!r^QPX zJOTx_$#K#3J9l|&Z6a@*bvr5^!k1bElrGXN%nxE`WmU9gWNtT7dq7_;IlZD0Q&-() zLWKOk+%&(Hpj_EGzZDRyqt?K%Eq2Ze;bJ3hOB*4ZNkDZdnyUl9g^jY|JRS2@yNYp; zQ`M<(S@$yKym~VgK>YeV;6EQ7EU7<|o)JcbKZZ0qCl32MF_Cm`T{fpxTE3g|*-?(f zpDj-qAJa&9Oadv%HSPlCamIdGT<3ZZylvFHERAxz&JaMP?p?3P_diO3wJKUhU4D01 zWz<=w=h3&wDnbTIwNI;mvojpKFPYRbu5Ouv<a$Sw? zrX@qs)Sr&flFP0o1NJmJ)wZ3M+bC~hNuvtLxxJfH-?#9(Zd+Ori_cgWr)F*&Pg`CT3VXM{(D54+ z%Jt;UG5Hmw3fo@@LrzEzpD3dsU<9o~a&Yoe4yjbH^DP0TaU_Q|cSdr!W=M|Ni(tlD zamgW$(H?#2r72fj^ERjIh|h!(A99r6$FdzY;$zfi0%dX_j#iZ<^atikT@cf38jE&3 zr=p8mu+beqYPS_78M>3cWp`FVc4u_Q?u_o(ozWe;GrD7UMtAJa=uTO52iZk;$lK8! zw&QW2?DYoEkqwdsPCOg*2n~+EQIm|qW;UR$zjjmAP&RkpSz&Y; zwR<$Pl!ei*#ymzF@$T~aoLk?=K4R9|ef1~P5cDDl%T6b89)L7K-SPPg6@TcEwe4J< z4W3yeYT5^Hs(7>LHakSoVI`kz%MKH=OL82uJt5=A4B7TJ=dzH^ zO$zd4ZMBTGbs^hyTSm6M*?A*uwLVsbiEP(WvK_xgo*;#2u-$pGO_(R!+!WI|Ac2LM^>KEQ8gENAYQH_9o-9P0 z@w<-0A2bh(a$_b}Vd@uwld_GO%1|OOjP6pyPrh~ef~WtartKI3LmdJARau`Y>A-I+*+{} zy%j;Aj9O0THv0mt?11#ixDL~|>~572Bsm0+>QWtQO93wQ8lsITjxm%F#C*2a*_e~8 zx>qeUtw!d$;28R9k7|6hT$*53NyL*lAg{e=-2exD=ny^iuqb3iwxlyk%Eo1{+KZa6 z;&apbKWvQ9L-I+$UK}X!+r9K!Vni%GcKb?rCpyw`N3}}o3HJe-1qh_ajRie9We+@Q z%-hXiq<)Du>u?)R=S5(S5hGLuCc8w_Alxp|mHH*oRf1w$nW23UKtcLnUv{I^QlfR& z7APCB?i!&*Ug-XP>+s>UNcGr`7D&xhc~JXoiBH~4p{<)Q;%{)ml~}xQ`q5r+&0&Wg+)})+`?)*xKJpx1r2*kq!7jp@fqvPeh^>@Y%+`N-+^@#+rPdAn5 z60eDZ%5P@%tRb^2y7~o31?IuUoXxe`U)r&q7=aoLE^%`?jr%q(YU{k{B}y)H;Q{TJ z^-LpJh$c#SWgIWMUlR$__=$3`199xGx&u|}3;_&EM*|>OygEPB$^g=cznkOuhO(v{ z0A`}&rciV;i5&-OU#us0CE-S&BKl(KtGU)uf70X4Fo0{9kNY#Ou?}sG)Hj&z62Djx`$FxNp z)$9t5HRP*E2MMry(xt(LPJV67r{gKGo?JC))zcQqb|FO^_51dyQ0znLB=jqzNMTfI zS=XXe-IoO8wpZbVd{I-7f{6XPbg#Ko$<3PSa7x>1*>Xa(AO(<G9m#Qo;oh+cIfZCI>B1V!sb`Pty&s6P9+eoV%a(%kMLm(I+E5j^) zYFTTA_6T}$sR+x|r$`6joJBX%i#6Ah}f>kZbZ@ zfVhHuC+aPloWS`FXtIYAtH^xCyR>=J#IQ7&j`H+XNi$lgcuYsuY^FC*V4J zsGsLu=MHN7E6G+hxm%M-`&3r7{@2jcvJ?wtss9h7OOWjPU-`}j&KWJj@N6L^#spkk z464em80`8-&fIwI;))(E(1C^Her+`a6}ux)^u44!D1;WgJ6?_FshKt`BWloP zBr>IvmSyH+X%*RBOJ)#QpDl*M3`?AsPVO=ePX2Mpup7(J4)?YUv0Rs-tSreeHBx6C zWC(csY|;#wDkl>yt)hkHH|EjW`>IK;vI(y#UQ6m_BB>YBu`*B``A4kosTTm2#qrXWw}RLJVl{z^aYjNe zsY(4?lABopB9U&I8HBz^9XzvDX{Jq% z8jRIcRsZAw0k@-1I~G6Dk~e3VimwfnWrpKb5$8f}SbhRCmB1Mik<$_|!s;jiz7;th zdZ0?RcK5hj2)Pf6P|ZJ*mMX2tfZ~5-%lgWFrC*vJ9T^EY1jg2iGT71x$F&zcq`~q<`qaP*Aga-s1Qu{c$Wpp?gW%#5ZYT^ ziwN1A5b)O5lkia+xBMiDW)5Kfu62h}#j{AWa^B1~*-whkK`FW0F@RfsJ69HUlnYgHH(jBET} z(HE6?H#&MiEG89 z2&d(8gS)7tY7>=ky&6CT`NOz_t{K7WGy)bW^2WwU$1F4a!;LhmhS99xR{~Ns=vTXz z&D#TPTRZ1eEmA%Osnq^c*(iwoIMK)(sFG-SoFw#G{E?X`a0R1z!kRDaz4{e`A&CMtz9yEAe2W#6XnGmU&*h)=hlqv&y694RWuE$x` zEhQuFyIiDqxXWAJ<<0JLt-HM5U8s&|<@ZTpj+@7H<1?6Y&zXC+Rp`o7Mnd9Sxq$AI zTwrO$(*p5nkdc4dEf@IEroVIw27&L?o%Pw*tAR~KCxJWXy}-lAf#P&DCI6Ix#HzNx0Tzt}7-H>z=QXM8!`1=sb(l{cxl+|8BW;)`oP-lUK>`{KqSmNJ+r z@0mRhp@D_P{l%oXZ^{<8Etuju|Ai~A8{O}rxQ@&2cE#Nd3!$m%Ph47pbaspC_UBp( zySb&XtW3MOvRj4ajt?A3mb=EI_enWvcA5rvSLs2a**8aY+2iaDXZ%Z zU0Gd^zJs#T3DfgzcV*p9=dH5xCoU^NHDA_UEoHr^rL35f&J^Zd?l^wOm(_l3SIFhQ ztZ@iapV_ir-d9=u$&(~!a~0q-$t6=5ad4*hG56|trX2%aTAWWL_T(&8PQo+`2QznFD!BMKa zWTw59-oI36+Lt8N9cHV$Ex26;j^Mevhn}E zU{7d8h-LnPS%J+9=}$}fnG3@NG(e!a*L>lHlUH{Z-8vRSYBcONt5vCaRfz)Ra(4TW zY`Hb0cU7;BybFdSy)U*AXc>RE*mN^APsOg0yOgA!$16x*(8NKYvtsFMe+!zfKUX!v zK&xuYFQm&PnkNpLNChhC+WFK*UHhc(+9%buPpWILy-?DwZ@jdFnKv$1sSzh~aDy!vVch&1;hTR*VM?8*7pX zOhdCRPkf!c<$O0x!GnU`YAcut?`UTtP%?iM7-LbSvxSKE(c!kw?zYv>`(-&Oj z8}^dL2Xp|O#59U)%{2ylxkH(d9+AC5v>BM7VT@gaVbZMP&;P2`h;-<9E_S84_AM?M7Ria}zQsLzle_FOp6ZFPE|{_|aBp4a zczn|*Y2u>Hrm9%5R?jbXlN`W?O);r9DMfc`xonC$JE(rtwLKDGwN7|9(zq#7wa@Zs-9(J zHQ~Eh1WmhGey}z!+r_#NdR33Hwb8VT?V<_aRVan5Cfb6_yS?W~HD#MjsN2(B z+N)Y{hE?G9Q(sDb*P5d?PEglGKcqCOzDrG9gT!`SwS0i~gICkOG!D^=#+vnvX68l+ zLVzyi^L-o9t>26L(!AJCI`xuj{n7@Xg85z&<7i6>gN88WE=HzD{L-I~ly|xCDXIn~bJ@H(5iD!}IbcJ621S?!@bpoRf1v!zHX3Zu{ca8IT zqPoaR8`jj5uv^>C;6uy03m`!;Npy zLQVH;Je<`p?UKf`sqlRL(t-_s!MyaVZvLjx=%krS^vL*p6htM8a-4wrQ&Wu@yil%s zW}=6VR_gzKs%anUiYvOxvMo!ftZ>?O5vYp?R&QryI;NKB&w2NmF7IM7o$pEj%zDnR z%kd^fwerBrr`mY@W24P!Z_%ps$9Ou8E!V$3)tK&9@cnae zvz3k=brWYMK?Z$O?L|>zsj@ABzL##CN28$5CwB(Vs`MBL&idMArC?X-v<~EY6pQ+}oC7QjUhszev_s(0=$PuNz4VcjgQZWszLQ^T7ShSobUl;IrghtI%c z{G22yMtBUVwGvE8HQ5Zn;irxL*se)$xWEKF174eLfzQbVKKWYRpp!9jXp;yPE%BvX zn$xjO5KKf5oLxqYuXgro<8IGqz&-Oe;a}6@w5+T`J)(}gES#(<=5YqHf_xlF>~O`jD31D z*tzgY&U{eMz&t!Ff%rsY(k$}Kjj@618{|!DWxTii9eo2E+bQ#RHxmnd( zuQBLRmfO$9&GNy~xLvAO#b|u5Y8xo1SH(l@`YM{qQ5!`rk0#C1x_f&}e^0z4l7NFQ zfO6ZDMW7!ejHU=z-gaf>@OK#5fI<8~n48$3bz>~dZDX-82b7T8L_>YNZLCq*_Z`~~ ziPYeGq1BJR zxrtDTb_qd|y4k>u-f64@V|KF!NftZiEp|*6J0^=2jBBF~`=WqtPSkf#syp4oW%pi( z@)m1{i@e=k=G-N87ws^)|F;>336#z(+JH>x)S$DM1&67RlOeU4hc+Z~K2CG)ikG(e zI9ZUdHA8yh2Ohhco0c0Brc|KFdw4lgRotA2-owjX>fyB?+Z7Ufc;gUd$h+)PX#ktBNTPd-<-@ z*b9NPqtHYJq070~Vz?Q&p1TGPdg#msX!YS7OS9boEfX2Ex26;8!{?j(HWmDe6n=Lx6+1I|3*QnGA+A=DQL$c+rvaZ0DTOCxFng@f`!D1;fV>Eu57rWkL z2+DR!q!2r5SyaD=+GSRO!bSZEAhDUK2tFKsvGL8o@hH)$CKcyz!N2 zXXXu{(zpV_`SiS3LU&{mqBH3u>-#fr0M~KW9qbs3>XmT^aW07eTer|Z`=J5dd6A$o zSLrH(Co5f_Ywsh8#3(X4@r59ld@P=%KQnfmB_GGXOlXFDES}=`K*`53Nl-vOmcKke z@^Qoo)SG-9jwR|!KK|H}X(b!MM|2lOI$Blo@$74JxyPZSbY~shW93f>&2W!H z5Ab`S+~braDBvC^|73vN}173BVw@$1|C%f$KQywdNl8K9K5&?xILXtI9ndUCN(zId*{l ztb=^)yN%Ec`8c-3?}3t!MM+RVJ{E2pAo)0Rs|nPbe5~B+CF)8(p0#9J$;T zH-lR6ao=s8dK}Qr(C;zydkp;^@wx^hpu;(rbDeYPwcH+nOsEGKS=6mUJ?_Z70aV8Q z{~)Nx-I=U`>p1JRrXJ6|nCgh`qDV)pNIh7E)3W?@E(oFrPyEhv+Bmy~i!A;*-CGA2 zIsPD_87{K;6@CwtiyV^#1zcqL!2xoSBTk^+T;y;pQCBYV$CgYh7dfQ2Z2gDb#9ZVa z`=#|C4|*q{v-1SP#F_~L2!|WGg;Gv#aXX47rFf_sgCF_igdJkT!hJ2 z_Z3X^7vC$@*_6D6e;oREbZH&@W93dlGyLPwXZSr({&7kY6!4FecMgz$oNxm5<{!sn ziMsNSFIqCK{NtG3vNa%f6Z4Np?3dPn-0Atp19~}+f2e-k8W3U_|3DJI21GZ5;vdI; z*Yl5ibTi~1L;f-3A4C4J=KKSIO!x;FS=6^`4M^qc7*ab?}eFPY{~nAE&;-?}74TTKUJK-m;LzZOI{gW?~D_j~@aUpGVkG2|aZ{xReqYtBCa$b^4@kwty0)`Dc-04ie=FbMu} zcP49kusG|r<{!^}Bh?YzMUjryf`9x`4*yvEFLY@g{Nwl$LNokh@gaT>lz$wP1O@zK z`N#nI#}Ow`Z~k#OmZ&TL_+v|^m46)4TekkgZesp%kNwj6k0YLc+@+WE_=oDpt^Xi~ zTmPXOZ9b-V2F5?``jF=zi@F)|k0JjU@{b|^SabdXKqmYHyesNkwf-aX2B002fI;w& zhcj8zgT+~|HUGH%p;Sk77ezW+3;yx@IsD_$$LZ2K_{YkALNom1(5Lu4Q2udB5)|-{ zlluqAKTbG-dh?Itu|!?@#}_S`R{n8JZ`t|}yNUV7Blb({KlXe6@qk{=;~%OYxBi0| zZvBUD#6R@T!1%|34}1Rc;*fu&yE_g)!ySHx>vy3WehYK1-@^1-e+ob*`~$oz>RYw` zBl8BJ9g~1T@Q-IQS<{2XS+6z!xc5`3j_59mbhH-yWASU{j`gR$D$-C;2#U$;;^VeeT#c$#RTfjKUP+}L|ysEvzAON|2U<$Z2gDb#Qfv5{nGl6 zm9pEp{%O6O$3Ij*Zv6*pbL&5dYWzd*42*y5zr*v7GanuLKZe_Yv{A6(HXy@oK+bs^ zkY4-)fK2!YcvsZ7YW+v%4M0040fXQlH-9S?mL4q5dae1#qwh=k2i--Hj@E*I+?c~Z zPJNj!t;7Fu_|FK<@Q+hZ@_V5Ek3*86fPXCg*#P;+0Vhyz{;@BXs4M@t)skuDAB%d+ z)_>Sd%s+0iUt0h1XP$rDq?hyfhw8_z{~(52|DhW@{6#l|TL1ClLC-%<>Sj3qGMs-I z&c6)jU)Fs71%OQW2N+q@w`%=I<_$nQCIN%sA9rW6rU#3&UTgmG+>@z}=q`$Mv=;p1 zdnY^nAB*?WrFHO+<9|eGhJP&H&+mcqk7JUcfPXCi(E$0!5hqY@{&6^#s4M^YV@sx$ ze;m?Vw*JFzV*YWD{nGl6Kl1$JF1?(`KU6<%{Rc7J`VZaM`VZXpyOzOY7htEAJ;X!#@svgx>?@AEzWi0slDp{sHoj6HcJs{Ns2mQCI%)MN6iY ze;m_Ww*JFzV*c@n{nGl6_j~^FfL_kyAF3a>{(~59{fBOB{fBM_#Xk=Jp64I?bu;82 zL;f-3A4C4J=KKSIO!x;FS=6^`{YT~vKszP@gWw;}WU{6Qi?d#9{&DX|QXSD<6zOO! z_{V?D;UCAIDdq5weP1Uu!#|Ea$M1pik3~sPz&{qgUK-%~kFS|Pz4^z=*Sths`Ny-C zOe_C5rMGPThuy^d-{A11e2LPGy4=}Q*Z`Jyb%o~7qOacbMKkm+CO%E1lz1IBWxi6(U zqPr;4(OU42Km5&{^&fZ9rFHO+;~yn7!#@`9;rBrK$1zDzz(1BhIzaw$#0k`!e;ke_ z>dHU<*pg}GABXgot^cr_n19@3zqJ12qn>}osZO{H5ihQUSCR^MbLF`!%HvaI zrNoa=f40{DYD(F~A$T<|x8IZMi0-0DN2|v_qEmMCEqFzLzVfwTJ_H9Ndc0_9cE0}9RC8LGHyutJKzdYP%_#4paZZ!O*w-zLhM%>JY<+<|FQT<&W6$)D>i0U8LZy)9E zl!O?K4$aOtXAxgx?b*mKJiWNGG<#*`lZ7i1Nn34e{=?x^! zq)D^<9w*GQ9wNp~WBR)|mI$-&J0r?m&z&?UoHPdr&lQIk*pl7L!w;o*a7_B73wdQM z%x5i?R%&vDm&8o&(={e0NA&|<@;NW)eR{E-mW+iPmKzsHN7PSa9XBV5W|ZW(ZZ;93 z7aQv@45Hoia2Hm8E*$rL&A9rS@vT8P!RO88E$&hcCqn4OCNA|W${W>dT~U6sdv>k6 zyxv`|a+k~9Wt+Qf<%RuABv9w(%qPr0Vo6N#n_c6_xYXwxo23-jv-H0 z9ZE=h?D25DCoSBiq-9+6fhU3fIMOl^uA6VJ7imFm9(zq((!3zn1gUz`lGTKf7AtB@ zTI@%tqQ;~p4pFYAiS?$5t>FdX`a(^3(n4}6X+aZh!R;zYcgz?MH<$`GVFw#b1$Ac! z^?5xB^ruAy+noyPu?jXf>&t>Rr&uaRY;Z%y80v{JY|0u#T`Jg^H3mYkRlU2X=~S>W ztoNaU&51G8v&PUC+^&L633VM0H<=2?QNbotL0~FSaG*ae<-f|x|Fi4hqL&6Wkyhb4 zwSRSI(P`$s9e{=7QQ~>e zZi7F*&y%lb>H0J7qbV9VEbnPTGw!29A_&vrR7}xkplAkzEz}G$)xpe`W`!?C6-8P) zc$x7@$0QvuQ_kLPG({oAtEMuq+$D6EO+2F|q*5B+9=d=FC zsMmxsA*xr8U6)gfw#+xh?6zBPJ0a?I{<7!XwQa#guFIKp7b1G<#a&9h?8kP6#MCPe zQHH#`r#ZRV9@8WyQ^GNEO{cQxNIdl-xs-Z!28Xqzu{G+H-g)aq4WPT8b8%;-H%HNg z*pGTA{qdy_>+{VqaV`Y*oC_6PlB$4IJ?F}*z&MwcG3H$MBUBk<&J~9!S5v{5sbDKA z7%NnPCs!nwaxPTR7Tm6ajTr-QV>OX}H&!#wC8jQ{2=u2#1#m8@z;P~Au(>(8?8kwq zz;mvR87nZ(Wo3*xm;JCmG3SayELT~9Q^Ce?vJVw_a)k;~&V>rvg4{80Ig9?4e-!;lHUxsXR8qFZydvc;Use(-9_x#EzJ z7vplnvwXSL$96G(q!%Y3skjrh9yu@eY)r6FOWSJ{D{UV1G=iE55v*Au)T~FSS%K25 z5UMfNt=p$B{L(v|Oz@Nk-ciuA6aDct`f-cirJIES^vLwA8QC*wwkMNp^SnbnGCfO1 zc5lk+4i%BW*fG>C_vzmBs+KaQj_NS|rls$xbj8h4t%Cbgpkj8YNr4^8fGLSDsbG+! zsZjlSOpgAhI<>)gR*nl&iS_SiRO~JV>epk~wMaR>zt%#vw6b=_x4wn(9r#`El$&-= zImh@;$_bZYdW}e3H9;SFzh({G&X)0=P|gL6@AzUeQP_p@wR;55f$|-5g7l_* z%dsR~Ip1e3nO4qsL~ofJ&TeAXchr8#5x3|k2=CL&DetR=m9UC(tTv!}PC{e=NeNc$ z`rlT2VkSu^ph^5<)OK(mV@eulytc@BXU3V2mJ8Igdf1s$ zEo%M!E58Ta^sC6OaFe5yR=DZF(DjC)Im<{)%*=v~-fKmA6sq4ChyQWY{d3{~tR3?=CVLy2Di5;Wtx zGcS-+3}tJNq4#GprlfJkYm1>bX4*GeE>O?vVQ5aZSnJQ|pttgSz)io3>zs7<%F>YJu$-x^$e-42GW27h?m# z&;!c307Lg39{`3fIzf74=t3+>R}B50J~RCMu&8Zf({{EHU18(|NWLLP!QA#V^bYSR=VQ9|h+{&Z>Z?=0Bs^71#yA~?vJL=X# z^~BKW77RV|UA4e=3|)Ah&UR*ypUyMtEOLgnm*)mo^Y7`m z^9AZzJq)GBldjEIi&}sG%I^U;{VK96+~g>w6>d5(be;2uW_Bv}+bWxwnc&`gC-*2+ zzq=rJEmY2a#;t|wiJ?<17<%RbwZL{Bx~xryGZ=d25q=K@Lysuu0t`KT{{S%bkQ1ag zhAzdDbj8q*TQaQ}dO&ZPKh$nw3_WPS_SCQWOhdSYm;1w&7qQVVRy(50^u zn!(T$Izeq97u=tz5n!Z3zF_f)6hTf6Mn3BdBuPuf? zl{w!EEf=U~^)NK2TGaacSAGw;=~t0m;U-5Zt#H$Up*80Z&72tOk2h5w{hwjlqfq^x zM%uMdIp>PD7OE$PPPSm^ky|+CvjamHZX`5=p+|HI_CPT7jE)^Gz|fWVC5Mo&-B|vV z6QnnWo{S~wilI+hGOaxHgx)fLsNKXE`h@+GKlFY6@bSm=awiY9+Q1*`Bt!;>p^9CE zp(LGPDDewG0*ikp^8z`=P`36M`a&jSN*ZUpwix>POtVMJ1?pKn49%$)wf_E<-ve&? zRb*GV$x%ux+;m{*r1OU!Np0<}BS{V3p9wyk2Ip8*k3v11Nn|-qq{BM87V7qgQsEXK za>7}C#*1EiV(3H*h8{Sq7TC^1PkxHf42B*!!ta4#=n3UqfT71fH2@4f<^<`Dq06x( zT`}~tmP{*#9?@Io54D>ZLyy`o`9nYDG4wvY+=-!98~8(=gvj79RI!UNl%x|3C4K=& z(2O6>yg*Jdl;v1_@8zCnzdkgRF(r*N?r0^wv+Y8vsI{!GS{G|srAmGsW`EHU)POw&Zm1?pKn49%$)YyBA=^j3Zk zxan7sUEwB2DFqnnz6by2_fuPY`uk}OW`bAJ;2ewUQK*|2s)-#hEL6K%N7q6<`oT1T zV;^)0^pBxqEf{*@+iHRB7`pT7f_v`>LbkPaY8$%ajNxEX_ z_r9U>v|{L)Z+HxS-fm(HebIi&ANmcCp*+vSP^%66p-w_%a2TrCMHoubiR}@;03^WB zo1aZzAg9<^b1c3$n4L9--jT_elExXYErvdoY2RqMKs~F6p*hu}*5AMKd%#VG)=Tzpq|yk(41;9q{!%?xAGOc3*7Xp z$gXgcqm%*+9d-WD2UA%pW3@6QAuPJ?qSsz;$7&Lpy&CemRYT?=*lS5n~?zv6`J zpNEdLVCaF*sRg$4(377bG=rfB9_05xF!Y3SF2K;^pBVs#9&>{9#?a+hlCBu~SxcrB zLyzb!^M~3^jG;&Em;9lh@fdoaUhc$Ds}202PC{gG7^>Js7)sI!h7!L3BxslqXI>zu z7|L=izBicVH1OUpJf6vzlExW#w36PboF#_dnQ5A6xj;RuhoL#uqSoKP@_WEdzl!V% zH#tfvz|axr4}B)JwVR$vYVeLs@V+!S$D(=^>h4S;OKBn<*3q?4&%Kxmcj`qaT>lta zZNbnpUsnrk$I#`k5SqczGk?wRfnewn5ZXFu_RqF^y8LHD~2A> zTjme7n;1h6+AsM-zv3};zg|u;w9<(8np1t)UUR6z?KOuaZm&7LGqAnp7H{=?&7J<8 z;a+pe-bKT`<^of}aIZOS2R+eN0=;?cBdzL)##tglnpD0kz>hZvwYB2_r(LrzJ_n=JuDzYnO%27%I z53Cvw{N}Ccrq55`YMVYQj~6n*D`{|!MfE7u&9|j#FWi=<{kFuqSKbzzOot69-A9+w z1dc7a1p4QJmFR?>9^rNyKJjnZf474NE`7I^2cEc@CrED| zxDZRyl?Q(BMU|(O2cCJ+^T6lrCgy=J+Aq!Nyy$r#&+~bp>ce;-s&G6INgNNsSHPhZvwY7trKU->;KQ@@H-61kKqM=1q7kmFKF z>`Q-=QmqI6B;jh0XM&Gsg3oSVI+MuBG?5PL=vt_IA4r8e^uXEjz;X)@Jo0bzc;Lb( z3C;KekNnA?c;J~Oaw_0~D@!8-n3r~f^yYylV@bO5z$Y!4RvvglZ`r)G-NZcb3Hzma z>7@}rFRhnTe_*@^vDF6i(oRBTaC0h;aZ^9jd(RD$PB4`C1t38~cqa1#ImJ-6_89s? zCSyt(XWY?BdP8>yDD;m0`ApM9%LVFLJq*pM7PbEVm9N-2-IRj+Rb*GV$x%uHhH}6Z z8GriAsjc1h<)jAh&jcS%gL5pZN1-0hB(j_)(qSE43w8UcRJg@cPPqQZ(xny*J@7@f z!1g(nlMfJ@!O#O==J!Cx(kGO20frubU;r3;%n8yPLziPox?<>OEtysfJ)*a4UfOPA z3_WVUG%x*t$I$!qawmpbZ7?tGBt!;>p^9CEp(LGPDDewGf`;&L<^^(!p)AMZd!tiM z1MmI9R4xzI=GQmq}aE?XwDAfI#L=LBkbXZ5%LjBe)={adH-t5jv>mNgd77RV} zEw#XQ3|&4&Xa+;i{2jjsf}uy0a{-1PJ~aRgJ>&%GjiF1iBwaD|Uhc$Ds|~)>aS|ef!%)R8!cdYRCMu&8Ze^{TUtfR(>zI$t2QCkzL^?M=8BA zv=&w)4pnUYxLx-)E($Br`SYBlTp@UGdbHCrkRVOo_;JQ9KV$mB70#2VK=3I223uzK^ zfP=dm7jv_4)qLY0aXtQL1pEXy&+FzAZkCk%Hg3)!;7+c`cFs30<$9XyYq%cRHQ%_5 z>%uGM8@sq3zi7U(o$K>lU(0og_kNP=ruoKITu!Z@Z~PS3TQp$dr4B?vp zI4aLK{z>>_(bC92ZTxf;G$t#%b%^44b6S^bb7pUJy!=besc`bzDrZtMF3I>iPWl5f zIcZUcl%3}qNObtqqw~!`CyNFCWU)Xeiv?Q)Z4B)WFP|pay_`2b$@N`eM^xGyPF}OQ z{+`B#VTpsq5FlC_->duO@#c&UMLqcT<`iMXo(>UfY5bS;($qDZn-i+N4dvaoQk~P! zD2R@HqwG2--5ocqqmkTk!zbV7M%X9ykb~7Y-Z(x)-_iw?uofPaZk(@ z+tyraTXRLW1@cY-7+Lh4a_D>hb4aW2(_3a)Pfgk zAy+6nYnZ;$gzA9;H>ZbhFRaDk+jpet?<-1ww*F2XtsS@b{ojGAUn&* zp@34lj#PFJvTa@=u0J6{Y=0d^^;Ohho3h$+@&>gMztJIlC=oG0`k$$A`VH$!wVJ9d zsy1pu4?~d2aO-^Z-hUNdF+W`?1(k9w{ORg$l_@GWYE*7ijVfV%bAuCCscatq81~GG ztI>O-0Ahg6&uk_#y<^Bt4N$e0D~Rb(_}lbvuAA49*AvlcSjS9au`?aVAOgmxM+M0% zqw4HQjf0!>`|8pBzWP7@w;&p|zItO`U+wxbbl$!5J+mP}8$`8pwdt(g!HuIA3lI6? zZbKg0tZWe4^swL;HY8QIvLUXyd}yTT=eHD{qso_?ve3=ZNPE#;@b^AbibkyH=W|AE zl9M~AULf3W_T~3dd*@@6Q_%-sC|??QW&O?z<+;GtwFBP8MnF znN(XRUxK!(x!R&6(bpgP^P5M1w$Vjf{buhq^?{70{!La>)Z{FhJdk<5KY1Q$2p{cg z%toU%Rk#CMO#Z;z>(6oEXmr{Zg`vRc1S+12D?_HS{2q?h;7NEsb5e>CToF8O*PX#% zDtvZl@Rbb)&~Xp!+T!s{WdZIN3*)b>9NXZk^_cA6xTpUvWkGK4r;iABQ)Dj9t7dqpbVON~b?Ix~oKYqLbV2_xT(qwbW^`fdf1@(QnSY zYrc6tBazYQG072`G?8+~lYzy2r`nk5(ZcReZRW7qOz(03gK6}meMEmWjee|;=wD5v zKjsWrf00Oyu|rY?cF3c^j$9Sknf54%tS0CW?7c#xm@VNJLQox~q`p$6Su84gR@kz@@>`+uyJ*5M#JB*#CC* zS3gnS_x9%Q*9F1C=llerUWgGgawQ`Diuh@+e$ie`rFzwG=-PDZ2>L z!xm!^>9ALxH9|KI`KGGuLJdT98oTshbs4?za3%V3P=Cz@{5E1SQ-A*iaBINzr1Nfh|e!+3f#9gh1-12H<5GN6lRmAU=l_9 zOmyNDHHF(!W4)=5KJ1P(`aai(p|ZQvz@?%zRJF1jUhBx()Ssr+BZI&91~0~QXxz`H zxs&GkHBo;#qh8~UGR}5ROl|ATo?r{gP@sY5Oh#k!fy`D zg+G}Ab?#e1{Z60H0a8mr{rvEPa8o2_(NX0enG}(7q=Ugy82n84u$4PgTRC91(z}^| zI*oo;AJOkmqaW@g`h#ioqt0;8PkVw6N!9#2Au2+y+0>*};!m4IaBlJ#KGU_-Y#cu|A?d zlSV&T6kYv2nX3tR2&KS|tQFXi0ZMH1bo^)xeiG}ZP@RLH>DIwd61l&@57R*L;AhGY zex_OnKP_zpg4r?n+2^{Myf(7vd#go7X>TL+O$&3KgP-@Q6OIQzXD+e~)26WEo5Jaf zLe@hhO@aH?rtodw6i&A^g{h<|m_*STYYN0EY6{;@jrDYqu~JJnrhV8Mi!OV-Jq=te z>IbJ%gYU>%Y4w-E-+O}>=iB$Hmch@;d2aLrhT7<7n(^*MJ%>HhYd7q<`Be#mF1$(z z8t(GLp6Abt$317xD;W4Ze_k^3Idfi@p${J*8|fsEDSh$2x3RjpN}|+~tCW1Zy$$={Ng94SkNF;*O!ueW+GLpU-KP8AG4@?YcAg zQ-w41`A@rIq|Xd}4reMW9r_&di((FGaY*ja=O9nI4}JD4OW4i6T_H=~5=iI171HnU z`RpULl-;NijF5$#5m7!-seYu=yP(Xno#b%&xxIG=yO6* z+G$vGi04?0uJ1_g2TgJq-8`(!NCoE1P&%@^oW&- zI7NK#;hjmxy}VN$ckiLkU!>6==_C46Y4j6C(KADz4x!YpJF-?_M+PWyIP}2`n9h#k zd7o7n`Yc*EliNlXd~da&DD7t2;XI9G=)=mx9&;HT%isE)`RQ{N`8f=Kj%)pU*YVG>+=cJQ+`{*6J~cWQD8@|3hYdKI1=gx zCc}{s;Bbo1_qgQJypwPAvp^Q7o#(ZTg&uoj+gRwt8_#Ym^au&qG|(HvpU7YY_pKQ5 zsF&%OWJ)n2GY{kn^q9LSS`i6+^o>bxe(a6KF&5vSi6 zUXp1M+_$!fZ~GQ;y0t}Qrh}Z|XIzU=w4xUA?bK#Z7uhTpcw^e3ow4XL%iGhy#iC9z zGc4-JT50u{!QXqk*RW{c1K^(RF5%Y0tuO>{9~b@Lri5OfAnC&EZCvz^;whnB@wn*B zu7YvV^ShF9(V1Oc#zm~GPsT;%H5nK6`#JDAjEj!xL*}mIqUGE#n3vrb%-yIAZRFwf z`{m_=@0ZtNT-0y&MdKoqt^2w-2ninsP3glRwFdjz3R7tPFi30Sj!4NJdejzW$P;)7ae+=V@HSdIDcGpP>;Hgi}ov5O%A;+WNU?F zT*Q4V!r$R@+Nb1F&XbuPG7%ytNo2W#6a*HHi|$B`W?#G)Ko1-H!!-KAKBC{7MnBX? z^v|Wy?{gNM85ea(s(ztE9tC#fs=&^)hvTAd6+Ijm0S+hGWrRyE+dFZ+YxyTEPCMIc z85ccrecQO``1NNuE_#3jY>w#q@Sh|Y5rqG^9U~t0GA&D{6eBW|M6N)OxQn6{vA~C~ zPkQs^>x;)lf00Iiq>t!NrO{6mMbC_jI)qZ|?#Nn!9T}j=;kXE!UgdGoqU(HeTgrm( zxfU!=drLu_rLO_%hV+_(0c-}EiwX<2;QA~JJD zPVg1iA{4EtMSL^0*{6$a77KhKjlN>hWtKOmz1%`kr>F zE7x@yHwEdqsTN8A_OW6wjLE4UYvqwIXYVW==v`OWXSdZ-yxO}0HYz)IryaWyYzwY- zr48oFS6N{R@^h#Jx%o7LE=yu}qr@n4kCCpXm$DYP5is_>?%T z&XxDH#A=T7^bz*18r28e76 zsxP5$2<^hhZ~7AYH)83U`WTfkD@9q~d}acg_N{6)df{LHYE=ETE6P=sN>QVQ)8%Na z{u+G^zm@&vw$3*v^-=s~&CzA_-W=PkC;F6UY;*lJjZxlWPPW8$ZS2owiR|8MVbQ_= zP_6&>spd#DKHt>Gx2D2y#5OkB5spamARJ@-!K^{(jfzS?|qBsspUs&Z13VaT23wn;>-iil1FJg&yyEGgGb z?ismW*plm(IM=`ZMmc&Vx&J>))#w#c%_Ws%WA!J;qZ^+sN0U6*_bGeO(7r*XZNcY9 z-PSHu^m2r4T^JT3PaS#KP=fDW$DKUm=xwfiWK@5T#$Qp5NFrGiPmyRgRXgE)!{+qh zGrpjU4TaThf&YY9si{fyFe@VaCM9JQM}D1ae?;C<9Qmh`$nk>k9N`qyCW3<6GEz`m za_GD4HeaYnYZYzYfMuKMjQH=Dcv5BGM12`*pD;buvVVga+$6S(%R$vgsjhMcSP3i3 z%?jfC4WCqA>IM6Bfsfr-w(ZGm?}s8|+@2Vtz8A1|LbI_3>CLf6RkrDYs+6@U1ei%^DSbAgxB3%Cr!B&d5+k*ciQPR6id*k+Tia|4i94~d*JF@mdsWkdtbz0k+WnH%O8E{w*$(U|2 zEMuQnl()@D%{->&3^SXf^j=Z<-JmE5SE2>}t6sy4BT@N====OvA=47i`39g8j$E^u zpDz+T_Vb&YmFjz`YkTGA*@dLSE9_M<5(Ty9$b1uUQr5gk_?yE~OZ5uuuB?JdH#4>R_MldOZBYCCM5(Oa zc=vpBT%GZ_?~KRQ8INy81L_Xyq(DbC<&qso4P?59%kI6dx3E|{Tx4=p;GDaJ?y`x< zw|vA-_zI$x4?C)%a+NfEDDMs{NjCvn7%cAyxieVaE^8f+w$o_Ta|$=qO_1akbZ<{o zXXBR!yP6Zrjk1kMpeTGeqdgMJ?n1|aim)HMlN;$vhuUXotgj`VuhDY!Q|VEZsg7^T*ki}6!|>ZeF5h>P7VcB%ec)%Ip_$C_ndqgZM4z{}^j|L(ob zk`Suo5vnAFDhZ(m3SxKd^B}gU8*(3l7_~hFF{gqdh=oHCGwl1J2C*Z*P=SN3OupH{wV5 z6`X-t*KUQ)!{!_EUoz_3l#SHX0GaV$RgT?})Ulh%!2G(Kc(*FQu5EH$xu!!T?|{pB zfFOU-}w-EvgI z*JTOG0^$ItJk=|ffZs%3wVz|0s@klY>;CnOEUVP!1yF|(?K#ueuSH&!|L;WcKHEon3%3rwA>DKHZO zxoA>(IPB{BX)aNlsw`_Vk|$I8Q}s?66DsF+H_i;w?k3fL(%m3{>uxI6-B?vo z%wn0 zM=eKqXWKcdw^(Ih7P|v$PdRFi{(4w!Cr33?eTTEyw~_@G`z|#nW=Nwy`yQmZ(;EA> z*gwEx>$w&SXWSKAY=xA!?uDr#I3HbHVtbd!V$IrD{ zs|(37KDBnF_Web69YUALek}msYV z1PzDn8Gfz#nl&G`-#GH}9=0DI4%>$v;jkk#Ca{Xb_V>TcJHjXMOi!jIP3_A9pP$sguneV?+AaF5#ijhBm5ES2ycFwcZ6Sfp%VRrmte8OiQMeO zEZYVQCvr!w`8BOKN!IOjOvb(pW?X*fWezI~@arM04A+MYXIxfweaLMub6EMqAzK*^ z+lRyU)gHEg@MR7w4}HH9y?QtZ8m?v?t`Aww)vUL_%wgr<4q;`;R)%b4wb{ytUgog! zfg!96VPyy_s|_n3d6~~${x)j^fBYp3f`+SE2fdp0_g>~5;a?9s!eK`^>%rx&Wjl~%)@c!uA$ zgR86fN#7@5=CE>T2rEP1%Fws6+P;-LU*@p#e-B}02rENaS#4PPgO@q1d|(JGLs%KY z%4);PAHK|&L@eO49WIHm-MW87_T~Pgk=mb5a1QJ0@5?bjx9F zA>UoAhf$z)ha^Di?elGiR>j;R}eYx4ZJlU692cP&I#I@bN z+q^v8Zl4{*IlLg#FllTB;NXS>Pf z-6OT5>l~u36rD7%R3deM)BwkwzLWDn;=?gc1#M>yaNI$|W7<1gVsZ9NIXWHq(*{O6 z&d0D!?6`q<0*Q9qz-X81?XeGY0&Al!2W0H01cJ9)R1yvxIB4fO>&z>Ee2k8<;0zVF zGynBTyLyWbN-9Su0z1b78^&O@;XPqvJA+@~66_3qp35hW2Xld)I$e%_-`xj4M>__I zIOAYj@GqN{==-H#WfN{ro2hJ$N*sq>-t8j1#ph7jd}$Cw-wgInj|Am%xukPzqR}Lq z>-hEWKUPYz`OL>kmj%JD(zQ-T1o>ygcw&Y`b_Q?acEY{-*v!R2aAjqWPLD4~R9N&u zPD$8WbV>ph+CF~#*o^e#c>-gm~#N+E@w34 zj!Zg_X>hr#JFwh)0rGGCO(l9|4(bW=4gyaco)DH=_vNs2QjRQFqY+B>moJn#Bc7YD z9jWTzmFS}c{B-8`K2B+P6^WpZJ*bKEFIytN zHID4jGy1D&}0>kF0E*&q8bz>-YoJ02135VHE z#4T~IPaxuQCbx^y!y`EQPK~AOnJ`y>0aWoAP+s?1hyKURa=Oh<$x>v6=ZMFr!kmSF|_D&KIB|&fTB6XEtSP`FI(N9`f zbb3PM;Z31=Tkw%mBF`;$QXED4RHjc`Ih$iH{@qCJaKp3oa>402E9wc- zKJ7>;)2SUPwRLJp5qD}wIPS!aS35$Nv)bL-(-cD8+7l`a z-P&ngLH|SkdareJW%`-?e`CvE6u2e@x)!lFw-|1?jA_U-ors$b}SB+lLiF&pb zbuUD`>n1x`Qd@s>%#)6vL_zPLn40QlY?XSX?|FIw_}obtLY zxY9u}tZtk27F9!Ht$~rRU`qJ#!yw1V4~ZPr9}+n@y77miUNl_!VXzO4*nSA);M7k> zlraxahM8`JDGKg9H!T!A9biTQ2aeLdx41LkM#7P04)_fAY>p;%zAsNaId_4-_kmJ0 zS^w(T8yZ-pf_xmcV|D#uRRIxN<)qXl>R+z-LQ zcgYxLs@ox;vfQxzQ8QQRH4mc)a|(yu9=>%-ebO5z1^JWkFoa)IRVW_5$9 zUn4I<>c+q?&^qAH943_YWBgT0&!5QiV=R}?;<(OFkJOHZrAeD@JR3j8#1&=aooI1T zME9MEd4D;QAH&?hb3|;3)|{Zd%8ya0KRgjmba?06{1}z`q4CB<7X#_xp0CBTjuS2J z`IqX)P&Wrx8jvSLC%#Ut>r(h$qvuuhWQX1dHOlL-wbi{Yt_k<`mkbzY9D1G97S za*RZ?dmCfnc(iezA=gNBdvB=sP!!<@dQ#zvtGA*#`4GyLeP z9J6_e+Fz?C`;(Ht8XXVJ;9D%6COa~(ChI&lfZs+fm)YE`gyz-Q{00WnIc7q70>!b= z`FFmIe`gkF$0u0AgP$j7ke&6B;NS61lGXC>R7A#Fp*!Q>0jPUTLsOC|6{nt^7|!~4 za;Kq-{X5mn0xD*cViB}}%FTqQ3#iC_lSJ5(6(Kt}ofQFLop-E#0o8G|Uqkz27-!y! zsZqL{Z1_Ru?H|fnDwWg~=75vlWfo8N#}nae>_qC@u*R2h{xm0Txd(OB*^-LP^+&=6NHF8cPfTA61eWDU#JwG%-r^Gt+p zhBcD4o_HNzi!=6|Oe(S4yyQo-f!X9)I>Pc2k5*;`cwh~{x>#(t!Bei&vq$8!^Fy4I ze_?`AP7eukddSuCFQjASZ9%7hVZu5O8&K0g&&t2>??-Cuf-qouqW)acfl!{HNd8GyKowBX8XZ1>#(wb9^`*?YSed`LMhQ!r|Fu&WYf*&%eIVJWK$ReP0Z~2*v$OeK;Ct019|o8B-T}N ztX)aa_BiOWBxq|Km9lqW_=0cY(62D)W8UW523) z?aEFFkffrly@{v85G3CA@RD)OszxA#k6?xoD&6lTDRHSEq?cXfFyiDm zY|FNv%=E)OYeyvEp6+V9P*>Z9%Rt877`PdtA|yfg)CSIYq1@=|IAp$4rK~1UB1yPv zPF^kd?&07p`Aaas94~Kzh*Bi-qEhaG*J5K!ze&2OKCZ!1x(MFIG|m3Ff+G&^A$_G)G?AUJRh{In7P zBiALCCrGPDgk_9v2@TD>MAg^UT6^e_^`M?K+glWDy|R8LH8rcA{yJXO8{^4hMm>Ep zreul;(`3W~OfuH~V%sgYT*hKc*pDM*^|fVce%=N zK2LAH*}Wg6@O7@1LwTpHKjT3y`?{|q-Ph~g<1iQa*E~LPm#b%Q-fz0uy&s_Pb*^QH z@c#X8x?27-?^|wg@Bf|m`)+aXi2ADWfAXNl|Kh&h}y zS<0LB@v|)DO&U03@9S;~LO zQvO8GM^1DD^n^YhKGBWPV_C}e+F!sB{X*Y2-Ra8wtv+tN)0O#jmh$8*<+J+!*wsjCPDnFQAm~xa2QU{njuMGPSv3+1Ag;W>h>Yfy)ud2p zF^^imewfpaOc>fHX!j%0H}(oa%wVi|gC)GTl7>imyb^MbkqXxwB_+=mquc#xDrt#! zN1}yebOLAYWc-aC>lP%-i0@%qk#|%!qq!1*`T_l!z=fyvM&c+uV_4+zEbHLk z=d5>0T|H0g@-@T!br>}?hz4+V2RLZ&P{7scL&Nf_g%#1h;rQ_Np$IR*BFQ{5D%)4=M~M~jB{(CcBDgo4 zK(J^f!5K{z?Y-e5f<-pNg91@ikY8l@hR+c!3QDl3lnLR=nM{b7 zu(n{I$2frR9lWOqdPg4gKZ~Hh$%Fp72zpB%bYu~9NFMZOMbH6x(Ede`b1E3TaD(5X!9Myd-kI$?7?kV{X!A7t|!=X4Ud5l`7N+7Bdj1)0zlNDvN|(c<=o z`BA(!JQitr#Y{g|qBu(wD^aXOX|NxHlpb^h!U$;uOAwC*E-2j=0V|qH5d{Oq@CUkv zN8^KcM`#35k3ZM3nkBriJJ)fVMToa)ENYrwc+bw}k)P_KUMMKn(mU1< z$+q>iCPb>HCthp9qbefxJrC|&>VYcm8s(# z?X_>%`Nn?z&KH^S!{6~T-uFTU_*{EMT(-4R&I?ZS;B(mp73zHO)EArc?4Ni!|Gr9{ zH~Ouul=ENC^&qslN}Z>j_F{8>-0$Z9A6KaJTnu7Got1K4_f0S73soR=xeuXAIk(*5)w#Y(KaYRNgKedp z_pJAFerBh!PmFMHS%0)X8Jqn?t1`Up6>%bft$AykXT}sE_*(PURxmtoT^{YVkhLEl zguUWczrKIW=^|n~OC4{Bmj`=@H`Ff_(_kUh7zDzpSc=kN=fS*0xl+60RYTZ!;Sa3T z5(%VJ4XeWyPs#AJJu}wlzG#zcbB9K_QY3Hi3Ii77Mx01OGr22pxk(?q1+U&OXcC2N zPih@@FjNj{UwKaGwiRQti~9|UA&pE7X-EudEDLs8?1+4^Bkj_@ZueUg{Ybs)BvE?i zS+UM*2vC;NPiF5yx(*v#+UeEJ&gKgtLrQr1Q)LOi&faI2;K?IHO89%P4d;(&gD0a5 zDdB`qmu)yMd!O9~Phc5R!sA{W9vRVw0TE{5>hyD;jzuK*4Ov#-Cm2t=#~ck>n%si) z41VL4WCD&dDEw=WiI6>GG9@#=28$M^XDtpT*^XZzWl6e z%`W93GM`)#+IM~@r($Hjxni?Rfr`wVPcZhf)8kyqRAj!VV&+n;BJ){Kn^?8eHJ6eV znLqJNwale(MdqJYthto0$b5grnoALj%$HWoTuNDF{&K};mx30VKltlv04rrJGXMNn z)iRgj7MV{ur`p6QB`z{w`pIgUOQDO*&wZj==2Gq=^ND9x%Up_HWWML@YMD#vi_8yK z%v=g!Wd2meW|uM;nJ=uExfH|5{A9&u-&;tWWInqhk~~xh^khD@V$G!tNaja2R3m^t z^-1qjk5!u(kN8~jgB9oV#*cVJ|AI%V)qJZD?XR3s4L!e7DAEAzpP#E%^R`oSO_9u> zdcIob&lRdInLqiPYMIY0G%zwB_mgUw@4F{gPRM-gqt!D1?8DwrU3phE3_JZEFY`xl zt5)-)w|LFIt74yTdC;r*b9Yy3_HPQk9)MkSZ?()@?)RE~Rz;%!RACpO=8sg&{A(Xz z_x`*Zv@b7gQ`CG*#VPsik9pAEP?3h+QrO|B`NRKGt=Xsh#Ndhhs}0q)g}zVCKddNk zf7hp;*HrBDwr_h#@@T~=`RwH$8M?M2l3f1@Z>XOCWHo?&uP_M$utzDWieB|0f2eM* z2(V{9?lpT|MfAK0mh5avH2bz6R>QE*_`K?qKdP4bzQRUB&EKoYtG4=d`;^D4)%;9h z)uiULw^qx1sy|deswhfb;LoaWRFt=Wc7r$0e^+rzUU-t1`G$%j^VPl_cI#8s0CuB4 zF~0WwY7^tjKHWaAq8xUyKU8;BrsWzw$GGh{JNLh!vOlnVo#!7broy=N1twg zv|{EjZ1j-iw2GO3>$97U&sKx>3x4JwR@CSo_W|}r)?BL$)oH$V^Wln_Z}y4)=@m7) zi+yN6x2amQuk`_T#Rsb~x=;9-Z>^a5lVA6yU#)% z1>L^=_KG$8Q*uki%%}L7FRmy)KJF`J&sXGCkNZQlsiGYA1z$}#z9O&syLBG4Z>(so z_&d02F;qXODCvI$SB4_Pz4+$Tfdu2}N}zNzE( ziZy@t0uS0}-dU~LKQH`=kPPm6s2acq3=UN@{|1XrG0q?UX|)_o*jZ0h%Y3CTxIR!( zulkPP?2Q!{>_6@67{^ys$~Hdik)cN`^5?63vEr(#Vui1Wo>P$+T!m9sF{^HVxY|&C z{~KQB&sS8we~D{BQS+6zR;&59{!pDIen?3t@oEcuR672=5zd-AFsH;_gTNs7yh6c>HUOnalN(TqUINUYsI}4 z$NB5N1b9b9A?`8XzI|~;`}U(gqx*VA32?JNtG>&)RS~5w@RhQADk|UC_(cDyiv0OH zf9>Yv)2lW6m%h37+=`UsV?KKRx}tsi3qCRU$Zx9=z|Z?Nf3>38|GYn+e_2rlzT#`1 zM)z1n@$m<~WN=MI8{j|qr1#N^jP9P>y=FgKQHwqGbWZ~OK}8+oNq;_HS5dn;$48Po zD_UqC_L1b8if%B!lONzS{;Ybq;%dUDeQD_4ibCAwz6AJ_issszeU9;iih}FE_)6LO zijI>f`{Vq0MKbgW->`IjMdSF@{;ayQA{n~z2i~lDw4$*7OW#`YSj9!n(|w})y&oN5?iF>6bH42f>%XlyROk6# zT3@O-G0yYZ&8CXW=G**<@goi!uOiS~=C2x^ThTFNy)TEI@r!CTKjl-;>nak!GyREi zQ$;o5Dt}`9eMN!hQJ(;Qs-gk$V?OEqc*UAe{HTYX58qx*0zAo|&)-s>3zl*;yzPR$9SOF9*P<7Hx)7LDZl1hE8_OWJ~6nlA~AT%=NP9|)ab7F z8QrFe3d-$1CAqJnyVFJ=!>+Gr8~U+tt$4noQg)%==c_9A`E&l1yrm+qy3@BZUtH1p z_-h~9U#=*uKk8>b9)+U{(Lc#|+5AXFgTpC)=I1IZ-8(S`kTZ z@E5P2t7s29_b#vID=Nw)|HOh|Aq{=4qF8aGFX?Zt*zENedK%r6Y|yWQBp=-DWxlmy z&1d>V|NIB5v73|q`TXQl)iR&z*SxLbP<_F#`Rtq)xnXOKkElGhgMin;R=;-sVd~A0KXU9a-~nKD)VSxOOu#^LKpN^M&D- zxRIGp@NxUA!xfZ~nLqD~k0)#$N`^*ee%{xg*9|vmjm-Qlf6e{&;SM+>Gk?~13cjdf z%|G=;sUHs)D@N9Qvd?ZlJ6swXnfb{ZJnH$K;k#c(X1?Fot4Roe_RRBQyV#zb^TOC##|7=Y3)Qvf*;r$eNGymli);kr~Lq4ku_gHWrbe#$Z*YlWae$Y8SiHmC&pdA zO!D;b#p{tZ-|q{qpC4{<9hv#pezPALz7=j{=Cgg7K#bHiPKMmGCnK8w9;_`2lC z%s2WNcExa;!N|;C^KF3l4EL=VnfW9B!p~_HiT*ZU8v4QTC8v=!-{sf*XvNGo`0VC4 z!|mH6Ykur%PjkPuB9i>rpORl1z7#RC<}-X6_Dn_9=pTF3(&3zX7-e469*y1$yx`ELy!J!_%&d?o5WI?>lLv{*-U=B&;W*NL>_2L%iC z#<6?-`o1A2J#%^1bg;iprRA(XyA+dyY`NE3H)reY@>uskaP%x^=(&sDhMl6PGqX82 zFR&|thb7>Eym{`dWe&iz8NYw{O_(*Iys%8Z?f8<#0Wn zO}B@8EKKS&-W{x_YAgRtb8Vr{wkrdSYLcxKHp(oerqe__(@t-*BleE2P03 z_?;Kk&>4NMjr3Y+vs#hxQK^hBaNb zQRVnxMsa5j5FR+m&vmxvn!+6hUvZ}h(-oaFxTl>^Y>2?Qi8>NE@(=NInG;JJCB?~# z%Hnso7t6FDycwW_;=)|SWSRjso;Gp}l$<$-xs>nu;p zt6FDyR9@Ab9YysA0NWALiBwmbu`YR>WiysA0N)9=Xnz*!aeN_q4hIV*9b^4zsFWy| za^~|6Bud>KwB+4ZR1^Q_M=gi@tAE)~qdQi}^qoL#U z)iaZE5C%GUn8D)C3&3Fa@q}Eep$j$;JL7a)cvQMV*Mme{!fw~4WvRIur$~*oOwtvH zcDNl)rR!G#GhAw+0>)R>R>mul&AHTr(ce~oGuNl_wpwEJxLui9PwH(o0)d()y9O0i z&~mRVYRMY*n!`GbDv7z7$8NCXE|4&3(pQG1>F$PbUC2^$*N980i+;HLL{O=@{wX=I zXxfcSpt4e$SdY5EVb}B@s1$wFD`#(8@5W^LDZn$UgWMdo6CI@N42F53<)9VLlLRcsM{wlcUq028YtGQ1`Q}?#D#gs1h4;Q=gAK4S`?(%@B=ZVM@H$ob+yB%Tt)%9?f_llP6h}yJq6`v$kYUrr__sf`>Hrbj6IjVUR4VQK9>&k4em1&~GULxpY-c1x67(%uBc^WCqnel7SiaYE8w(;rL5rpMRy+tcqmc1>@b ztdY$eCFJt3@q>eLA?)~DiZKL7)HJBD9!6*XT$6=j-r5PMq5WdY%nBQu9{WpgBxt#* zzF>_3o^ONKy2g>*;V5L|4lUKmi+XH;>V*2VNEOvSA&w%(&I+K}zya3K3x#Op1ZV7C zqQvfBWK380nCpU1ZF>CJHGNQJ<6Al*Boz?zqRYQFP6z*)5s10x2H5aWIWDI%WqI7p zvbhk>*kHK{vF_b(B6ChTQ;Z?4dF|=7N&STBwIA$p*Q5rETLY9R9e0-~{eK^kiZUnR*Qtt*bGfX|WR@WqgEh;*ybrpAa%KM_h9NFyiUgov@)FPp`{=)^1?Z zL{rzbKi7)JXtHrP-IoMu+>gs0GO#iDtU?VyhX@o3FzZ@wpN`p7qJf(4GCV+>=z)+wRx8ca(K@bs+{#MyT<+O(Pru zpb;WHv7-cBBlUhdYm?z%-cvqk3cdrgb!b74*Q( zsqy+W=+f34;(u>qI_Qa((xs#Od2bP_~Oue)wCZ5>3NU%GB``r)sC@h2Bta?ckZ)#^fe z8By6#T*E6}2+}RQB)WaZAa(p)3i}N-TasS>RNTF7ivi*y?$HRy}Q|u zM1q)t>L~H9FwhYJhnBFS@Cf)hL7SNA4bU%ywyY)lMLBpHE4%k{gUfH@e{4G0c%g~Ln#{V<1{%Oc+hZ5PC$qa+wGIW( zX+lIz`O@`^VQppi{`wLr#aj))fU0dc$S8k+T`6VjCt zuxVz9 z^Bjcf^nqy>re`NM&E|pMr@L2OBYv`b&1m56l(Z$-86vn{AZ(ydHY+zW-M_4MY%Hhy zZM#}K_F)oz%e^k=^?LW3@Org-6`{Psy^0=O>|U9L>3QxoqX+*n6(G*P*yzD2%nGad z3PU#lmZ95ca?qu`xrqbhl~pt~hB=CG1Vvc6`%2nwb# zqT20WPKIsSdLW9+luwtp5!vcVJ~$YjgVl+oH^{FW43f}>=eYNd(D7Z8+C*|*-MTQHKX z3n?ib?~PGJI*tO_O1~bi(iOZ}c`+bUiD}mgkbaMFHHn0-TmuF6C-NdYsAvpV)v>zL07u@~(aJgvsHf-(V@ZU1k^qI! ztIPtTq9)ZrHH9jSV2cqlD7C0u3QY^6_zf^EZv zb)qFe$65yE6}U54JxO2MWjHLQV_i!!5Tb#bXMmv2-E|a!0G*(I$r#WS8E+wt_ zw)dlWa1=`=2vhITitH-mj_cAuOLbqbLtCfHVYQGvf{98t4tp^Fd1=q2(R*cY<>q9w zHxMK%m=T2uIv8j?+;0*ib5BM=2v}vK8%OLBt)U0lcFYL^jR-8M3$?8T4QLwlnppvs zuqFb6sYLS~bGKd{F!Oq-HB8h4q#KBc!MEjrRI5kz?ft}c$PL)D_srzHdd>f-GbJ0+ z85)|LPJ58c17QeeY71cuzi>M=$tr2DPFpj110pLk^oy*it_Y&x%!c=Jtu+N=G&kd5 zzb2#_?2~Ato9k}KYlGzt6wXIf3(8hgbk=Ina!#wk^5)T^EC$_BR-ATF7a zsU}PS9p-7;%6=Kdnzh&|A*haep#c#BO@Akp?D9_B-zsis}aeHxrm8>s{Pw2ijOtYE`=$&v{$1ISh_FlMUe!J`gC_q zKmKpTG5L^c_X?2P5c@VvuRHGe4I59{v}N5|Or7-4;#osP%5e9=)@5taG6yJ6T?9V> zBi$kc6U9apo7DcYLzB{1!h7N5aI18sSnZ(*>;Nl(*&HQaXBpxmgA!u?%Gk2Y8F`=0 zv~f(jWsjpMVB(l`-2?GaM`Jx(*IlKg>AI~kbzH{%?pY;IQ^{7i7<_NKmQ{idH&}@U zl$F?LT-1qdmM);Gbz6g@pa!aS-NaEx^Y?~ehQBLUi2~7IEd3}VVGm;5XkYl>65OuJ+KNa}5rT^7sbyO6PELI4D_|AgO4)vcwmMz;7Zm`D*~aWGpG7{MJa!=?S1$^TZHU;MP@&ua?aCbym-rxR48w0~#^Sy80aNub=}tEnYijMAsH<_8+^iG+4c z`oM)v@nL<7=%g2YzW9#yz4c4QcckwtueR@_k3PB|r|aH-RDWFafHJkZtx~Y1?Gu0| z#~htLbtN+bXVZO9sRpYWpH-B6m50v)U6T{$xF*TEsTs`@ z@Kc1s+CihPj1TRPcckAoNS!{v4QqHZKBZCuS^Mh=jH9{MyC*B9SAunaSyk23*)vhwuB)4539MOS+qgEC5K|c6e z@V>M=;|hpXd0v3Z$6=!k(D>4A8(&rtE^*?jh%okk6%ZnXdst8xa3&^k+6}~7ncd40 zm?NGEQZX6~U=w?&7R_tv1D|b*eH@)W`Ouvgv(Om|!<7WLhQm4&meR%XJj>7Rj8;CCy8%g+<1?~oQa9HrJ-4ebr6h-Siby<9`-958?4AW)EeHQ zCw~6LpIC>WqDo>N8h0JCxWhW*emzh4^|W9qfDOA^IFqiN>E43RwTNj1V9_`5P0%1Q zqh`7{G-2!62dje9usLIQi5Z#w&jWDC_F`8Iel8#UOa?y}4SveE+bgQYFe6)tKrCQg zZ*{+|*Kw`hvjPOuvZaAG3oGLejoP-Lx`Y)K7`c`p*YuWX28TFPh^F*o!>1yD=EcCm z%uIh*0b&e@%99#sP&bo`N>*rHWmgt4@NXE5$5n***BmC4HFhKx!p-l{s>RbMoOH%z z4{SMZePhjZZR7OGXJ7O5)*oO0p?T|*#nXCGz`NIPn7-oSTRx@#fBK&&Wy$oquiw4z zu_P(ePan7N*y+~B>21e7_o1!lY}pp9hq9j%A3NP8Y}@*ETerPIA^bczb}WWYx{UVN zq^T@Zv2FpV=O zkAXUzoiPKp7S9lT+A}?13Lak4n-Z)e`E&@J&aWdDWt&t7!v5}NnqHag?zwe9-n00q z2ierPgz8IZWzZLC11!+>7Sq7RLWnTy)Z%0k)2_;wnMAzZLCEE_Mv96t*U33afz}X^ z2(J-PK#MsiUwzeGmu~GOiLh4BjZ4GxE#+AM@hP%i$YJ^+{SZqpmMLM2IcR2!)6Sz%He>wWV^ppS3 z+YEi=U0}eNn*RF_{8uQ!A%Xi@m%jvwrqWdJRg^~dCHdObJiI3;Y_~Pjd)wQEpwE)4 zdasJs5E}d!N`F!oX~gx+6XI-Q&#GB7p$^Yc5*nh*7o1(GFMN3@fvb0CakxF z$pm=cK+~tk*7Wz-*jt<=N&f@M(lyi9w$>0D{1s4LI-T;^4vf&d7Eg!C(hqFxFPRS4 zCrj4oskv`I{}QY>fL}WOh7&gU!+EKE6Ryk0c?!XPdP*bvis?{~#nV6_#3zHd7qYS_ zYB9fioRBQ}PeN(HO4S6a$}G(uf7uU#Et%#C<%CSC8tk9ls&Hxp*^5S?O18}{V@z%t zW2IXLenf<1ZW&{%lCezsACvSywk&XN8Dk(vGKO!4xm-Xf^B-I;mN=BVuK%h-Tq}RE z_HTV+4yzP_C}Ow$j}Dx$k-X|a6O8kc9x_%b@^8s)>LQFfNqM5hqAJ|T+WL^leM8pn zQSH?t5;G(X-Q1StP@EPSAG%{)STo;zEMeC$<)tzb*eWCHi2|1Q&8}V7`y%qiDB7V} zP7-q^nn~mL%2u99{(aV{(NYeh!5xWJti)*H4fdJL6HBknTvEWSzd^FO36B)z$>zK7 zP&SWMtS^=Q{$%sU4rKGrOD3B)Og5)HC!5RZZj@|Jqa>R*kRb#)Z|6z=AhLPeWb{dX_hz=oBVeVEJ*7 zGd+DbS>BpOeX=DqOFdm51A4jw2K00@pV{~h>gm`34Ktjco@0U2(|3gyw8eUo37d|w zn~s)f9?TSw9f%1+5;|xmxl#&VS4g&-1bOe5;(i&=xp+QtB~hqsKn_j z0>~(M5esoe{zAd)&h&T56ugODB=}N^^txRNy^dfSGey)yCbKicCweWaHPPJEx+SC4 zx+SC4y2Y7Vx8!$H>lUNdEi}o*)Vh{>Ip3N(sMak^mY7=S;!uTll>~_fG{1mYoGdi$ z%qzpxx`n32COmSj$lXFU?*aFs z*=n7|M?GA>B(+&p`A&w;!ZhebjMEYtXnJQ{=&E2qf1z*yEB*YUkuIlG>lWr}-2^m> z8A%S(%~9)?B=bQgQ|p#Uty}T|B+NwvYF&;Z9sK+prsis0OpkVPYMmjgb#XUu`-5TY zZicM}?RL^lc44u(Q0XYZSLznabzJJ)Uv)wOWMVg=uTz1LcIWDCQL=c5-o`%VQg748 zT)jP{6j^TQnmjb;F=b}v@4mP`xjOA4K{*%=k+?2<`bSohH7nuRVGPPBHQ%fVJOkr|LM zeHfpJdEr9$6WJqJXqMig#%BqgSe_?HQnpNHX32kAkCNpTv9mtZqD*Ei&hRELvrNZD zW;p2(v$wMZlNl4S#ND!H*@KJBP_InvMuQG*$BZeDP9nAyrRox~7I}Y1iMV58x!ig@ znOhPuduv7)y;Bl#R&iBoV{1yakM0B3}3+B;rg8cBTXw5Z>6SBP7leiEEWb;$7TNWRC!mb%o97xq+}1~RYB z9#OszHM{UWdSKnjf7bqGmTaJLk2#SWRcrAFwD980z7G7dKV+r@Ik3~NFnz7yBTavP zu}O2?Q(C7B{!1rZVlmyhF~Jh6fb~145S7h(ENHX-SxXjM<;fDK0La5-NE<>tY)Cuy z>bN^ZnWAjGv+OhkAx@{0btVZrIM`^D(QvR$>>SwS5nMoX7TD&rwKJJjE>o!owaK}# z$)MJm8&e5tbDKbW&4w@AOCy_xz&a+-CKyE1&sMD z2f9_lVr9^LA2S`!GP9T=)4i4i@&1!S1-!Pi2$0$Gvqb705i%*xrU zp9*wkt*npfHYc36PF5@nLU38cIEGb>BEhqmd|A!d#zKKyfJ4BouOrRL#%kzzwgTo1 z)&e8Z#hk&5Rt?D48RaRwK%SG^ZI_u8w%4wEX;;$eY1MXa+gPbY&D4y-mktAO{N79D zhLp%r!xjJ`nKS0jY)gr(_t8Q*0x)mcsVZtJUZj(Uc(9d7Uo1Z9D==-670BX?xy>rE zxAvJ+V{`ZcWV^0%e8qXV>9iMqb(+DhVq;3h!}qLsTPHS>XC84FnidqS$raHWpr`Pk zoIknf=G{>M~Oe60Q3srJMF+o1b@YrF3Ma{0#q3&`oe&) zXh_m*0{{*bIAzO$23o|Tq}U-o6S-B_X2L9g0<-p7i9vtdj@xjX0HS%tPh;M^M)6aG zj(Q2ph+6hqw`c6WvJGRFj6wZaXp{c~ z4?Fb8wq%wr0(@#{3Rix<2VD92WxyZ^sn!?%|!qyp>*XZ6}t{+x$^Vfo>kSj zzVlrJ#1FXg^F7p+pTz`oPM zz#`ltx&a9CMufQtXeGZ~)z??yBH%pZMGHynTm<~o_`(uVx(H->y~5-oV6?PN{>+u1 zosC6(F(tH17Xf_?xCkgJ!kLyIW!j-=vSN_I!UHNOy zm0u}6SN;-foh!e?SI?E->M30LsiK}MV7T`L!(91kmV9x_SaansD{`*viXTBp%#|NK&3zz= zOmFgC`3F7^fV+9ID+WK84}K!IghEn#xv;!j*r)5TB3TGFN^V=ehDPDBL6J$!_MlVXpjnIt0Gm z+$L=vxl4tg$3X3lIPfxNz@}A<0}$^4Q%?38?#gef;R1Ca>`!VZH>fb_`FueBSK|ao ze8dJ(8y7ph(w)tjx$<-7f9c9!D;!xCBq7^E!3O^ACXBL1=BIk%tq<)4)Gr*P%ZQDm+we@KtUozI7%t##31TvkHuc@>%uKcy3uKetTEL}qMG1n!etYDNYzn21+5J*_*67sL&%5N=r znYo1IFhb1VkxPh@j&=#LEgLVTOGwRg3CXJ-;u2ExT|ywvtz=ho3E`}d)k&+=E?RsP z+C^(s(#l-*22av2*1wS*6qHl*8zW zOT`8%$yr7Qoa_6CUMlILc-@aBCixe3yD{4_%f@AhhFtj(yNA2-7e4u=Z0_heEHabL^@KWl?z_l%qD79KIwtV1 zWxIR1y7F^=nCUf+X3O-D$>u~9vN8bVtB}o|sB3nLTsHSp%dg#c<JHYv}2H)l*vHqTu7hv0bb$`6i@ zcI9_C9_6n59*)TPzcV7spTGFR_r<}Bul8rm-RxcjdB*6>Moy`cWeamkXQosJ3P zN4WA!nlE*1q@V_xGmB0fIHw7{9anzo*+X3U>rO51NF_8^ey;}U-`g!Zb6lETbmq!G zSTx`l8E}o9>&idornG}HbmQgZ%0Fg$Iu8A%o({pmqC23czjUtrxWD_Z{POpk<;p)M zy3SrM9NtY&Zw|Whk0s41j@igv`I|z*SOCtw>oZsW(zPB<+j-NwE%&7>zg+Qc%f0V* zBv*cOwa>QPXL<99F0~z6V3mz!db+vtk9o8prdI_m(8mBRP{05!c=4|Mu%02V{F8HB z`B@)?gJ-V%yGuc%@4hSl?sHuEn}s|-)Ro`m&vXvCn9p+Mr;?p=<=4gy6U|?4uKZ0w z>34MH_sXc|%I{^&Ks>^gzqvhEemh5Nq$_{ZsdZKr7AwPsO0N7~PHSZH`*G!Wn6_P4 z{@rK0^6w5;g(SG6^#AC}pZw94-#n1CGo#po9mzrMrPSMAq~lU6bLIbi=xye8GDL5C zQLg-T=gMC%*3ss=@;kA}x$=({x?JYUza3q!SoDEUjd0~3lkpkxv6fqgvvXt)!@ioi z@|P`heoIc^k}E&?>Uq9|k_wA5nKM`ZGPCnr$}(fp9a8gv-;#E&7BF$H{8?sm0lp#KT?r{~bugqh0wu z!S>&XL|ny{{|_M%V}trbOT>S4BY%-xfJc zu`XQseUaE)`74RUb6oj{2&S`L`AflcKqN*y+mT2-Ak_|t#IVvKH4liyxXhO|4~WDs znJa%;zVk`vT)E7Z-v>YD=3MUoJ-hPPohyIcx$=)}gSql^HB#ovU-rV3DbybX6W^8J z74*`%@|P9P0-Hlu4_>(PyUKr`uKWW~o7)7?$mSA8LNt?|1e$Z@cNtkG%-1t;ao{&| zsTZZfgm7j=1wV25Q3=iM4B6sDt^cb2Nr7M3HRG5|6YUaE0Tl98a`K?jCvNq?+ zA3In6xOC;W6AFvXZsvYkdTcmX{&>KZ-_Iadel-Qmm$$PHso~_S%$2_^rgY_3V$bHa0rTHH4l;(S=r!=*+j^xe(+exJ(#ktsK@X+(@&Kp)=4`T;K z%n8~`r1Q?hDW<+#dIfHxyOFK4BmoYhU@(!k{HlY0b6N=K1greSbGpvLjF*8WSUllz z4>X@=BvW08l4s^LGro$oRDBGrr7B=xEfobVFCOz|t?;ejwhOjd=4D+yxon_0=g`~6Wdz^*uxJ?mZGVwD@`P0)s*uh+O*Z8oAg6pJ$yi*>?& zII9`Dy2)W&JPYGq8l1xo{{434gvinmjH5lXeDnE!Q5eVAV&PQ(aKvCoLK4r$xY%xs zDlp5O@7-u5!Yu6QxdXmPh6ifChGCY=ur1bk%nVnVMT2LaIEfvHuMZEO2F4D&kR$)~ z0XI%b{)`J;;#w;ZKi?wYex+M-cj$4WF74lNB5&=$-Jx)0R3 zM3Spo;Hyd8{YkyuZW2jy_w2eSTh`k9DZJWcoRH`CjBWx%OitghTKAre>6Q}RYX~fG zmpEdI1M1!0o|bm=xSK0uP$(87zy$`!dOELjbpyE?b?x>yT5fm9Ip-t#qKKgV{=BaE z7%Ef++{mR0+&&@IlWt9MLSaK2rm%J5Akq8j}4^xX4@#MPp zDQ>k(gA`~_wf~Ci^c1zU7rJIHO+rlrt3p}wa1O&S!_!TdxU2Bg%Pb?89F_^%|Lylv zu9{T~(s{)nyQYs#$RRpyD#Y?tOJgyu?NR z>3Yg=yVnJVBeK?Bd{(;@b4Rr<3e-@W0!SEYD;v({H-q+)fe70+N>q3Lc+lR>i*h*@ z&gTNPKd}+o@ks6-=muL*h?{S%Mu!^h&xaw$uhSHcS3eM+S!RH}f%{2pZ`>xC)OhQ+ z4ve`?F{$gld0?FI-mnzQ!MQ{{qIJlkeGYl+v%RsEoQ+N3BAn(y!cR3+vdXnPi__&| zSIvR6V6jWaj3C`WTu}tuQQ9YlVVJkK-%OgD%SLCPdCRj;HD5*QbCWega83b23lQabkeSxg4f9#^3Q| zeDk@71opG_4V%u{+@Cx!etR;R1qH$XVKgnFVeeq5&d>%2yE&eZb$lQuYx`x8ZsMbs zeb9z6E9m{ShusC6`<&qLZhN2C{c*EDZ?ihL5n4jZjzT({X$ehip3B~xd7IDc{v&NC zVsn4&!1y91#7X+ou2Y-);|Ip4C`=tS^y_0hr8AQhXE;c4He9H0o6qgf->j4>o}Jlz zFWAgMm*Z3e3|f5evU$^{e)GHoaF+Pcy zmxbM?uw5+6O?suW&D1}cMQ>49hfg9j1ghmqg)Okx%f#_ktmZpF?&lAV?V2O}N%Uv= z>h23-gHd`?j=Q197sP1%ZY1~1T3E(GGF}fj`ML>r? zz$p^Mw85A^KrwPKbI`gi0$L7EH|fw`JMAYmRMI8R$ZXcNON8H|tgNTtVizB6(Ex2=%dc0U{Zsc4*LGI!(dq5A`XEnnn zm*O(m+%Y0r5@uT)LTzmbmr)?Q@OsV0O2ls(4s%pk zoD~N25&o936F6EKsm)UM`W&pQw)0QIV3_J!86=fMctyuJQu4?_!QlxA@BH~aN@x~(Jp&*NSqgTo!&39Qbs%K(#`sI&HkGmmQ-Tl>s@+<7w z-$va>b(pSBIG}Rfo=Y?KikKZ>n}cD^$z!1n4yOc@j`ZCxHLMg6Mnj=@RDgc81uoc+ zrxXaF*eKh5Fsne>CEJ4_}uTz@2?-*5k_KOZC50@Pt0R5(c`yCWSdfPXA-Rna&8V~wE zOXT|pKn`Fx7ee6=0na|cpK&cw`sC%~>TUf^wYBMU_O5<$VUp6u*42h}^kA=dZh(ZRq-vR}Ar&NNcG?uO2yc+3u!PH*}`E4?G?p3oVQ-p(rs z+TRYt`r7n96Fbv;?4gaN!Jh*fREqc6fz}bTzc2F$_7;~$xY)OeMLM1b>&kbi{mL14 zk9i@ZuW%6xeO)QJb9njtCgs zYP&S2IhW=HCCx$o6U_-6&7o(2kbfo3p>4xyjztWmIb|s&&Ee)sM{|Ol=BU%NXpS~< z*p1z@X^xx930FX+4lV`V=|xa++^t6u@rB}Dn`)v@(aLCLga1tPFkQGh{mfTtqIPzk ziz7zMiK-d3OW5wrjphuZ5fRW>$1$+i*)Fozh25Mt@@XA7vVs3=bp?7Y{qlE$eS_fj z0b8fjOTVK_MfYcbYw2gRcO4aWR`w1e3FJ$xWLPb833ZSYGJ*S0Wy(K{7B0U3&n zZfYS3GAPmvZqZgFgRjwBNe1`Mn_d$c)P5vjYSsNkC!#vETcc_d^$~N>aEtjGjEaXo z;M$Urt(Hj14pP6mNS)-V?QZ!Y1VhAUk0SZPEIEyacFT@yES|NkeZ#$9A9Cr9!1bDg z0(l>T$U3MYXUB6IsiJ4KWJqlc!U`4zG^Ogpezhd6GZO=435AN436nw zI5nHWNeUgt;2M;jGdSKfvh|@1jw?|Z*^c;xcZb)RwjlRTzw>iQ;{BnQ!yG$`eT^Wun*MajKLA_7~C+;dG8=& zaHMh!j#L?gBgip0f-(k2kYjM}qHS{D8jNVi2WYj^24wt(Rhc?qA;1T)gDWq%Q4+A2X-XQ3d$zD94>Tbtl} z>+CDl*AVIEqIE~Q84x|-UmfX=<{tNCsE`xmVeyE@8R=H5GwN!DenjewV3K-} zbdN}$k#3TEq}whRHwvybqo^R=fGZ>2tiv1Wc9=Z3kqJSwTB4v?wJ``INp}cchjhbE zK^>uSyYB?{TBe%-SsN%rKBxRhH*v_fJjsyHAp&KUq#OL!$O_GSs1mviCDTo;sGM|X z1;iRzZtu!TH}b__Fq2Iwk#5oy>Bf;KBi+0ex(Q1gf0o#Kg6SI^h*at(we9OBPMm;r z)Bl6P=IxViDu;B}=IAE0RZPF>$W1}IDf6Y*OQK{2nj-CNKP!B3vwK9c$qb zqq3TO1VvUg02yTa2m)}iYy{(MXp$IhS|g~V2I;7cAe4#`j5UIdmE8??M`m+X(#!;m zrUZ;;b`VJSgAJib_k@PD9#--si`68MLD>mk=lu2?k zbWsUCfQ?Ef{l*MBv?>YPKaVkiAknZrIv%;)A;}OlmK@ZtA6ApEfc!0L$1r&&43!%u za)8+LwZNd-Ol)!}3XSbcX{pbowfC+PcJrQ32zo%A-vf}#S)5cSXQ%McWitl4-@S77+_CbnMSed#sP*4wNZNI-*4%Bsb{7>hz5$ zF+t9<-z_|+1U=c`l@#Hu5agt9o9-*#OZSPS9h3n0BPI;ZrWPCNxO<}EcD!ni@ir05 zcAQVtNJFR*a-p)P<)QQyc%qRqC>c0%xRRXuMi?oA_6IfAGEZb(a|4R7Uwf}R4lB}B zSr^JnOe@_slE6ylFD|Im5aOS*YKmI663sEX{Vd0k_)bI&0W;@Y8i8y$#5yy0nO#FX zNzm7-6i{^131!k1gBO6;d4B>LVyQtN941r0erPAsKnqVvug9#i1s<>L*bPZpHjb?} z6_B!R`T;$gAkbf@^&l=WULv;4utPgB)!F<~b>93Es@VLBG!w1J7zdEJ-CYs1yRT)) z@)|_iDcZ_ps)0a8jN9YDmDdk9mb8B%$`$#D#@QqCc8Mr5Y^w z=2VnoFD9NKa@B<$vUJ**C z8E!Oyxn(Uk(*)WM4=d!^G~xk0yJ1tirFj9>1MADew@u-(FB_g+3aNy zi`i@7vDphGv)RjAR*=1AQe*h9A>1kBd_!WAdiUnBB_d(9bn6q8MVmD3-|8N3qAo6o z`x_{DEb9X!9jBS$eS#H{?gz(2xMh72ZBY*v%4W;kUeN^WMDqCuUlAkrk#i*LMnHf+ zi#TA2RS-(E6IV>Kw_p`9p+8;FMC^K4qq8bC14*3`;gN}{vHLFd(b)g6^5&YE1d+L+ znkRe3i$oQ9Lkkv~M>5^+=^pg2utnufBj%EksBmS03MKsa4*tq<7)p4P5wTkLg4Pl@ zRFrlZ1Z23GC}@A`4}q_>9pGzyC-Ai{e2qtp*>>=?mg6hjZ8W}Wa0aGQDp^5OOz0PO zzYjPg795Za3k;U#Jq&{*2?cKP``<5W!ay!*avQLSuKl~%II#DjCqkxCwieEIc+Bjv% zI)bOSFKIfHJd24#7gTe8@3?;~#^@ydeXu2Rti~27c)!j?AxZ7cXa$fX{%9em-EUf4 zYpRDiPr-=1Q}_j$Ox;MvSNHG_QHC162;4Sa$1aad$YJX!kMMvWHn}N*-kY}8mJ}!D zNGC;ear0UZKaOZjwzjFf7@b>cLOmIixZY9?O$y`+CaHfMKOC*(v&JW)KDIyvNbBjcCuq&b_7q)Vd{j*ftbqoiW6~K-XPljF;a`&a`Awq6w~68glNdPbhlQf zyQv{(#1l=imJteEW;~|qB$FM?=shBJW>;2g^VHfp5B!0O;IHmrLID=IJLiBf9;q=a z#A4>RWHsrnvjAZ;pFc9;noM2;g@A_v0<&2L2;Kw;w=S-0F9rco&j1k*0HP8YMkRLL zFjtfk3ZoJS-PcKa0tbL|rV<;Rb7+7(>M_8yjXrbJW#|K%XFvyK1Z3>_!=?0ZMPVZ| zkJLxZ*KDeptv~le>fr_8rY-1oTjEYTbMNiRRQLJHuKoMDjJEL2LhFO7bhy ziGrd&!mK%_m|dKs{Xle9bh5(OL7<6^MSvLt4$Lsy=4sCKOUnl|LZ|_H^X8Nv3V{>Y zr~MI*EKcxYmR>f;bHo*;`bBXvbj?jG868q6bz^}TT1NZ!kPS`PnoglJL&eO7bQPK7 zuuy%X(F+!Zv@h&_+wNH&wu&EgKiM!HLxUg%K7HUB(~V4zr(2GcuTCGcU`_A9Np~3F zm|8N&6$=c^3%9@!ndA|q2d|b$NP|vcN)GK3o>gZ>&iE+9-b1c(6f@Ox&oj(Qt&?Xu z+UoQXuN6!&j04mm%0?pTyjg3(05xuoc2*Xd-k`DrGDan8pfnGn+Hd5=vsN zhm>Z+9n;(zp{Qg_7|JpgTXTyRpNKbQdaP+V+?sJDF92}OQ z{i|BkSnDpg8Kp!UM%kilfl-mhJq8Vv5m-p`7#y}+q*Fq~tFc$@6HL{ZiH4mpr-9Mx z-o)}bi5IT!-h!gco1B2V*R|k*T7vFwY1uti#*{>22eXrAsjTDz`|@b-`K`dr&BL(W z>bOm2!6wMgKn_b3cR$Rz$Ra*V)9`2+36{>P5F1^~`ZCZB^y@S{swQ+kH6G)--=Emp4VNP2lr?X7IbL=wu*{B~X0tbL0=n3O4*!^)-% z$~MFI5S)^QZ%=2I0BOzdCL=Aw5)b7=Bd}E^zrHAWMaHy7C3cV#hXXJLhnw5D3=BRi z98ys>5Poq#}jL~3k>8{@>U<*v;^4Mv~ghE3dO6Ro3{e{+4=@rT;Hr{ zZI`i48WZQDcr+}m)#rryb1A0AmW*@GV_!g@#Gt7)OUG~%Qe(>oGJ$RUNSf#N*~fvV zu$e;Gdc$6ebNg&>AuBsFD0M=agLC^6RC}&8m!!GbWoGNixqY^ID7o6ieK$#GGYQzo zp=wcbwL_%Am+cc#X)KK@Kh+}1up57L`m88~q(rXvQrcM3& zU|KDV@I%_S9i^3G);Kl^pD3c9my5H(Gu`w zer;uj6M;wra3DHZMNQHV>*sxnp5gow@Et@2`TPshw##+hUF1U!apJ=&_6zfJYdexj84^wEPu(kU!sLmqf9WG3~8lDU*5r zFsD>+Ju3yDaAW+;B;y2Iq`u<}M4$=lvz>w7R#fnoyn>pkV_A7PVh=P+V#9vXJBnOy zpPNh8NWjrmv%;*H2Li%GsKJSWb`dzVUGFbyc=wPRw$iE(0$~A*0$|Oep<2qz{FHS2 zv4OE=9%yUwGDLKd+gq8&DYcHxFbTX7{~tWi#z%<)+PMIm*q%?>|LaIU{OH{o=^vTe zEi#E%3n)8E4G)?r%6|J!r2gw7^;>q7x?ZdT3vG6knwA_)(oohQtJ!={&^~kl-|3A~4ci|ld;S6OW z&ls|^O+hAY`OrN`QJC?doLF{RoZ~?#)JK16-G83&0w8fn8*Y1#xH{W=9-df&#Z!da z?XR_+>U+gq%;zqw#oBs%!V(}t9T>mO|9CsiDY7niZ_D?O-{Rhq{o})t9<>clYuQps z^hViiZ_pcMuV{a^5k+fvlLpNa$naGXq?NZIL-0s?SYOzYtR;ZZb}Clh+?sckx!a}9buq-|L7n@9DuB^=i4@EV=`B% zpb3zLlLeiovT2h=1gHfFqS}>C1pfA9BSPDrRk~A;S}LE7mS8U4G25Z-^ zKAX~=Hbf^}d$kqY_0}{UcDC244vl2YcE;}}t)zAyYJ{2htlWjl!9HzPTd0aiZZ-sH zQmCX1(P-&Qgmcln_H{Q^#_s4&>Vx0%c194ehvB?n%qoLVL4}i>XVe97M@N_UV(5cCz(fZ`u*An-kAtbZAhA)>9}= z-~vy<-a@&TTtlEP5KiIJ@krgZaudq!B%Bs7FX4!QT{s6owc#Z}$AJpY!^*7ws&MIq zgjwMlI#;x*hn#en52zKPA>CaCFLDLDZnUgAdZ1GZ5KdinLU7zRvKhczIRng_!)5?) z*$m)KGr(oS9s_JfuRJUc((AXBXQN!Xr8pafm|MM=8wO%7_F^^-#QcL7bICx=yTi3m(BmDwSL$&9REEdvpfWsGKwfwpf|kN# zrF0rLH$a_uyai(pk2m!we0g*@w2H?v2oaA(To}${q6b2;u+W>Y$5Jj5<iO3Gu6iu&FMg-l(f+2to4)t%FL@^`ktc;@T97P!C+NN_3FareDR`rT z=P9^r!ILg{gMu3g1-B9v$FZ+Uz0L(MQ1C7mJYT_UEb%;rb}e*Lp;G#4Dxzsca5kSp zkFiinXj%zzVkNxWLMfqXCB%u9K(~@tGJR=X$67b8)=|hAYR4;RU|V%|tj=+ZIZZK3 zsh60h#l(q=VY>l$(uaU1eT)MIer>y)>Skw!0L!S_uW_29@CE}nB{UE1w+&CUVwQ$f z#D0%APjOfy_H(cbo+xAx^TfdvGpQ`Eandjk#zqet1*)l7a+86!JJNLZmuhMyO$!&= z3X_`|CJVh-x3gs0TY~LCW~17X7}i&CgqT@s=uaBH7s82MIBDQdJDxr#0}lSQ4GxHE zlv!S@gT)%Ok!gc*qK!>Vd+XFls~9twKEXe{M0ILw8xs;8<4fy^w2FJQ=$;x0INX{t zE87E8&X%jpxl}q{5`*GdCjy!AC)A+{`VGTyvohKJ2o|Rq1sTeRF67M{DdgEGMSv8_ zsTpsFT9{aPe{7BsOuk?^*@$zpp}x){8`cNzcJ@hy5sD^+LgQ@I1T#Y~ilIYb7$*!O zlW6Fh0%7+z8jdJ?#o2*(`t9y#f-niW;u&^kb1;YVsV%Z1n_vVJIsmu~*nnG&L`Mef zDyS)oS9U^~Lk14}EaL#9ejEbTO7hri=t(aDY z3wUD7jT#)GQ9y)mXf)O>9?te9NhkBHFR;PdO1Fh8`Dtl18M=pd>HHGt1!%zFvZH0_ zxH~uv9o~l`x6$CXQ5L+xVW-g?r1`+tCexdO?hQ?x>R=-A+uZ{rnZDj4V^(^L5rjuD zXemo~Yoq&1)NsdXoIwvp;Jf|Nj(m544dSLGEAf@W#q55o%N}HU72e*x$Ig|;$#1l-uQN}NajW&s_aNEyl zljx*u5{(T)Q~lJh*H_0!8}t<@3JF20x~4$~0b00S7d?Ug3$a0-0rhQ>37muhrF>LUDjiWF%;e ztxCqSO+jPY6g0LB>Pyr5qF>q2n$^jmfhvS}Y?B0h&w8MlCYmXy7v_mLoM?GTHJQ0H z*&ba=EU6|4qv5o!+o(c1sMYOLjFAYSKboHg6y{0LK6`#Rq0KV5G_c8<7jP#Z3O68b zP#~+U9{|0^WTV*(!l(u$l&Nohv;9`=f%prZLh3e*IrOD}mP%dg(N=^csDezw{id`= z=C;cN1As)itd`0Wqo))_3dzMLOnYp|66(ImrL9v00|}LqH9%GN0l;7AjBR1PIm48^0stIbn;eRwR3033R&;t+eMEXD_2`fTtf!A^aq9~lISuDc-uVyYq=B3c)L$yxK&IGT@&1{RET|&bwy*!PmNg$>sm?4xPu*z-Uh+Ohxt$Z62eA$55SE0Av_6S$}$XSS-U%j_s7(3L5ml)8%-$b z05pLn1ag4qO*Alq2ntKEY}jri>xB(Pk_(?r3ln0nH;MYw42@|ZYomq&HmY`H1hR_S z)$icrXCo5RmC#8h=6D*=EC>Qn67CFS>@Z;rk{yF2GPocKxD1kM0Fi1hF=_^(J|Ij3I!@}h>074LoXo<22HrQTx zq|~c!FkSU!?%e=DefVoIc|UlaxncqGn!AM$OWw4aH+}%rGir zK+6%Btf{myUg;(>F*d`65rD!v)#s!z-PbpEXs1ECoU-c>tc+zKO{iNEqBuhxmBhp; za+s4a{NLCVi5W0xl{J`-88vn4gJ>b+4moG5Ae9I(wso^jHnBMCapuKAd!W>V%iG>O2tNr`7;4!08<&!B~aA}yd@KK zCL1SVtHz0@=VVmFlobgJv1NTY{xwLL!g#tkHoQitvHC z%^5eu7!B~MyUb;U$SQ?e2X4FYtPn*2U8u2nXxkKT0+hM~mIls&OMoGq))vCTxBv)1 z8alnDp)28M0SlxPWc2fM&xW%T&gj64c_|UYrl%xBWJfqWj&!!RhKeh}Me>@R`VbS5wysRd(o=GaMm0%4WnL z))nDAQ$|VJ$rM8YwL~_6HulZ@6FAdR2qevPByT7ATVp;_YoWtZ5V0WP$Z2+&AX)0Z zWkGs{*1G=|(-Dt%^!Ct079<|8)0}h`Bp!#*Vje4{naP4gan6Fo<4sHe9~_SiA*6EJ4!6LU zCY~lMB$>VgW}-(prH5mDP3fr>dObei!4jr_k=JZJvPCd`5dNg?RGL4zrUUr}X*Ep{ z0)@Hs(d1FsGjqjw0pB#uXklM-*(Q~nNZCXb^MihCKH5URNSr&R0^vjkE~BoonSh46 zvcY39xgiBx%Aoy3=}AA_bO2zxm*})3BQ8v5jf)m@=B-ZuSCHMN@&ANr&!hpZiVvHD zk_t-0+yq@2HkfpdUS#eIkriL-Tk&X(FvE1MiMuKFOFCgxDLyk35(QC^r~w>B3WE1= z%7il>lI9pR-G8`x!+&@W^qXMZJAb#p9^DdCiPOYr8WIk&Qa&zHaUpu@j&rP#r|~E| zO#8RHg>BjAaZ_!`qrZ`<%?+u|jb(I2R(T*JtC}`2Hslx@c28vp^vgF9d%L5emO&8} zvJAt7CG52+`TxGcG``7p%!@k=3ukCZb5AJS*7E3%u-~3ZC*GCVDVErM8I-m|cWncJ;z!6w?7uKp zWs;8>V>rac?Y41+^w74@d-kK;>`;|D9c4_0ZC5uT!nj2}y@CFb6v0tyQ!|}-=j!eg zjm#cpbiKv`AjG)Uk3?qBS+kiJGgBOy$xMZ?e@hwk#|$AQ(m+WHQXw{5kQvN>+8csx z1!aKWacnD5L1wsB1Ty30eXS|jIhis4s-fec@pAiZI6zzI518@>OSczckv0J*hCG&# zhOhun(U*4CJw+mu(4#~P);tV{QM*KT#sI~b4Mf&?vz#n~2OGY1FK=*MEYr(UXK2Wc zJldrMHb$VK4p$yJI!q=G9%d9pR={6ie+Z4^feRjy2Z*pBA_&GgVUfX0gvFv=0o^Z% zD#h%V&%Q53)YRl)IU!rwA|gRypdyuifaB%|_ZT-h=9uJBhle#)6Lx3UmSwIjN#9N~ zkqqd_kDL#+O2P6Z2;~S*Zyc%S%zvb*qC`KQ|aX~SUlS#ubk@K~>&OGB|wq`K_ItYJC z>o}zt{$My4{zxnyA7D(*Vx8fSA`O4oqGv#Nj0uB`@Ml~O_2Y&>amwC|d=L^lzuS;( zSvHYPU|J~KW#WXVMKaJYbMH%S>nF&d5j>cVY9RZ~8P4MU;A7L2qnX)AIOWJDA8c|4J*sH= zMAmXu)vqz>-E=qgU0|ZM+CFl9Y-^8Iz-+lo5M}VUNe>^cVf)G#V@8xZcZ9V3FiL_q zWKy>v#1iJ*x&AbM?vQS;7&6QqZDrVA|L0FcS_lQPHdlfY{_| z86Y5;QWJPfbj$!xSQ;g;0x4qZ`h{0t<^)K*IUU2f+5a*W^^#zopw?J5S6ro>J)Pu6 zIr%OjgYmG`k{fg24U6B|wr;NsgP8OpKp;q%dSu}IQOHJD=*QZ0B@0w7APYAH=0lPktSvpchFX+7AbmMHl0A%+S%58RHLKCujN$3 zL_~ctF8uzZ-ME-|MQX#b9<+ohgMj}H^uX0-r%_&P5{|hBX_I0Z@vHV)9t8UZ0k2+;al zJ3n{l=R#W)rvW0d>56yujb@sf5Uon0OnHfS!vKpy?vlDjth+6V7QuPz)jAX(3p|id^-ODv!vM%@_z41zXSRmB)cBT`ZMcsdA}FAeowf52d>{s zUBA1o-?dr&#!_VcHai=wSHF{@-+h)?Tp#Iqt?YTfZA}Lv^j&5sL4@3Wbe2OR9nyx_ z$5bJK)ET~5wm~>#3)HMGLeT*`NFwNf7d#Hv96-|0qMo1w+K=a8(}|`z)HpH}Y&pbX z3z`V^kPU$&dt=9($)mGt)Vu|%frF~_F~jUbJ9gu#if};3e#O;Ahjn-o*j1o88ps}; zlqMeh69P=zLk|KF=40D26gHeU)2OKSuz6aP30*AFS$jrXI*b6|>=mup-_EY!ZTbEt zne&$H52{)$XJTRhRJ!i|5Lt&kqAMkNv0krxMbua`Pedu1>Em&$#*b%YV_alod|3d7 z=~&j@t~@w*ayK4}W;D5zpvPPl*!|xmOxiR3iFDDs`hhLX*TP5^Kr;2UQIVaJzkJ6} zHvWIyy?c-)SAFN1kNc{+x2kTpO0CiZ$a~cT)zFO^TbAS&YbrsA7GSK{@oW&W^9QjI zu|&532_(W1>m9WL+jx0tfLY5%fGn6bFWbVrgb}D`kg>){wy?p2jUR1{0UO2^Mu29) z)_%UcMX1%KpRp!k+c^<#_`Tc(9oDV(pr60KsvhbSyfu6T+;|IPOui#{z z+xOo6joI5QB>m15e?HNKV#va>F^Q+Da*y_~%Q>e?Kh}B1 zdbYjQv!d_29;tz=@!8&D5br>JyyG~ncsD54;~h0RJ2g={hg^58PM5SRd`~+`tSq#drIIcKVYCIU;)j5xfbhy<<6^7n0V8-1k=&}EcfY2ikSozY* zgr0^PAqN9?7T`QG+_)~lErz!7U5qEg=8jZcohQZ}skpLU`qI38y8xjAtt%x%9IP** zX}9KL(2)bslu*wJaQ2^)Qcmzz6r?yg2LOlt6{q6lY5bMh$g|88_KyX@J7G?`jvA`M(kwo_2A!j_7{*mhoa`-4^4Cn1Q{YB{Mc8qjhn?Or zGoCMwpW-&X+Fl@0DZSVbBOP&y^~NIfc*L&9Bv1>#-P?-J41P%geMEhHfs`+U-N3`K zHm=B-`-oxR8N*0vWfGt$|Cz$-kqx})Arj<=*eEzkZODa_7<*jWCN`ZX4xz0o1_;@` zSXvd`np-Re@=ziMoA46MM_RxRTj3614Z|Jsg$g50?twQl=+e+zS60EG$nZ3BEcP|W zgzZdNDAsF|<78C(l@`&dO&df*T5di^LwYt(ay&B0acv~Isv&nmi7%wrTQvGE@_9(P zm(OvJG8KaCMw^J~D;i0{9Sc^J`yVJsTf+0hJBA`{We>_FWT76Lkp_fGy{fg6qPac? zk~(@YRD^FzcU}#HUlfj(d;eUqF9VxbA?6#H#L}mMNkqk4FAk^~uUkxbDa$Og^2mVZ zIuGa+Pnk4XCZ%7;2x<*+VtokX|k8v{PC!D20 zce%f-(^s5S6@n5fePmj9OuEVc-X|cgXXMMM41dch_+ePwa@Hv zTX8nmIbL`^$r#W~NXC!_F=u92QNl)2lyjdJ-4_5Ln+wpLX*Lq8%?0FwXtp*XqLH9O zNY`vm#KL>{Nx8~!FaevhfORY~s7;8q%5b1^jaTU*x0oh2 z85Zs5Gw7O_Oer(U*oI~$Dr{)(F&WL*V%Wh@iZ(HUQYMHYc^1rsJgcFmALsB4oNv{T z4A}26O|9rh63j;|#E^`$stFa} zEYkcgtS3Hr1S}$g`o1`1T~Mk9y9c2-!y%OdIID)tghSSA4yh<>ujc%)$?#+cxo2*{ zG~|~aBdu0PDY-@=k7%GgqSasvG9g)&O{i=lYdo@sK1?Q*7|+>6x}y-nUC(1x5~eWY zco4FQ9+@bNgsfGQ5HgdT26Bv+9k1p|+3X7?6a1=;>N!3T94lHjSvJtJ_yI9Lkoae& zRui&Te1esF{$mvJj4Es5jtJ?I_fiou>k(^Gt%MvHjn6h}k{(oui&RU-6r{rv)5e)` z|K7{9vuDMr=*gq;~`e7 zF*&`HJhUoFh~IP`D~gLeh$2nBgc${SoT_q^dBjfnd_f`k6_bR(ds|qGu#nJ~kEp4$ zj)#bHATar=tIopnY+a7ypeJ8WFZyzN^5yjQCpdGn^3Ig-zB3hmRWW++U>+YhXb%_M z6S?8ul(C$S8@97MQx;hB*-3vEn1{)Om}lIXu+N^zK0a5;-1fmUso%`%PN|K1Q_;8j z6#C3x1~h!XSCfj1feE7AsVD{tzxZtX5?EZf2eN~gI!$G|2KI12eGT$5hB_2=!u_aZ z7u9|ElI)LDL{XF%c&_#I9wmFb!|=GH9b1z!s>`cbZzmM4QXfq5eVSCR38$<=9fF@? zhyhvTbmYo0%625kDC%%PsY6dkDH}GWKC_g|tM5)O3P+u$<%zqK1L3ICw0!83;hyF4 zu@2guEM1n$-8z z*~RRRp#5doEK}=N0LuZnEj3(f0DM}-1S$F_4Ntd&s&234~x`2~)>m-vpv@7=oAtLeroQaR5pe7QPYj=GJN@+2&^ z;xwj}n7c$E7sQ}bs=zPePqGe4O!c^$FM&X~LI*ShYEk$cUq$+*^n!C*VonwnlO?5y zFVg4kK;VI}SG*#wFGlZ2M(>N!`}=LzNV<|j!s;|BnUDw$uADyAP-voO z&h@IasU)bwT2mv%5z`$==+WBFnH;LAC7APza?!h5F9%e@qFlwl-I>XHTqm}uuS&iF zApBOw<(x28KmlQD7#fz;VptMX0+u}qMN>f=28@HNL}}AfxCvN|4yu|6(=Axegs+q; zr)M`g>_vCu)Pje=;X$lY7A$slR$xoyapPMkF@@LOe214*L2h_j7%_XFUQ^!w0Y^8( z^6FGNFa{ipe1wMuyQbuSC3B8xjxIr#N$x-ep}z| zavVxa^)tZfLUbt8Q79c9Es;J|Id)5rLh0yeiDfZKICxnU#D^Fdhz^5PyY*(Wh%*U0rIy06K*EW8(y-5LBMtD$@cw}Hj<6nnyC+%{&laKzUa3!Y56V|7 z&K!Hs2Ec#RqwoGXIEGE|(<@u8jL!HB6A4aho4FHR!g=pBrj~Fs5}}eHZ?RCLlH~1K zNlrM^#SbMHj#EqWa3Ct1_v%2@ClWya^G^{n0+QuJzb^VLRYN7q(=GOBa9)AB1R=yD zSh#aeLzLzI>B#8?r;+8UWcjd`|wTyBkeR6($}OzG4&#e3=0*Tj1u z6(F3Jj}j_66&_XyWKU_-X*^78R8pgsXw+vr23hBH)F86Fq0M-(O#@R;P7mqSjI?-q zNM~|-hzxOwo{^5!f~w2G@D*#Ld}~i2NRU)(av#8B)m=!Fn;`wO#{Lo(2Ts=GXMuY; zY2SQ%ul&<&_%mw*C$uzj*}~vWH%l6@Ahrl;tA*sLzw$HR`24T_@#|i9*NvAVY-fL8 zJ@-54c1a5DO(G+7)PwR!QS(+91MG;~Pie7&^zZzs&Yq+}VVba^eOodo-g%12mZaA$ zrt4&|8;j&eqa&W0QLuUEEtlqFXEODeDOYgQQmZWE~iMaAXvqt>{De`kV}6crU10@IO6Q4oyM_F$Kst3HA?ROot7-B!=HW69H&~? z2bGb8TP9l6-7e2jJO|OK%nSg4Z>s_wV3SKbA{j_A@oUqUarLnX}&D03^s#ja%RSZkMTYZ_1G{GPYuV4aN zWgTj0dq_mPqhg(x$wffgxWYnusXaW#b-B&Oa#a-<%=ZxbPz7NKVU+ANQ&rZcCzG)k zra0P9Uk2CkBYrFxs}{g5IwlZe6w&dN&49^z5%<6AREL1R<^=unRs@}Q=un6sGM|(< z>;g}H+wa`=TVMLihrja_`MCN|{o?!o?K>5sl;CPK0Y?u;Dezb55wc3A9r}%3xp#lqcdZM5?=Tk zQ~;k5StA`?_Bpye!f%9;0)SH0lNM(yzLggH6yHjVbF`bBCb9%V5N6(Z2%#$g(OuYP z%#@hC5-p|z@$V%CE^!7N$@3-YaGzuKm1fNp0T0(hN06hJb~s(`@oW{8!zoi=K54M( z=-@T=tc2N?@(8-2Yizitu60A#VgOg+DY}RZ2_hT_@Y^f7bz#ds$9))N3=sOx0YZHs zw=8QjC7(%W0s)!>YNG_N9Mdc!sPkNcP(0pqs*Z5MkG+zLz#SPafRG*nB8SKDiv0+; z8)5MOE2BTIpI0(T$Em%{iR3EOqLl|I@U)3dq)e{pkX=56o~?JPZ>S4hWA(B7hv=7P zg@sINBal!!Vk58RAaCk=Q{EcRPonn5O$tF>k@&yMc5Zvi`0QVZzfP6UXDnyG2M~pv z&i+`-)G6OP)AECB!Uw}M{UER?jRRNga>LUXcrOeFE-C&+9ck`_A;d0l^e~{R!xwrU+R_ zWLwEPT94j|b$KV&@lGh9wbd;+n*~p$rx4o`Pu#J-Xxwv)5)7HP`U??vDfbQl#ORgZ z%^v$;x_Hqx4;l|^XBYNjkI9-6xHU!XBoW&S6G%5!RXwNj_`F=Yf{l!8v?#rk;|$>8 zODB}@U}vib^qE^6WK3KRk8?#4!?=hjoYJOD@)F@A2tsYsiuO3qUW8fz2P=|lXCu@& zH01Es>R?^dI7Ax@lqK0zE|+N2j+^}dEFCM1;9HewV}=imyo;JeT&(6v>`dzJ=6o(e zH(J?3>d7C)Z&_Vh)~#D~qlUzN>?i*1TEwZeRC?;G{(6V0N}_2b!8w5#BRnHd_dzbm zHVh9N+3XXek zz9dWl>edvfr)znVF~%5`fgB*sLKZM(%M$2L+@1$A56aIxD8arS6dtfRDD+nx6#Y;& zTI|8#W>KSa@ib;>pNtuXrH32amK-^t)X*Z_FDdjb;OtC;e7Zrv1Ol*kvfB6fark zph<92I1HW33guppke(UjRffa7<$76xDgLr|NM{u*2fTeG!S_`Dd2gG=7SVBrI%SE} zvEc_gpr77nDA?g|u$#zIv}@g14I2cAw1axT^n-&525=`+;l0bTdGBX*66X6^>S@MN#a=W$(g^{*|Awg_J<1C1YD(&RMM}$JE(Hp$w&%lhHocLsv)h) z6|Lv!7S#(q)b(BwhQpFaD%CE0uJmFFeHZ8PWx){5*wrPraK&^Bq4@*(3op&D)z=5| z=Utk=Fx)*?8&CS#)ry+=?x=P>_uY*6RD-y5Hv6wz6@rF=*eXN5l_ zvPRz5uxX8&LN_pTKv<&2Dzq*~8Mdpj+nT`c^ypfSicsBU(0PshfO9stX#y@dV)@Dx zT;^akf!_qC6F3X@6<4&%Q;~V#OlTjKZH}QU+A2YIH`Ee22k#Ahi!(#)P_1hA9HEZz z!Ku8*(Bywi&F0nXEIpE!u$n=Ox81Nl67P*jK%x1OkUAUJ)6&++b_hH#6zbPf1C#Ww zbPj7uK)qY|yw=(lI+B8d^sZc$is#c$hQwo&+7>?q-UyBH=i{2d318W@D0n z!=GBdxrSb!=!mFXQj%Y?e<+S1rn4D@EI3qrpJ%M~EW#aYJ@<#ZLT0ev?hke`<;=)_ zc5o8)gBvcO9TK#f^QG>~IXTlrT^*MyPaWM!#yxrD@mOg>O0ZJVS|%sJ4cIEsTBe{v za)Oy&`~Y+(p-8H2CMd~krmUGatz{}qby}Vm3xOloBRXPAst>|-dfsUlWx0LW{5IXM;t9@ zET~+{X&)dLcQ;6h3186-&1d|vOU2H{*F0C<>Z~i}J6S%l`ypcQ7lw4*4MP}sJqKyv zvT7p`UF_M2fstc~*DR4V@T9M&g%J7|`WwlzC9pvn+Nd;xjxibJLdlu(cv)- z-^kIymZ*~I6G$IDFZe{{*#|=fN`;`Dcm3oGm7rEGfKOE5Au#3{Y?(eFWfcHS08HT1 zG}FMG05HCp0bt_sdhGle;4lD9+Dk7$QLtd#f{g3wjq(XVsK}%#fMAWNX`J5bwACh6 z14s7u6FtX0PxS=uRdFwV5)#xOjgg{QGTsYO@Nq>rOg(ya4Yp*@(*)B6uWq)(&Zg6x zLGy_p+b*JQmbCb&JYXw<06mYLsbM}6DhS_%>g~tGKkucW+5nYyAPa0R?#EpKfUa;< zgXzPcx3lyoZPl_Saj8{{^uLS!1nK1?Tgwp^kj$pjvZiF&8XIRm6G%dZpgEDs-RKRo zh?X{0;GudZ3kXY14&#|sFTh&msB zK)BvEyXsMXPTtKVz038f;#}vKJ!tL4lzRkEkA_!uOwxoNSBqT`dvRna`?~MdxM9=y z3|~^b>(%3drQ&!RI_NxfIw&O0k7rrdG{r;K^xUFPj|W9ycaL!fM@77!V?;vLEQ@y@H~{1(j{0cQ4{?dpmLds`u5pC4Jn`Y*FD zBjdU_GKgYgMyv)Nt~wUkw;BK$q;X`#XY0OKdRQzYKN$TP*`7-hLht)OPr?~*6ZvW%mtb1dwl?sIx$e9rPQ_>b{(x5o* zC=lZ6G)Ip5j=3A#t5YAXIyyBTRM;L&e*`;P1`eh^80ZnlMO89z<^zGQWF<_|SLQvt z2Z^V#`31lVCV{~NeIT?VuU7OSf}k*f@e7QlY2KgE2g?j%k(C;<#y}6=FVmolW}(v- zR|B2E1vAhI!<;SdVNyI$$V_qM6@!x?pCSy=38Y;095d4$#2Tu}fmuiF^n@@7yVhf^ zNS?&7Kp3Jw0aNCeK$(Un>oyG6&~8=pq+J~;LjNY!8BhS$P+})V zG%QvL`p*fjDS#N#Y%<*msJG8;I4) zxk!%{5GM3UUOh(D9|^uf{zMXD zb4LiElH=Wk+$vL!DZvz^fT%cES$|meG>L#<3k$6>)buMnVt<+VTw7Z($C`egD3>LC zrL8UOA#g?dYAkD=C0r__IkXqm0pIr6Ae-fU9$CO~9gf#n*F6nFwsB~J{&LAH!?>{9?gBysCm3yGsBmm9i4c8polUd$)I)}Ex z+oB0B!39;F_YWs*v;|f888b!Y)lGeLp5AE_)c8@q`XKy{A9$vR$C+02L8=c_39Zy0 zgx~Q4&#`$OKS=aJ=mH;H9J=H(u``^IolLi-vHF{*7c}>r>*|l(^)Q@qHu)&j6+cS# zQTFV~NA5lmGQo-jjH;zjSNte>I!MXX(xst$v8C`)L*FXE(LbtWSn<2qSonMz9P{ui z)c?tM5gg(3_}z35Y0qG!m*Km|K^ahj%6Lc-g?w6pI#9q9C*{V0IL0Z!g-Q8!d|C0C zVW>DLK}f2&dRo(0tbL~UD$Zz&%*8_oBRO6&PmZo_#01XBp<0o+8hfU9kK*>FPw)5R zXQ5>Q$K^-7)n}9rpBcp3bZYjq8bpBzM-dA3XN)GaMwivvfdH{MCVd@8v;eGF(wz@r zkC0t}Q!E+5s;VPURWfuig6M}r_eMVSR>Kpp4V7wm!bFk2bcU(;O0|rD?;KF7(fO;) zUj;ZqdwiuH;hrOXN^Q}^EC%>Wz^p*dYk#G}Gd)!HQYx$)l4sh(@YN&jVfd<|k)|GA zC8-(Vu@gpyY}5cV4{wCrDcCiLkQ2kebd)&OBVF<`zlL!tHzMu-k9AFX7Hg`gF4V+F zb8T_zT3CJ2wACBX9T%X*JbXe{s}XNctIV1j?{n07XTo~mDpF+ z_N?h{0nJctEo0R)jLM}wJ3igBr%%^4HN;4L3KcA^h#^+;HlQyeV*)4`wHgcEtOi>T zedJ430Z2Wh$(KA=|7UvpKTO*PE*h+-k!1?ijJ1(vsb47)25m$w zSL)Z5SQpaTQ4+b@XDiAV$S!{lq9=LIbu5hR_g}Y>t}5eW`6i;7juChoa^~RW>1D(? z!?uTvmDI|3hCow-6R9Upqt{r#4EZvm=*o#vLdx7zEkW+=Wc*XXqxy5j@p3;Fz1w2l z+)uv(?jQagYtU4tUMc3qYs5j>cp2+EBmH3;L)#x|EqB~zQ;WrB7O(BH3^_eXhsR;@ z8o5bcytc4(ZF(7Uy2YftUWN=vbPRO{2Gsmy8M1$F>)Gj+A$#ds7eED2&83r7gNITy zJi$~Xuhhv;brq*kf&k!9dI-(wSK(iz^=p9u`yogTNqgiG=0KEmQ|-e_jaPWdxHh@S zci;$)YXIT$yF4qMDoQMoWr3f^w9Z6U&sLMGXevv3ApROLr22Rh?Qx+T2 zPkKFY(yCW!XG(k3F0aFznZN9kHFZu+PhPfHgXzNhxnQDZwygofs17P_IgX>!a!D8{ zpB|OC&ZF`~C+rRwDnT>H;f3@y!HAT91MBD*9adG#cvLMaU;?bEYDE#Ah^g8uq({-J z+HN#fyUR|WJ^VG07(3yGGI?=uo#2FneLRY?Zkdm}fhMPTXX4Gp#ev8CnE7xcs} zdR9nnEmwXNM(R$UV^w$|>&oz}EL@V_jvpxS2(;KZ!Ao3=ASV)?%ZKkAAsmKMr0ZFl zFaf7*T#K2U&v?rx9AD3qG!fdFn3uox8~N~S1LQTaRxLoF5*D}k-SB3%W+M`=j_Ra? zM^^DC?u-?OhGr|1Oi^_eLPQ^UafOe3riW8}OlcE~&Bnu5K~3C6cJ{N#&Ty64c}n~S zc78<6+(_s2Pnb|Q;4x@h$ccE-kalTdRxAi6B=ufgE#Cz80J-C}Fi5$2t>`Wl&WU5> z&n|`MTHmd(HfQ!JFG>H!iBnhQK2na}cDNkn!jgFX_Ymu@c4mJTvp-`EBoC>EVYrYq zs$b+?>vDCtJh%V3jKHC$FohxsZxikLw#O}9(9n55ENJWOd}>>zMp}r2gt1 zKb!-TP}kM<)9<@3;1TM2?jxwnD=X<&I@_=37D@j*Ex?+~tlELaBjgSRE4z6q8+{qZEu-uy>k*BosdodK;I!!@RRYSqzGzIZn zhJxFtDM&hOD0uiZ1zB$p3SM@af~K$etqNy}S8&X9Z(*3Y* z|1Ky3_G5)H!mZ3-GET%i`E`i;@|S+lYlJUYeDj(;ezUds<`3I`v$^=@o2lPujpkfC zpGo{idu`3VIo~g|2667iieD&?d+tT<7ZUfgFOJ3k%Hj0@>84kV4D1n9ouCpeP~pV>90!g5$W{BVBVIHS@Rms{7~5e3C% zJBT7!UfTP`yq$Z4U@20)yXLsRpZN?425k;+D8F@B~U zHommnEkBbqzO;NU&u@H(7!RWPmwvGEy}?kvW>4cwNY}O`TK%V1MnsF^{N5eAqOyR23|M!}a}hlk#i7 zyp2b*RgOm7ELu!D1J}&bWpIE44z)XaMaaWPd{wQbKJ)ipoc%2rU{6(|1wz^k5X14TIrO zU@}LR4~BQA9SoqO17|f3hv@R*3ZG#(w9O);T_`Nn6$j(Z%tT>A8#G?D#Z+OS&odhX zHLukXO#{EfUV0O-0stRV0gzs@cp}h4wz&X6Oiww~ma`~5psv`z%}5P2 z8#?xgVW)n<*fi?8=(P~3uH(+rApX{3M(0*a>c}seJ0F4u|E2va;|@!;*>4P*dpNzW z=$t?NB2o!CgJ2eeBMPC%L&@rq#COVN>Ryy4m#6S4%qJ0m3`1HXNyU*Zbt$901PPgn zHI|+puH8kUpQUH3aZD`2QNWTV9f7s9w1!lJ_GnewQ|l#sDO#8UxkwpJFqORzWG_lv zm#4BeAj-~>gv__16;JF6o1-pvQrMj9Nh5;20;pM`-O&mPtyrQ*CBd_4jRt>-`J~a{ ztXYi)-ZUTN_;|Eg3vHH5o8?;0#-O4$lTOkSDHP~Lo00M@ZAKEQ9tUj(gobbK3~vg# zG*ZgdgHgLuEa+;fd8#B>P(DU#MY0?c3_3#ug@@5SPLa-X`{Cg;?Lmw!5uIo+m4DN; z_h{WsXfK}9NY_MrTIdzDfoLx^?U6(&+G{QItjJ?p(Oy&7p;4DEchoFWL7*lUfoPS3 zS2$u`UX)%Cs0k0?qXRYN)%kCt*aj6|gsR2n6&C>0VwoxQGac4pVG7|eSZ)d71tY&m zIAG@vVc~pj>;T;4fCHU3u^ffX3PFE)#~bAfWL5#+3wfU4k_IOOg*D1i0vP=MKJ53$ zP(%H}#o6+XtQcPySduSlU&s}X)eK!hzC2cUYNuoQvcJee?YNXVwgf+$a4d^}Qqg3B zI39Z>`2juz!UwsqoMf8|Y`g#R6fIL^N0J{5f}P+1J%A{J0>4;-5=Y*5JIe(W)D?Yo zkYlwHf2jbXR}v>)GFp+=63KI6EqUxB->q~bWoff4gPXm@#TbmuSYu~RAfGZQ(S1|n zX)RMLW7~v^KUqmF)4SMN;EL@IWEV@!bGNM(q2zVD4lkz*a#;ZOrt;}j6;=IUy{dw{ zSj8e_h142+;_EpWHSs|%A4anTeN{?48a_CsDZ!G-2*Ffzor0M|XB3Pw2}nB9#f=V0 z@iBXe4Bx4Y*$|@FhHBxf<7M{-tqzyTfVy4Mi#K%AL7WdQbKlkTA@bgw0|K+TOGw`H z6kbDQ)FWYB>TF^ z5+Vgxj~()1v$K<9LVHKg=TNz7O61?9&amqiZ^mua)MtB2_J`IfVk>LFhTB#j*h!s` z98P7)xPK)&ha}}^uqKewn&?TxSXh%)&;@o%;p|C))>C1O;Ymsw{WGf_wD?`-heRWZg14I0a0G&uW0y1WYx2 zBDBcM3}7PZljexKs~Zf?9d8$F{gYC6G!w@Rq)-cuQom@AQb~lyy&CInB&3HU@QMM6 zGGsw}r~85FF%UlaK7sJd8~dOXHMybAL8b9y$aUE~o%EzX&@y3wltZ|?I0=yEZ1`pw zmw>xWQJ{YScv~5C2wBh|TYq|s@mz{ZlZky?-gD^z?J7=^Z28V`%ao?PCEO;^m4xL! zbighfir2a;_z1#o;(%_+-lt?>&=v1Onrsmi4YCn{P>-}Ebikdb_HhSV|MVYC=9g{= zLT?l8K&utrSf-(3L0W3l#zNR_Tk>c`bpm^{kO72}97KSVGm1||UaH!m{bg2E+|?lI zKRssu_242p#Qq~8`md(7`;XPe@CnX?R2e0%Av-CGOO!D=fZhLAEA1jKM?jR(Q)>8g zEHm3u-6DZe8mNX9#7$Z9Sb?k+Wx}t<+O=h(bONvW^$s8{96ZuY;}w~-oEK|p!wzF~ zqEl_Wq*eL_7BPDVXhVFy4vSK`P>9WrXhDRidYI&ByerDl&b=$GE_oP0XZS;--ZI96 z;RBEaqTv&Oievk3nMS3Td(7wHGTOu{3frLRHQ*#6-i+4l!6)Xsq*c1@<#6poiH_Zt zNf}nthP|*b0_cVY)CzrLZzuH)87_>uJfDm-OAk|}$?h_q17b&jw>r5-yh{#w#R>cj zoZyYW{A*@2-sGwxiP4Be(THS!;weL*5i3Eo*|4InEOd@OyK}Nn735{*iZ?!qvP_U@ zs<=CRUFSTY+`qPVS~f!yl7_M@k|1Y9(Z>zl^r~V$bTWLSfRw0WO2Uwh753kiLgym> znq4Ba#V-5t9GYE_|CRGq&1!pYv%OY8j3xBF$&V5e06@8kve2_S?IzNcIn6pEfF`Uy zcSUXYGj>Dg(=Kx4Hqs0EVp1>nU&B^9zW0t_@xCY7(*Jbkc?ZaMWSGxjz$$9olPrS{ zI4_6Z`pxYEDxA6W$WTd%>mbsiW*Z<(GUu(-wQ#PFC;a zzB}5&B(Pnh4S)0L(8dV`GiXbv(3Z}l%`Y3!)-eA8ZO)CGLK~Z?Pou5jBc^l}+M3?h zXnSiX%sH^gmnh=$qRUgTsZ2=d4Otvea%eIWXJgcHM+h?xK_B))?VsZ;ASn!5JN>6t5hp%L+G7b{DINGg=u} z0LfAo+-MMJ$+GbBt8&{JLw+hyZc64ds+l41d@=-pe}Heo2n)vXirD{uOx_A%v+ z@%B&rR<#{UIHFFJd1O-lU@}lYmjM@NK{OO)#YJ5UUYEM2-t>~z{u@aX`ZwwSjvaS9 z8)`3$5uQ{=Re>(29L&_b*#?em)|Q7=STkl?eVAZtSvZ55~Qj zTtIvk{c7MGCm0}5jFvkuOdRqNw5p96Z1U(&6?to4wYZ&Kqmzba4<*d7Pb$cGbhM^Q zHc7A5FSUvxV>R4kYPoj)h%>uti1MzY!WE?jHVsj|4N*DuHuQCFl<^_CRR!A_TsHg` z6EC%L{%j9$B&-1G6U;Z8munwfYP*ar|>9PyaRQv5HyBdcRulU#LGXPs6yxDtmGrg%+Ykx2I!oNzS#g|tJ}$9oCkd_oaQJR<7$@KXl3AC&j~eJ1y8*a-uo z5fKAoyJtz53gcN3`V!a3relH#y9bK25pTo`EPq!le~DieD{|59CVwOKsG2yyWg=qH zI}oj(CRhX#x+|lIr2Jefjh+S#p(cO|Ez8|Njfc;hT0222jjlOyY^O|yAMK#n+me}$#lTrs zKH%_;R@qx1GM#QLi#UKr;YswbqRRZi8J|-(e{gjFeS7#YMKqOc7N}WyPeAF)L-C!s5*Xh!0r{l}THs8JVES2U+t*H&8)J@}EQOnkI% z!p9{iS|EFbNsGx|(?af0+*Y67I@8P%VwtfR8I^=Ki1b>TFduf%L)BwpDTl~mj|*Hq z3>mA^F-5disIc1D4^HW!%7bYQBeG*EcYTXL<2-Kf*BF2remITX()8MBvRO)1xJE#a zw80g!-F^3D+3vo>d(Q^RdW&U$kTJ-LZ|QHeW9Aw;pM@60llLl?a`*db`ySoh+W{)>94&kr?o#i-=K*STYJuvxN8ZC= zknw6eJ4wT$tKnCi3DrQ0azOoOU=_Wk_c~G!GfAuRu_P*gk#@t^TcbBtG3jP=Wl|cA zABK^{wolr#xf>$~(8l8TS0>OdwSN~(#NrRQIAekS-x=xu9jnryQ&4W`z5pa}&va4` zh2@#9=;306D++bMdHnBiN5JHofC`=O<;vNooO%okVWXeR^?t68;`$)UOvhGzk1NaD z%iGDe<5<%2A%1i4Xn8N+5$rEd^7}Dd@8_(Bv$e4lA>{HT*P?1SH&tgrbPyUDDn5cK zq>WLEbG#HyV7VKMCfL<$pk8GlK3ZhECDFYTj+ht}=V%Gdc*7qs!<4)h#pZWF%evkk zukVW2Tk`@1CesVSu3Jt4;^4!5@F!jPEUC1g)hPy}e5cq~j5LMZh~0o}RGw~V$>D~( zv8`AdV&X{h7SJfIcZ;r;xy8QW`|>eqNB87Kp{`UtKRO+3=Ub?I~_=3%A&T@36@0UR89Xr@bprdv`x=)`_^7xYx_v zV_}da^>>{9lqi zPpCVPJ%FBht|WL?-kf36a@82W=iw~r#`9}w_FNCgoe)Wis$UZX<-ugGR7MjAldsX8 zpexTcbzaR!=bBfQ1Y6a>6|yvuDvBDZfU`%Qiha?y`ta<_*q?^M_x?*|;>~2V{Om3@S} zfOqU%k6UJ3K@OXYc@9BWe24O9*7FGZ+5VMO_UQ=JPwM)X`!XeFrziE}t@oj$0QY|c zsMccQhgLuz{kSB%gHmEiP=NVyh<+)(o7;<+XUO?();HFo85%6htOOl}V!m4EPfN9t zs?jhiQa&V!*O1HNF2E}PIwsEn+R~%7LT8oKrYdiAdbvnUjxHc&B^=!p4gmDQPhJ(^bDD_f^~W4~r^*z| z(K(<{*rtEtGT|rA4K`)a-U&lStwiPS@P}AXfR|^FN~*8e7V7tiMn_3!Cr5)o(44Gz zV)$;WNC2}<5Fm@&Y*naQjh4)+ESXiG;|6?z z7eV{sa#eN+6F_op8wDMD0P=ODcHbak*= zv>`^Pyf2wJ%qqL8z)ENA^(GHk?YIb-q+dccl}qMe@=D2{Q2Rqpz)*j_lhqHuUO$u> z6HA_|AO6|oA%|nh&fBNONuzz*XR&Ey!H_wW+^bw2gXDYoAHr} zNMa4h^)8!A$m0iN`ERb++QkGbZ-I5XL7dvzt|eYr^kcanblzuXOJ^PSiczaEVJdCk z#3dm?4eKQsLgPJ*(K{skS$f@g3%Y@zzmq(Jzv(lsTT6>A);xGARy1;4Uh8k*ma=ff z%WW!kWU5|j9rtU?s9*cVSFc*2I9X!RL{=7tV2Wr7U^|%na`bH2G<+xS3Um{ z&EFM$C-0KmmBT8nGH#8D%D@18NI(Z$G^m)Hx|GXL3ezipepItuV3u<3#SOKmJdAq@Wb67TTA(V zwOrNo+ejT2LNS{FAcKx1XYr5|1@_2HTP-(UD(U$zbcD_xy_cZtiv3mkUxZc5FBJzD zd(<={p>UJMfaP4A99~8q1QMJZc&(7ZYoW`RCM)p<*4l{NvY=Kc=@qOo zS%Zn%sHc7cm&yXm?tzR95co~qIw;GA18gos_=T05T*BKNS6GusUOSHyil1u~}3@>I~ z=!G6Gw55j)H6BWShjqIlNI&ikzuLvZ2%H7REqEvG2^DZ#61WW=5gos{Ho_L=bLIIy zi9ENe%tq`V&AO#q9@KTU=D3H@IS@56{ch|i){@~SfzK!;zX`sEU68P3=0E9n1XEKv z^vO4+Cn~VAqwcBnhw)(ZjQg*0FBiA&AK?B3k&4)*TQv!c~RpoJ;WRK5IWaI6pCH(iVjfIAG-kj0S&GPI~{3iXlDgJn^e!M#V zc(s1eZ5Ml$et10F+)Oq44uTakQ{6bv{RzGc^W1Cec`m^*$v3=5HPmAFw7d)~CessL zB9uXoplE*LlI+z%kL1^0nxBYjgovfI(6#z=eVpck{ucu0|M1n1e+`rN1>DlaOCX5K zlkShoFsuC%KABx-wJ)jJ=mnM-Fv4pltaaiHI5Eaq)y+`D?9fGE^K;tGYEHX(D9NM~ zW$RUQT7^rt;e~2W8@QsH(>|CBx(Aap>9@))^iDI{*8u5yCVN6Zs+sI7^aBXLQddtp zX?|S_DhXcbb?YZ#C%=>!V|c7Oni_X&mh6wh;QlK ztx@sB?pEQmS^0r$A<1?$2ue z(q4!t>yxpZW@7qH1(N~jgDYWTy5OP-3^JL8!5~Zd>kzZFP~G=pb-xvJ&}iY#u4U*j z1nwu^-Fil9#WHc+@7~ZW{7tw8(q?3!$WV4acyG!7XisuTsFxi#Jg=GHMW;lIJ$+7_0>c@X_us-QyyMh_;B z2rmu3V7v;%MB;9AsKEwTxWdG;l-?0ydL#=4XZThdu_L0dw~N3?f%K!MAzs0L5f8*H z0kb5wx=Luj2u&`Ls=q1b{gu0!mh4=HA{6Nme)^p;!UV1kz zzCU_+QF?#q@IM3L9jSmZ*+UjY*aQ-S{`{=(pCFRCl;CirIY^sV(?l|ZWL_)w!fLaTOzDd6Kk3er0$L3k|DR3b-4fwE zOH}^|xjaWBGP@*yrF+#z5TEsQgN)-LF*PkKa&B~(Xlx)QJHwyqE}v;QK{?Jel%s7) z%(9ur&{!rL&tVXWQ$;cNzi4b1K0CYr#WyZf6w`;d$)l^lVeomcmcPYI+)3dBM=|9g zakJ;75=K_Ik&cXEKw-il2l(6p?jsGvsCQxaQFwAU_p1sM3%$#_-jTkfBP|R>+KboY9Zca1~;p8A|xEVN{mk=UACka!H@kzZJjPRZl#bb(B z1S77)IK*uA4kZS=^jTP_;ZrLa@9s`|J>13A65Z#>w#4 zCSW)f!JrW-ab2R}y_y>CGL1h-i5iaYtHM9BE*2|pg@Q4qhsAbFqA4&C>~0OgO}&|i z1Vk{k`Y#Vlky$IOm_ZbVm=s}Cn(&FN4bZ})@k07pk$J7ZtvkZ{ntFxp@tRgZD;RAv zs(;~W`la4InsxhSPu)s`%P4_7nS27v7JH4Hd~~`QH{V%XvSemW(a3f1&+v{THQ46r zIBCdQZ9h7j%l2`SnYFfl)TfXSK9B&N{YRtT1ay;hko8Wlm$cH%DXw0WFW&>=M=Scq z-J|%!h;lu1O-o5w0;8M_G&?sdUZV*3n!P;)D@#>2&CsJ>c!a1W{tpm% z1nexwEMrs6N7-l=dO@a-v;c?)oHL>$NZ591B|}(n5@N!7ksQ1ibQ8xssB>@K9?3G# zMBC9lJ;!uvjaStVRHv4HbYx9&{%%0ysvdRqh<>ofgYF7>fuSOLl>JioBCd#PO8_!{ z73O&7@C{;L`vZf16o`Z%M3KUy7!c?)s}^A-*Xk4iuXG<_B^|+Dnyalghgjj|wvs5g z93QWgn=cwMAt}#x774<9o7Ws0z6q_xvX)U&q*iIU5_oO|+dz>x z-6$3KGUK-92a`4(XZKuV88@q0!F+;gA)JW_!t-9>pULxz6^u?sFS0gPorXn6MDd-- z3ai@Wz^uSB8?j0+Cdztc6thWXzfQQo2RXY&2Fc(6tiYNEja??~BJZD9LB)gI%dgEB zYn*2G(F&SWX$HmK0~xL}(F1p8%XHj}a3p7BM7RAF;JcnZIn$Q{?o=s5Xd8jnn{V~# zG|uQmoR!(qsbFc+-3+in6maII3qV_99QcaMR{dId)%W3bFTB2B$!pkw8Kej|G+77+ zBfxE@G^n|Y4CFg=4#pNcPzqw;KB1rNs)}QP1Epv@)k;?pypK1>g$Q7R?1|BL%KjH(v*ah&>edI@I87lzfbSabyX0Py4sr7vf9FJK#F4{0ar zp>4?x2_WtUEK8BL0vTLdqn5fiC^kf^E{%b#GF&92+Qc_hpFFMrm8V#zs;WZ;Y>%q1 zc`S-X#*3yiVT!kUgOt!4o)3zl<&&FG=z&!&Kv$(9y)pDmIl z*|ZxH@+IY>?MC`MSe4VKaWSjJo{*is9ITAH6680+L9e?d{V{rtUK1hs9jmGtY_UR0 z%wOiIVg~=3O^_+VYQEs-8vq+)37bJG}8xM}MDIZfY^@`_`uje#89~Ap|N?F0OV-B%SL8v1Juu`0rHC_pg zA@6EPw2D3Mh}xkO_2^s0*$vMJUg+U=(A`(AwelUS3g(9@9VwC8;b)D)Fl+^x#puL2 z)3B|qtoXbFDs0A*{3$A1hms)9u&h+J5*on@g5KMfiVC7v?D3t3q6I*5JnpH?B zL~ptSlAh8jkuq9OHk>eh0)s`NNd_5}0mzvSRK^-&+|brrn{pHu#ZFml-MTBa#a3)+ zda@xYAOsb3<1hZUG9evaLu&uvCcKOg8R zWCTzhkV`|4}*ZzzIe1bRGYjOIl9f}*P&@| zd8c?&t4416Or)KeOuS%Vy6 ziF80uB|NUw_8nSQj;Rx{ppmO{;h`pq`~ws!Y}hkGbE+;C#Y(prFqkODiJ;aIGW;B| zq36@KWYifv4Q4Ggs$s62cC;(gv_+?)gr1NUdy;sJ)qrr4$c$v-FnnVdS>r|Y*jW71 z;}PIOHnZ!H1Y^;a&>##e^@|*D=_+LNIm#{{zAjXNA);~sjzaNytV%B|4J6Dn8gqldR=x7~VcfyMEzT!$2G%^uOUHFZQ6oYO)_ zV(;l7^VyH`sgF2Qoz=vU)bY^I9-ckjL#Clx5zPfBLdnjF z{NK)YERFXt;p`WCp&;lB14_pI#%PTnYsI?kGC5{PS}@B4199AX35z=(b3@T$ul{3v z!_#-NzThR}uAX+T!vLX5p5B^|yDwp$!PD+_g~I%t5ZJl~`%ZP9r6PFXkZNUi{V^!o zMntPPEB-7x>I|ED92>2PDJXsi-m$WEJ;|ln4$SH)B9=+ilD_L*DiT5c$S%Wq37K_v z03+5Sd{ee=80!cq_NhC;e=@~}hX<=bg(G?%eps}e-+=I!dDgp%4QXQP>-lW8t3#fr zK6?_M@w;_B-XGGo<<@If)#!Y0{&=uX06qlgusT9t} zR@4#wg4Aqmc|h0SfJNWj_MWI}5-FnK>ijm(3=ZLm!75#wG260y3htC>J9UGi`azw!0JUKFb)KJo0ux)oh(O)J|8Ps_Av18{2F%F{Y5 z9YYV9A2pBYC)if3V-A{!vDnMvDJ09}nl6Lh4CLv-fpXDh z588(=d5zKzP$hQZ5l|OWjGhos(c~C%3sYXI?S=Mb#}cF|oJ z=hlce9Ry%uY8f0ou#@K%@(~yGA|T&HYoUZ{6Y@=)7D^TJVH~}%sD)sRcRPsaNsaf3 z5@1}lFwNCzHrWU1xjJoFL`fPZv!T<5MUPp8?7iX@+tddR_UsC!!ydvmOpm zw$wM28O}VE%T&9=2Z6)1NNq$E?gEl26oN!C2y$nF!gOAbn{t6ig+d0Sz)3Si{Ja4o zeqKRDhH04bLJsP*NKO+V$sVh_N*M;fdox5V=H?-yqrT-t?7y~?uE#LqYIAm*=uzmd z{;5xz@UC~-?SxohOH3y>P?$PKv%sv3FezC zij?VSBxMYG!NH*i8WI6il))TMI07PyfbgP_pL{Xj;kaLNmpUiC(Y0Nik2JMC*eX95qW5SI=Jq#>d;#tIXSs+}0lViKw-Ru0JU1SyKu(%do_ zX*@Kl(L(aJSX4vun*2t)P?AWI6~`r9EJm{^Hf0|=IN{eZnziuS_MxL$m3_$2W$DHa zSXe8fOP`p4stY_4RdEr~Nl*o%;|rvBkX$Ce*@D=N>KQJ1o1sE9{vVMk7vn&t2L>SQ zP@_7J0+gzTBX$pwX)0vX8@xclN02KT1q>_5;^%FEY}@8<1zFq7o3+iXVW|Lw<5Bqa zR{dK2p1h70_XSH{PaqnaG;MkA5MgQ$g{l-i} z8e4=jY!b2}LPiWe0y()&MU$;75ead+Whq7<;vR-Us983}Oqiw}rDG-x^dZ07{vvxS z68QpA3#22K_5(rFGAqLjmYHOG0~AJUOud!uDJu!b?O&w4kcELbppG)_D^n(F4m)ic z*}nhDA4vB}1)d;w+Pp(_a0{X#=qzVKtFwepb-^X6%PFxwFL9#LQ zhs<6j$nk>Hdp5*?0)L^)n2-=#l1c&CmKTv8D1Im@lscnAfLp}N9exg=t~->UI_%6l zgCT+@>}kukw;BQ&Pz8HiDFVy5Ft*gO0xN|zDBF@8RHe%3E9c_r&q4h;42YIy+mE3; z(p%}iQ{P}15u%QvL{*r12({{=>AeRW#nGxc7Kq(--f-xA@l+b;|yqopOYtF4U% z(%@Ys;g`p0x#}G=3!O|MrIp5=0y@Yz`>i_l?f@e9I12$?%Iygj3*ckB0CHBK63u|L zKY`nZnM04t2X6&H-W>R&S=bJv0bJTj`wP&TtUiWtf3+gq8)7Ue|Fuc^Q)g2CyOZ({ z)a8Sj?h_bj7h}Zq!ETuS^1**dhi^j{6CDx(IcS6qLu=IAGYl`&Yd&ldix5oPWnak# zxMCtKGp8y_=ILQ218cZG8KD* z;qgtwl83bH4l0JF`7qN3Il~2iuJc;uTket`qC6Jl?Ce+i9_*tabcYDSDAXM}wM?^h z7xF4~M;Dp2=#Hgs%(--jzySM9yxcbPFWQz-DOz&BTIGlCOx?#XX?WD}HC^9-XS$sr zs!mxG2!PTJtnGted?v9_rK2%g&k6(~@Ci5^7|RWWUY|iye&s8<(1b}5IY8w~oo*he zj?)FxLX#q$hzyF*mmDUg%Vy*Qc7drD*?azoH~|je9H|LSL(l#RltFaV-%T{hXGm{& z8aXZLi775|y;<;rB|E$mmjT4#Pv@3#O_ikXjrc&Ks)}7KK6MBaXmzg(=Z9Fmu?M@f zkZ?j4%=ffC&vnPfXK4nrk7pf3$CaaVIy+FoIcPf$O#0L}^YSylos@syDnI@2^I@{p zBH1$oPWtD}kz(^o;Xuf#`7`hjsasn<)>N_XxFEK-@x4RnV=0A5tI53?8JtP+S#6I6&kdjCbb28DP3Erfjrr$Ky({*2~)&X zy>z2;qS)+K|FC&Eza`5|;TGTyG5kx%|gkn+LKJu}uJyxp= z1%ip`ugCzs24xE9umBO`aXQEYoG6}<^fcsgimF0{D3mRuR&y1+y1L*eG9ZB*ASOXN zD?tq~5-8YGtQ=g+dnz7&ieJa*KK8g~>w-IwkMo{YH$yl@!E|`qh8l?H@1}k-} zX7pjObD$|#yGJ^fjp#;QKG!yzG=p$huu)NbfO1o2BiqRV`0C5V05H5I@; z(XgCWfMVs75?N=i`g+rxiwDJ3Fr?Ug&t`vJ}C4jFuPTRC|W;XmkyVAe( zoS)?%zq*A2N4(T(`<{s=0>g`X8?`@V8%Upqu|#7pC?-a=+kC3podmdrt*2F9`R}tz zXe@aeCZKep{QK9phDS!JjR}oxP|ZHIx1~j|XQRTAM*0VAi`LTSltX5NJ~MMk@2lPO z=uN#--y`n*GMq1(({Ze&*DKI%yQY+&ey0(E7WW3Him^{?WN$ug!!nF-`13;RylSp= za-6C$UCKlsP)Iba!UkzaaHlDL!gQyOE zR9kIuJK1W3N)S_2;-?T4?>J0_EghCYhyvf!f|Mu_rMxX7rX+B!SKA~s)e}FAj4%m` z=7x+7EdHT7YL5iIP#fZ_xcX43E6tXfp(8v5za1*JeFKMrp!+hJ_a_tCAvPW)H3`_D z7jdg0$e2Jr{P0sqwC<5TrSvoQ?Bbu)VXr);DG}7{tdu3Z$Wf(%C9;NuE z#o0WiJx1W4D#T$}n$Qs!aHJ(5HVboIDZNoIB6f1r1v)NTJJxod0@04_0!~S>#zXr_ z8?tdUs_$H(rD|OmPK(ughRS`cjJtY<8un2pcSfKfd0U{+(NyF}S2%7uzz!Sg0+eU( zjCG!3Nlb2680heIxrAhfK}jySy{j#Z9?`_OBju;5mo;f|972`tG<c|PMS(mJGoh2;?84%k#9ynomGkjr# zm7P(&8Z4FHhm|K1G1!(>mL{BEOCol(n@A$;lX{llAc>qc4aEA_U{%`2TaRmyc7n`ej4I1oj*8p6P=Cw%&hlH-!6^g_UNJ6MpH4U*Vi=4r2<>LsC9va*p%B zc%%A^=fCr|G`zuo+Sd~5M7zL55a;}Q_})}|AQ}}vbzg9YYJLy%UyMg{_=~a`pfr9B z-_qUnjGdTscXR=!W!GzNLr)wZ6^}Zaowr$H_i_XOFw92=CGZ`iV6P!fq zv4lN_jQJ`=zgiY#ign2_n3iKY5{#2tGjitwXw;;lJ;cuZ;!yIqaqFb4{5B_qv07E; zjdyAvw8Z1tRSmJjgURD+*j+FMJ5{i)Kh+LbAObAxQV-5zi84N^+_SqBp4$WpglY4J zxhmprQO{Y!j-og8&eXBc^*aUEgNa$X;JPUqlIW4#*aixM|N0vs}OGzL%f6?;g|hM z{|{U2?+^^brFrkb-D1F`C2Ii?NL(Wv(6llM^c(h-%B5PFzWccl5G}Y6#=3wD1_nWE zaSr}@MPG?s>(@Y+Bka@7bsJ!pKReQ5Y@HzDu6Dk^xhU%p~5*R%TNCpNk6?U(PA zqjpcf{Od2~+zk8WxBFZ-`sJ^^Q4iMp<*W3?TEG0lhf;0^{qjHGk9jfZ_sjqIZ53hh z#b>^wo0Wd~AAHm6mtP+9pxZBhLCtjf$lKepZ)WOezRLpY8m zJWYkuV7bBFSu$>dO1Uxzl!nbr;^FDc0h}nN9<~m+rHkaF<85^p!@{#=*uoX`57 zwhppZ*o1|yvdLmof{ko~d#7*^X3)sUTqyP8Qu@>Ehq4@$0e%YP&O?HZ&` zO6qDJ6`s&Hs)1Y{=$Tr6cBOpx+fw3E-Gu2x-Q|{YH4I##LLj>m;mI1F;E6J5vu4mb zi%$KR`&>(Rcl*3*NSG00bVd@neiQnTLwsdyDDohN8ae zb(MVMx1T24OsyLl~qn zL0EqZVOj=QBP=WS?1He33SriwE5+sl!hm`}*;tX9S)>sSnMRsEpCCkgLVyiXsRU{x z?9F;lSBAtIU}pv4%kc_H9+S~3bAS}LqGoTFGa&KO!TDslnuVru#YyaB`d+zqHgvWi zG$6tW)2D-T6xT1u2=l6jk}gU%pDQmZ>z=#fG4ezrUlC|lvIuA*u^c}RZDa`i$X6{5 z+F1(O^^9RkoiOiIE-0Y|PyoessWt4_t>j=t0xBdU_(kfOe<^?0BNGMk(c8L8u{uY+ zgx-+zWl}?f>}4&g#8cJIcA5qaSffPs0uwA%;UX)KD3XW%CrlKFoI|-IGXj=G0OMv; zjdNh!*GDx@|0}YS>p!_i>ymfbL z%bXNt0Zm{mvoOv_OOHbtY56TgJ1-6;S^4$qHs|)rHB7APEA9jxM1X5l(sTVT*7zt7 zKh*i>RYfy(ezSVoD*uw|Q6*LNoKzI6&&#%epJUc7@B9T*P5oU}X*L;2K3_iv9;$wh zxz{o?>ThYyZ6vN$Jz{4X&*g-`A|J~=ftU4=Jbt+(nFW}#my{kvG&JHG536R0hgHsc zR|{2CoSi>nNs(EvJaXIxznxyCD(bSwBm0CVz4fCE%72Y%AnFgqmQ^?BS6tapm>?km0dLg2M z=|wFHh0~wP^de-%Sw0if3kFv}QdX2sKI0ukr>{Ir^#SuslRb?({;Z@Wh8N{pis>eb z2yW9YI8@VacEt!b*m|_V;)sX_<^eiBV6A+@@%22F4QR-!5E@-ua%l!2U{{a$4s5A| z(+D%D)F``iYPXrG_umSe{>Xfho?|>tUqEJBbs*)ue3Pe}GBPYdF>ngf?Jy*6U?Bq% zbPo-zAnK8zdbdZ|Rkt$b_h!h#@g6SIl2qiTsh+k>;{%(o&c|YTgtVRYmrR&VYrAv} zTq!o21l{9oW_{a3v5VsD(UAF~QP62FEsQGFj@6-A37NgJSD1+&mjyzqJv(7or;S!@ zb%K?Rz-CBOHbeL4wEDC*1|NCVLAwp~3+QDW!9Z)k8@S zeUVuX)CLa-HzAPIE;(Q_z_VvEAe&tF4&b<9ydpB#V9=}*6B+2;hRHzbeh>f;rU{_+ z^tBBD%zQ*xgd|yr5;F2w*=q{m=aw2^wkZQOqzTs;_8KU*jw1(N<)Q(>yiRDfqFw8q zH`r2=CGrh}J-_~?aGW(iu(*N16uV(b>ai!6^|nmzHUnq}gAHGQF^B_@g$>J1(Jy-- zY^X9^QVW)VN>3~SPZhj)%`5V82rTasu>VJPN`b`hqf>Y*5}2i)Dcf8=7g_)wvc6^} zY!a69rid4UxDF6d5;l>xf?ncOi5O#FB*AoGgen-V%Wx4mWf#hsqSp20O8D}u$rJjd zy7tzZFH=pJmr_bXtw>UTwq(2p92>7jHG6h|RkrT1qyo`v#;_$7v8-Y(VpuY2RziVc zc|e)A3&U$uwjL&6#PAvkHWF9ZY)T)65)<`gAU6co$1d|$=x*AAU9U{9KpSP}_&UO# zA!;5gB2C%&!&dIWX)71kM-3asmV4@}q6o^!5#Rk!si*57SS#QCIXu5ioirJabprQn zdA*$Vn2R~^Yf>jpshrYWk_A#xSb{m$+q-gRExyL*rH8Y!dtw=DZl;Y#7OHh+EvYzp zACSr^9YCyQToOD-A#&8T*9ZaE!DM}doV!zk8WbrcYD}#WD^#`oFXo?!Y?~WX27tAC zyI7ORZi^)rd@t=0WrE12I%~B3L1fEs)7M&$?PweXx>Khz^uC7fF&T#ALA#2@Ya+*T9sc_X=JryPf$*iy$srke=>*dqW;B}hIFSir_dM)6Aq7ll zg0=guY)A~LVt!};+CnB8SvyWeEE9EXAG+;`NEg*Y_sr+<%F(KPj1)tIQq$RFh4K-OGnxABYJa zXP3w0{7OzYy?dPAVI+=u=d$IPr(>6)-@GkQydab%CY-ceUOu7+bd7s)aFt}w9l(is z${0)``!kd2mGu98$|lqc?4DOUp?B+JE9r0N{(zpt^Im@aiUJE5B}=Ug|JSZmtAFR)u=eY;~F z!$3S$-K-xjbTe9Oo!CvqI}QVMxaMI0lUr%e7C5s6Bi+I&P6pVpO*3FvD|m9{J;-(- zGEaH(S~;gUsu>`>F`j-X+F)`#^GwQ(hxyz?_6q>@_%1Q<@@J!(nV0iGY^k{omW}R2 zGurIKy#XWzkc3h6Ez`kHbH`{eU^}LXU|%7~t-wkcPA1@SW=T-1bQ4yel&Pqyhmp>x z6#Jnq>Y#95K1LoL{U)%14s;cXH5DxBbCp>|%7Lv-!7M>9{F4%vrf~8!l8dej`A9?8 zk10w0nd={E6YelQEV7e$kN()s{x*Imm>ajL`YT~bg_>6&B}12mc0OjhE{_<5-KOhh zG77>m3o0D-2hUdBn!Xn8gGi9^@%10?u1x)xPTimOHgSoJzj-X%;@bXy*n9tIyQ(VB z_nfoOJ@@y`NeB?RsQaFZ8YCz+o(+iAqu6OJq086$#;8B)k9zOb>(^tvYA#hns;GMY z(fzokDNPAVlmHRZR$39FM5P2ZD(V#?M2Q;Ps8JDO88sFuO$kbnbn!mlIoIBM?ei-k zKL9PG-2LP1z4rPs*IaXc=Z`hs8e=toKr#S^rI&I5Js;!1f;+{51$Tl2{A8K~!!<5; z!Ki2?5bDM4U~ZT4ymh19>jY{IE#xt8A%w&z$q+-Ya>}L$n@2lvBg+J+WcCYhxIA09 zJ<;%MP?V=|L}af~z;Q>Cj>IGzA!@DX7%bsGf@0F7)WmF5NlohNm?n6GkxdHaz9yy| z@gX&$mk(*}(r`H+;u#TsbdwvlG>Q)~iC0-)bm$qM;K`a(;6v&LOnu&Vb}6(z;tEGC zZ$4s>xwK>piwW4s|0}wF_BCaB+!Tv&$|kOm3@|$n`(4Ox8Fb+DxHlTa5<`dLt zB_|SO{w3jd_PY#r{m&KR20>-5zseSM#XcFX8kpaMe#xIhrRQquuW%^VbNO5O&lCeo z5+zcd1x%YDM)B*3T`l`7V$k}%UX&h}*Su73MmQQ1)VV~ zSElv3f`=71o!T_Y!8UBPiiVT(u(-N4AxD}i$kaA%ozjp5L}|=Eo4b!yMh7XPq_b)} ze=|BKbaWu5q%$#?n9%v2UBon@SmpsVg+W6!)x&|GB`bR|D`33c(?MbpcM*>!;np%S zNG<6WhY+#;=2LFe{>Nq6K~e<>nu$1_@%<){ib)U%UkDNsBgg}pNT}`J)iM25(98_& z`1>Z1(xSHAL@?U-*(Yu+Q&ksR4 z8EstT3Xl~y(yzFdB*{Djj%&((Xs(5f} zWnnl_iDOqF8|b8Yg)%>IcBxLKuBaqIcg50=T!P|BO1x5X#vv+_aJp4vy1y`swM?pZ z2}cvVke=18(WS3BiAgxf!y3Dql;Kro>0sWYN#Z_T7!alu`bx~DVACBudW}6AG>VA;aJNDqgaNHk`n^|Au&u;9xCX;sM zcM@V(t`~Go1-69a?Hr|tk{-O4vAc68aWJQreX@buTlQv!k)GiLu*j%oI}_dhQH|TO z;bz;KQRRt?@#Z0!>MQHQae-sD2_!KuT|X{zQ{%ePA8Onjj$6a=PL3JBZ*4X%%02rm z?_BE95H8L}m=t;v!>FkV=>lEqPm?HhW~i+eu*T<^>c1X9b5!&(8r%&>N4xbkCo0xZ%EJm2zMFiQhWY534xf$^U%6B89`617G~ar|y0Gw?F(n z+DOhK{d$TY&W?Wl2O_(dN7vuy=@fIqXttWUcXho*n{696rt;{Tt3<4C~@;K-s{v%U@AnW1rhzv+sp( z$xnFnl0F@?iaMG5A=wDE%L+1K8L5pn;4!@k9Zh{vUxk+nSFhInVz2uvsqZ6E-4FEE z9lYcZt$t%v?+Un5%Wmr0alaBvB9&iV`*+2y3-Vj%7q?dDx6UqZrTMMr7q^z@w@xW;*;bRo>+%=H z!+)ap)t7jhfyc8RaiYAWBb@|uPomZDh-2d0GpYpTd<$O8zOf;#e0m$Me(h?WFoXZn zfpk_i7V0!g6W-_uC3iGqfajV+yvqfMDQ>CeHXV$8Qj+k~oBC77inton)t?#GE}({| zQ9RIgf#>A1*1QxK2P;AyOx(i?{qZ6=!C03UVQYW!_N0f+l7NaLvhTjb;(=|?GEEBe zgHxauv%Brd)!=yslta1ZYQ5e9ocsAx6N)(NM8L4g_fkY4>K*X#lHy_850ZzWnGtt*qIU4$k>1vHQ3~p;INF-RA)N7(oi;jPJsk3 zyEJs{RLUNX>P*Z%{HBh-jJ#;}1f5Np>UdruF4IdQPtvRPGhfCKrWdiHO?IZ!=|vjV znV!|SAtUHZ7};heO2{ZuuXX*y!j)28+`jYb(#vHnl|G@YWu=B`>oN>9-E|zXI-cn2 zv2Vz;wR%3rl}@V;ZBM5S8rZngUg^Vh=*spJjky;%t!YmBNI_N%Y^TY@)69YPWJ7bx zX!_{s0cbgl9#`PRA`{&geX(0cG5q(wa^1`?-8kT3UE-#AfGWE>X1+hjm zpN?dVhyi~l`{k^-F3X?Mx^!L~sHax@zu-q>>5E^U;I5aR_3|X;u3Jx!NIm~`6 zec{WI|Hjf6yc~^Vto?9(u;gKDAJlJx-2&)pzT#_D)OxK{jFlf*6xRdX^-u8GAkL5E zJ_w2IhTK^5ZV8WTO?YhFN!G9Iz*`z7DxSvq55u_vfF2Cz*delSgmYW2F04I|<*E)? zcstuT|Ew{W42mZsY7E#SkF&eIXh^^Ntl4Up6-twT>ANdxy<+#8hE#;xr5R>BfJ|mn zQj~qI;U&*9=}o30itsERQamlE**57f{3c}%edfHzW*q_1H*u6u{0X)G=1sDT3Y%;w zg7;HG**0yet4An{c5=xUJl@v#3=1ec>XuTNg~8?{5{dIZA_pJz=voQ#KYq|hC-l6f zu{-HCdYfp(6%4P@Kd!SLsbP!Aeh|(>ji#TLKI*B_!C%yjYE`3$!}-asQ9h5>LqKc( zPJI;S(FVsnhEQ~#afuCYxRLU^nrE! zM|d=@s!6u)>owEwUds7jf89T}iu1>J`+3UwKZkQf-t5QWT$T7#;Px2baJ=VQcM@nOVy=qOZ#-R!_Va6ORNiUF(tej&h;6DSl+S$|)SqU_Wz*t8J}I z+Z!lWTg9`K>rvk8dXzg|k9Jtm%`b?MSNTNiz<4Wgcx=)3vI53_k(;tm%w?D&^kC>qIhvCXKg0zSL?tO?@8qQ&sJNpN6WP`m|K-o!wRY z@Goi>POomeHB4Yt?(eFTd70G?0xA}qZ<&fTAlUh+nJ`2RIc{s=RA3GkEK_q3heb0A zI1ZP(jnbr8J>C$Y89cF&D3_z5a$u@S=9DxlB9)}cA5$=)Rz7l9$R^)ZmKBlla(Q23 zB$at`k(7I+vJFEv-Z5kj&bYq z$`Tc)YB0ijvoDb~`QR*s^FU9Qs7LixQ8{SUSQ8fkb_ncDRwk{$-@MP+mx}soIIk47 zqr0ehG1wW3+M%KzUs9|IkNRmSNP$?5Ymrnd1Z34)eMbOa4ONP{7{fJ=#a`En_1tcm&BzA#REHBQ$&ui$TQ^;5BsH~MK9 zd(9@?auy{0Sv^Ui#ag5W9v(eE*$cSJ{k^vO>?NaF01|E0GN!Yc9j0?2vER^^Kw`gN zY2Cx647}GtHf}yt-rQZ>{91W)M{)DM^5$K|&3=q-h!}nwzVad6#b(>f@FXILPgjdY zI6dt`HFdr&WrEdwAoiz4pC=cQR>-2(di5l3`-CpQW&vhBzAJ5|)5bdWn1PALwYI~l zOyMAlle5n3nqUpstf}x$zo@-e7ckvhbv(Gvq4&Ea9brniN5=!}>SjbRk%=ciqnnhu z6BcY*n{lc25trJ*6XKkzL-yT{QNKw3>wX$YUJC?X9EXg|C4G^xJdpgOko=yQM+d{B)ad5% z0r+Ugz^fO$vKIdRr&m#}+S$qCNauyc&HtFbAbsKg{i@6LlhCe3iMiIvaWkpvSXV>Y zo534u9j@$zG;VyByo53}j0+o5-8w|uGZ@$%%yv*CTr1$f3ga!6X zlg_6M2QCULO$`E|74AAovdI|}s%C;vrF4O)i!(!oDn@9djgac zgUp2>_V(x;Da#Q5yE=91*Pv6^KhvGsE;>~cvW*j_VGTy7PO%T(RZb54~olabqj`z^%ctocZR?tFZ5}Qh=j83PjCb6l4P8<1L&5y+7Fq>3M zuitUitx_v>2V#53AvW8-86T;Et9gHkN zIS8A%MlK<9%{3BO-pGHTg9tw$f;$qE1_c`b@;*P;(uY_noIo(+mx4h0Nr{<1-a)=Y z6Fl(&zo%9Dmo(N~9hF@XI6r*$Dmj=);Jo#0`&#${nM@>b9*hLe13}nB$E0h7M3z#x73F)SP>eb zr^+=lql8Ee5C2SDWdJJI7j#{p+jYIF>pJC{3jMJk{sghXl6WOLK%;!{pj?6;NYbT< z8Oub-Gwq+`a+9T?QIyNnrIR-O`BRmZgxvMWN(fl=6B{t$GO4$JQ0wPCB#CKTOXeJ# zHj9Y)=W-(tru*?CvFXWdUoB_TiU=@Y)n7k0Om1mIA_xir%Hq`F##c&flU`M>yG!` z@xz^)KHdehW?#O^k$~+`wXoMO2d?}PT^m;xmaklvW{kY|rn)$-uu`}7 z#Nf+EV&GpsY6gynnX&Kvfqfrv_8sx+w2N_yH^VsFeh7SB+?AV()J?Jr;G6rC^i){f za`Da4_JO0~o46V}_}GtcQo)hz0%x1&96i?*qLbC7+3ruW)${H54Yp+WCu|qZo`!jT zT$C|TM#Io^lrmZb2+9aFVY1nTZw15RGXMz8&2T20y+f<>TK>yrvyFErpz%shn`GelI*H``jaD(#Ggu@SQQE2LdyC z0A{opGo!_m#f+X7e7Q3arTHboF?Kcsuo2`^AS65GT=Pjbp0R@Q8uKbJalc$sWitajkN+W4v} zB5M||5DfeU{dk6+!zoA*B+KlEa8!nEU9Szt|KgWd_~9}?{3q2;5gR0D5QlH!uHXJA zDoJ1MHGjE)>opNE1?tI~W#GCSoMfvD@S)YcNm-5|UN;a!+&ms6;%v+KrMw@6;_Bz- zGjhe%^~H&SDtLe2EcYpHT+$mYGl2Qo!XWQJ^T1%d7zDIile(oIWI&O#W};;)Rvq2z?qXqvPqgQSW%wGCE#J z-Sr$4$&d0Ep2C$*Fsth7wRAc>#u`#YQMWD-4_fFm2H-NxiV4W+WJ=Rd6U#fX>+urS zV;ta&@l2*mm{Xc){Z`~+Rm8S!%b=~xu@8!2Cj0KO@E%*2AGoJnmv@KrurA8)B3_rd zH1~#GCtzvb_K15wXlcG9oNH;mEu4ocur%{k^Mu$nUat7D6I#U+;*rmLv2sQ`5YEN- z_JwnO;(>4;K7khrpD-T@J|VCP`@Tib4B!U4#*a1x$QBKj1ovX#JChEeXz*A77{uyA zwi){;s}oB@;G5AJChbGaCGgF#P%Rpe#`+hQv!iA5y2q=5Kv+M1-~qgnIpMJy$JFf4f_ zkz>hY8C8+kqFP#Ks30LKxP!nYSOzE3wqL1bJ{yAj#F$Jow$vc?j|sy;m+>KngEtU(n4U-E8Eq_OJ+W58h&p6SIJJGHfPl?kztEzDN z9(4SU|KZ$S==j!f9!O2-c+B0i``%nPnESJmc5}T(+_k?NhQG#r`q9)ej%Y}x5pjKw z?r-CX16=R~$iZQMgV|?I>F%hpA z6WQ*tVsydnq}j^t_S)0kJYDggkb?rv3*k}{olDUl3OBnwmIX;{hCkzI;kHn&Ojkf- z&BgtZ%Ti(|^?L-eH*;~n;+&xP4&KbyXZ3aN25FzcwlG}Sk9|3UR-8_#zS#7T9Np7H zLONlPwTo5Og|$CsBG^ty7FWqbg4Pliq=bQ>!+HS zd;B!aOW`;eOLj$z=gzQr?qu=2JzhL-KPijnW9lv!NDdS(i%*NrfjT;9$?xYbDD71; z*GUMZ=5xWnCh`#)^k9A}aMT<%)s|I5k!mE6UZu`^wOT{lQ~h zvv6>1A&0n-O@ zO*vv>g+kLk*{ZH`7dd)6F-&kVw77t6k3rQH&e|)ujGN#xD#68N80~C!^nwe!V^&q& zv0T+1?IXAxLDdBoE>+!8klj+TWz(H(Wpu4%B^Om|cqGF&HUuhN zFDl*jHjnC*4FAP&uE~CPI1dv_fkESh(L@XR_OOs|XCdDbFXY;c{lteZ+$7n~7xMK% z-dSC{ro6efxcR2?=AmNAf94jzXO$fAE8B}FT8v=xwK*aH=0+2tXRXxXxn2kUls%2* zzN5c;5WeR@u>O=}l?Dqs=F4;vY#0E-F2C&3uwo*HnXH)G2WywHsf`KhKRzK*gsKDX z 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

kuEGZv?s!fK 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 !u!9hNCB=4wYIB?S(8WDwMnIBrO~ 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 LkSzvW$?^XHl?|>V literal 1947360 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

o)RS6v;|J(QyC^IJ@HF_f*d*jAT^vW$mw* z)g2DzPF1%hP#ux4y0&0-I(M)8TDLR3bsd4~huPC zZ?HPuy3@Ya4WzejAW$8Vuewvg>U8V2*eO8eZc}hNP`NuFsE){2-AJ%H-MYiR)*VQ1 zUBP4iQ9bR!pgJO7b<2X) z>DG;$^;$P3O4(zI^^w7n(QD``;&T$)udk=9DHhj(iYeZk#93QgPYNN&ZzReV;Z)V;S|DY%GZKh~Ry3^kCCGBlHVXEGouvqoxNN^%my(tN7 zhRC;>vfyTPZ%WU5+7#QlMQx_gVzrsk^vx^_Y=+3Unabd1v^H;_^)_?DP7-P}M=VyG zc_TP^sNU2BHbdmw%-Y~)bZ_?iHnZEenQgw!Y)aouLtryRzRffSH=}#A{cW!|uh>aN z_2xy3Rd1dPPByAHErHDt`8Km9xEbA>KHp|~e4FX?ZKgeaGdlyDA@XgeBe)seo5Mb* z?e{rtx6f(Y(k;*(*bI?xGY5m4(Y<-vH>W-2o6{cm&1sLM&uRUE%@FxEGZ5U2?#*uB zoVLw3*=+JnHXG6>o1wsFhg^Ox0!{(&FJ1d=$q5-^UZ1R`8M-*`ew=kn<4UTraZVA ztxc`ZX;nU_Rrs7%n(nm9z-EYi`}}G)<2$g{z4?&CueE{dhWF-;?!7{*n|yw+w}w+QYpu_SRp~|?2yBMP*XmPOX!VC3?+2WF-;uDL?1D}1dk^|iX#*XqLbR@VhKL*#39 z!xdWnA*a91f$E5St!}wOs~`03F7ET~F5Ww1j=Hn(_}doy=JB?`W{7;P-g$*qf5^F5 zSD-o~U#q*X(CR8*t1Eo1F7@r?iqm&;y@AaT`C8q7g;sya3F)aobws{a4_%?vTYY<( zmwbDf=Y4ybXVUjFBZ1ARtCTnBM@pjKOMC2KD!1ICJmWGodUGV>hEVi7sF(Yb8>0LZ z{>hg^p=9W9%)-#*2ePbh#OVyV4c zyc(ddjh6!SRo;48R3%KUfK34P@IbNzu)iZ>?{Xj^xI_!$sn5IPa?NLCU0FZf$+nyWHCRu6Mb$!D2gtKAIe$aM!C#-rQbZ zbn4sRh;k}J-TE&15Ww6jRX38(5t$pQs+k29iD{QQb+I;GstBTWu}fYO)C!|G9v zMp_ZPIvh@(YcTUiCQsrFT5KPh%BKRA#;dzHj62yFt<%@Yl{eKhOjk7gm+`G~b&_WC zXo>Q5k}iwclXO;Sa^q+^EHtTiG}#xr&qt%Y(0InJjctU+XO6~TLgQ^m<3OPq4UWdW zmZr-L9Np#IvAdjWy3C-E8X0=7M#hm>Bf-}rpE1&XS`G4+3OmTRAloA;_X}$5qbKUn zrgDjA;Bt$tfu|%pDBQcF^|AF$FTbs=*oP&wfx7|T(>Di*yr*vlC}j;?qe~4zoO$p4 zr~BH^T+~G2GFwd#1+`m81&jbrZI@wwk?72JJIv`G+g8S!M|tl?PSLW&w1p{Gx1X`| zhT5~O+#9%&lbbA|_|alF4v6}TWgM&~G6M;qn^plRoEQEUL$h8MJ|PQh0KQ?9r>Bqx zNN);hqL>RGcy)GA;0X{nwvCXFpHPaCRPk|xWPLHC`KbX;iiCKdwXb-~^hN z9HF>3fnHQwbQ9>JCuO`r>!uaL*a@^k7Tyog3rhgL(KT65pvxeA#aVP~;?AOQ&{?F+I1Au&7Lm_clnOcvBE?x! zPb)wxbOE3z&^}>K0nDLg;c~mI7s@-dJWAvpT8osx81X0t&bP3MJf_t7mLUGJl7 zJbJZ{#`97MW^|imdPXA6~!rP0)?{^ zXvuPG^D@Mp@Nq&Vg#$LP$2i*NH2}}%Ylu9XH&QBK^A?Dp%{!%@T7b6sVL*;L|7sVe z4e-Xpa+tV-sOMohOza|Ba86s4W1)jYi_eARNm(M@#zO#I_fdd%K+#L&9c)}6GQ&&O zF08c7DHwC0G6M1qp^xfWavtmX22tg2{wRc&X@h)pY=eB%4x;5^kR+XSj;2@Q=s_P% zRxGV%$&yO358ax$eJC8X4=FSD0r>1giz_24z_r zz*Bw)krCQ*RjV>&lN;I ziPgoAE+|jnZd&o17MPZ5fj>UBz#lgPx2+J#lG|2z0@HC3xXDM;d7&$Obcsh7`e+Ow zYhUoW1kVeN8J(vXA3|TN)vh)JG9S3=8SPR%6NjUjAS~_8fN*vO>|J3k+>dY*o&kp_ z9N38$R#^*=;118i7l}Lz7geQLxCA0-;VP+Tl#<%Q>tOWv2Py!XDF+;VL5=~J67|0z z$AHyD@4hX^fNP09csr!c!?(SN^bGh6K-aV$;Ca1{$QuXSh|JKDwL67r2ADC_2J#J$ zPv{x23(_}0=;LpEfK-_Q@`7?@wy>fQ)(PYKaY6k4B68q4t)ERI` zclb-{>3nsmvDM-%aFfOMHpC~ALlh3$r&{bo?tJzk^4X_4)jkj@_K|uxq)N7JujYLP6tuG$lr zj*GxmKAO%8UFf4nobJg%pB*rOtbN!=<9VSOCeBlg523HsYFC>9nGam`jCQG>iNn!M z5SI34KsY-CwpCjT??ku>&w$+&4p?{)Q|Q^H7vNd=D3NF3AxZ^y;v*123m31n_4H9v z8+Hkdo&gI1nkfK0v{!D(%q3d1SMIwmBr0%c!DU26=VS(~BGPSq6rgKb3Mh1C%ZcuD z^{yi_Lr2zb5~dnp&ZFu;zTxpnJp(pF`Uc3#!2Mc%DYNXbxfZX!9`n#)?^^u*7TZfn zoK)+IZuqd9EwoGzkWY?1Kt5>)$VxFtl1@6`&?{#rA5B&)t!BWsm0};dHF5h;IA|YI zX6ys-*@wtyA4&!71Ce5%Rbn4X8vDR#84CfLSqL!dRmrjffT#RiBA+XWd=h^OO{$?h zfooR%<^`suT443sjH^ryQ=?xFeaZ-2zDguZE?MOXOvgpwVjoTCg&y?j-s^NvcKT=x zAZu^)(Rf~H%;-GD_z?P9t#*}eCYcXh^^A6@o{7WJOc0j#Wn#JmN)>ezvq0~zj+e4|(%lsHoqF(70Ci;nvP?Bcq;lq11_3*jUs-Z83B4+rI z1924{b*{SPjT18GX!0axBiXBP*(v?p(>FtdQ8i;$uI9V2>h^Rs2?+XycdEGib`jrw zyNK_;9c}t%XiBnWZ4D_1;gv2w*Ki>)iZ!Uoly#2Y@$74$~CLdkSB1K|oTq^UdD zbW2=8ik$o;M`&{CXcFYPg1inYPe3YnC|4BKSXV4084s&uxbOT%l7o+#Ct%{db?2DH zAu#pu!Xygp8M;{0_)?j9gsZm3I-wGvUs0l-;95bTUtgkbAkKpSB{KpUY|n4JJ)gg#l;0@&`}BD0yO-MvMoo5<`r^`wx2 zF8xrR5e8_*niL}pS8G>=c=J_qu-ZJ#rHs&Lu`)uB#mWes7AqsPTWpQ+JL8=m=#4f4 zuc;r)2pPr*bW0Q`MNV;&BQ&{mGzm&K0;CvWNQ`ivWK4K^D0n(CO{;tQJ@fQR>C@H} zMF4MlSU}`W59O2!>`p2nj8B%@r&sEwo??Ku#U_BZMXfLm0Aq`GSylr$T`DivSwnQT z)I6cUlb=LBTf|UlCzNN44qB1Ar`S^&(O)Q6R@hN#Y@w{M*dN9n6Uy~5zR@9)0~6|P5vBBQqrveDOTuy+Rh0FNx+1yFhJpe6-G&}-ct+# zJS&_d@~lv>CdCRx5J4+ctg-bBQ&L-DHH@}GDL^yJ0OsmKy(}vMtX?cuSWNWvVzELE zkY)-<(TDB^XsMPw zKDOj>BRNeLZRx(#mW~Teo*Yf*(5@Z=~<4g<6k+J)%?7$*$M zvNk~FE^)#Rq7}Qu3B5$VQ-f?oItAr9VTeYgo*G;#G3u*Rg9{cbSDdw29R?h?Sh?b` z#mW`?Ew-*urv~HNC(s-13V!8gtO+99xPoqp{G`aqPjZANmyRYu>8^kjSB!`&E|H8> zR~#;r2R$Rn{bll?d?dNsVtbk}C0XHy6P#1-p_US1%sXe08?4>^d` z1?9P-n?|I%qGhvp!q{Z7az(wx$`!R1D_2xmtXxrH@wK{w-e_0kjO~gX;|jVZ@{=Mb zKgkiATsoQrrMm)BT+#cCoh$lDMye~ueHmeh!hy?9h0j`7jF53}uDD3#%@sw@rW_oW zK zIxaMMax|S!mmE?gZ+q5CzLSnlSn_TP@87mreOt>+1cM||?;d&qp5#Y~JjsVBWha70 zy?Ype&=(AzDz>MF#p`T6eU#J!FM-jL7Xmc15U@*s<*Q1T6#y!?isW;NR%{i?%ZYrF z^Yyo6HIz3K)T~QPdphMvq37FLp_@^;^V?ricVN{#&~Bib23ieNmS{3iIilV`Yltt6 z*AVnWZ%)1`brnO{Z%WZ2QJ&;DW`Mp_3GA zL$m=rL+l{(4AD)gz@DKOV)fBVRg>8>3`;fb0ImLIfcC?nFy{eg3Mj6#%LbsT-1*^2 zqLuFauz;0(e&D-I$%Rm!A4=*H(^jVVVQZC{0zQk#Efy;qG+L~DP-n3+LXE}N311km z6X=0pgq=`B;eZpGNUnB5 z9l&$KdLqvWEtCp4p$*~#^;Np+g~kazQcXQTJK;D$JE2pUg8*}kFf7YD01wv7m4ZD) z#r1NfV1UTy1of4t^H81>Mrg#^6elb{9Mu<%)YP!#usK*#bHgHwl`H03tXy&VkQ`8P zq-n8r#h1tH3VNemAzzESiYx5bqUe^$Pl}xUBu8j+>1Yy^?g~h8MZt5{74x3^zi>qf zg#$;9RnJ*hlmk3hEG6<>QA4SKE9xNT?pxOINYAkOie;-*QvuMf*bUIGXcA@%z__AE zmNf#}+`C3M676vBA?+aYxk7yr^B|Pxie4J=Y>F$6JYwdD-$wBsi`V?1`L)gOzGgs6~HH84}iVXnmiYj5&0*otKWmzTQ zId{Eb1yQ}b-q1+oa|K`EN^XJj4jkKPMCyU#yr;Ya$4kBo$>)O?lE;1ENK3WilgB<+ zuwUPz$s#S?chb^vp~;h@>3q84kfM0UdOHtv(a{Mj-b>-Yh2&w9sP_&708jCgM4sX! zlnUHaD5y`pMO|8N>lvh^mV7ykmb@6CnKFPmP^gt%4mkXVw|{)!={2Vm0^=S*!;CK8x+(|2!L+Je~{8^gvrdzUXz8 z!Ee9lMOQ>~(&98HAwrWsN0XFvD?o}B8tbhUnn^(Fea08;+j!M|#yX4Lea1El)I79K z-6b^l8GA^mmcIjFes@6KXxu|&ew9GoY3!wxy@vd%K5rO+IHzwozq`O(VH}luIssbj z`3+Y7VPP%-%!n_QWkXOq-ErbMqFwGdv51v?@~cb#Wl$|4@9BdE&RErspoq`C=IMi% z3bmO+x1jCwh30aCI#hVZVzpCPX|eLf6Ba99JZiD>#X}ZbU;H6kAJ@4hUDLjhFSlLA z7xv3-^id2zzMKKbl+YyB(PSm(tM$_DF;Y7#TyDWZjpgPb_xfGmbjh55RuO!>e0GO zP~Hqt@I2=;$|1gs&@Zkuv%=?4dA-HT32Q7?PFP{Fa>7!JtrNaDUMJ84?F9K2+f|%k zzr{vZL~_#NBqt$4_xWg&lI{dZaYE7a)(Hzqz=WMpPT}X9PrSC}l@@cAq4s&}gi3(t zgcU@d6Y3}xa6%)5eh0(qhs@zYyHryJ&`#J7&`xL-W+%W*7Jag;1<>d&H*O}{=q@*Q z6ZxE=zSh5Hs*BJMS*+%V`z=fhMhbULPW3h6@X^X8Z#(fc* z-e_0ISKqGU3j5VJx+U_HBIgQ{BQ&{mGzm&~1*EuQNL+EAWK7r<1urC~y|YSRBrtcW zN?)+9C<1sFp%)N&7op23WnE#eJyk-eXH}jmetfRkhtx|w#Q<%KO#p3+T45Rh#un|e ztOoG%PC0~FL)5ZU4k22Ie73j_TkM4LY|%k0QtwjTw_0Dw(pQ|`Tjd=>ylt_v!U>C& z6^>YJtuXGpRP;bwLB8a56)V^;dC?WooU}O2Nr=$o&(S0$-3pLmh3*&Z1aXiAOxOwo z6s|Nggt5XX$<@1xA%JIvb3~pM3O1xzp$LN4PVxNH$bH5N6&q|l!<5ukSPi4CPzun@ zGJvr{y(}vMw7MTsldgCAqe$w+v)e-x9@XmwAJ)bP4%QlFt=<+bOvW%5z0!WBSF&f|t#tpe{y^ zzT{01!xpOvV$fpcgg%R{6UKcpk{)O$$akQw;spC0D7qq&lNKjA2@$%`N0XFvCqRl5 zY8tH*){=k;JE4)n_Ii;yf@mkX+6gTH&k37}JSTKeDsZ~l4RK1nnQrLfWqkrNDAlwA zv=c4>v=jP-IR!AcDGFb-%X*=X?i42+CFx42AFkvTDQaIp*dXlT1Py_Isu!hKULL;RDPH2HJkG!5XPUw_s zY602_hXL9N?ZR{c%vr^tENcV2y;z*EgJ^iMIH8xw=LEk0lRO3GU1}Pl5zCbmeD^3{ zTWeJQ1S-F3u~PqKiSZvk*+<4We)mnY|CeT&Xx8DS!`64r^a59qwp~;z}NkqE( zkfQ#GsDFu0Pgwn;jVb4p6&tPkB>+$T#YCR^m6QscNz_0*HvgIacQ1Wl_6SW-cR<3%Fx@Uf^V#T6wG0asK>HKP>N zu2=`7T~PthOf|sF2~D!B9I(|r_P&&8n|tiNj>tDBd>U6YLwT-fp%JOBSlDBZ43#V9 zTdZ7h`GDb-D=t{9TyfT7<%;7LU#lzVjdq24J?9wTfB3Y0wxLOMPLd)gKgkhSkV{9C zpmbM2iYwZhtSfesj8s>Q`*D_T3J0z_43cQQr|1QEbH!02Z>|`kRN&}w1mbM|LeWd(qT=F6U9F43a-vZp8~^10$OxS|@$b45*a zx+|93D+kIIOD$HeSZuL!#R7|!E9P3PTye3*IOkejQPpf*pVS738oIV8XB+=RxZ2->|JBU12bW77L*~Ta>(% zZi|{Xy~(1=Vr7d8i>w7@-lVyO4J~ zJy*PKv2w);ij(IhC{ z6_DbJf|so;=DnQmig6!Ulu+2b%6#ago-C?fwyr1#ct0S#l*s#W;TlTu9ZLOpgDzDE zVV=id@QArC)hhK=0JJT31GFuggxLZxw&;;%jez^zK4c@&e76tjAoAHlofI5|@@&yd zD^hJSxWhZ%e9K~Gi$fMGTkNw~*SQr)TZ~XRV2k2S))oZ-&lYouJX@4(O0h*bgt>D4ptVJ< z)Kdu1w%7pBwx|+jEx_zUT4h-!pnShvxn4oEbiZ7=ZY1*UL#ASjEl{2<+Gs^p%H@dO zcJFe;8|}s-$_lSrtgNuzVr7L_EVfn{_vHwBpsg@;V64RE}zqRx6 z`c?J;+R_$V&mbkW6_&$jD-;7XQwA_+q_wiF2+-i}Z7m>r!QI=cB=T9|2CT3a%DWy> zM=OG_Y~`b9HWx;hY1Z}sOz3a=PxZya0N8;!KI zO*EvRPD6SqGzoDuy-b%DQlzbX#lCo>nhph}y@nT{*HJj|4Tx5 zb&9qzugIrNU@Uh)*q>3cW4TXiX#!|v&jR#V?h&RRV8-&OEb9g|yK9RFh+cNr7Key@ z%BmUn5|lTV3pVo=T_vpV+Twu|=8YO^D&KR$yir4q>m3%WseH4=b}Cn=qFVe98`rd2 zC*-EF#lOjjPxD1(QsGo42||-IN0W$j@gYV0qRn<(FQn5!@vq@68s!uYd>5j2vlYJ* z;En4QMBccrqf|itMu;~3jfzLC{OwXt6+p|sAE4!L6=o;E?A7~ZSqtFYt1_@R6P*kI*&kkj}!qsk1QbaJW@_6JNKJsnkpdzR~qZ3nqq*q$R>ccNUbmp05e0h%d#541m63q(GPsGEg5p}YgX4jPg6)Z`YhEh$bYf(TqNsMunw8K$6i!fF`pgi?TJmH~_t>Sb98V1fG?jm1O@zRLHUsmNk~i7iBIIZM0tt=Ev+<$>)SG;)G>Tz20u4a%*DR zKDFEM9S_zQGtj-`!T*#&{$a<1G)YVQ#j&ORqLG%iiH7vkX-E%+CLxZdm+8_%inKLb z?eXARIuw+aFM+%7N%JLe_dV&b?|ahvoQ5C7p>W_(znyGpX*-i@UWN(Bz} zyCK%-uRzT+hx&t3O)Ef4djX)O?Gxq{z(`y8s$JF#wXH<13LYieULscoM~HmV-i%1| zC^zIuTl8vT+HobVdeYk->hInYN*?#5{n2=(rAb=ao5z;+W+N?a6AkI7(~uqtO+p+^ zFVm%k6lqIdwbGW+p;T$T6Zf$1ooQG2t)of`2afjY$(EM32H=g_HALR1ZKPCS)V4s_ zQEQL(I;EakfY$afKx^ABOc%gtJ1EQA0E6z0dOL_tyEp3f68W_K5-Od7@@YFnGg7rZ z{`$nUrAb=bFO9A3myEWwO+=)hPDFYrGzoDuy-e2@QnVcrZ7{X?u~#)3&HBMcWdHpte;~&nP9ew(DTD zwiN))R0E8*O|q;U(BK{lTuStUdnmAu$fxb^qEa)IZ``)fjMQty6mL_R!e|Kzc zf7fVB+eAeA=|rT5LX!|j)5~;iAw}D^HmmJUIy7NzyD1#dc93l8Ik^|$X?v8&({_kb zfpI$m5!AMLyRD~>l3K|nFk0I}fMyl~%o%uY|p{IC3C@tU9q8?+Am)o+b>@>exbi&407j;LDqyO$&My->3)F}ztnBFN8Sx2 zDd?ALxMI^nVXM4(Y`hZ%v|ri)o?mtld4B1plzm6$L4A9!7s9;v>cqq5_S~@4(+<$? zxD3#K85HI`z~0N>VV4a+mAU&cCy5?&_hAZH$>$gKbk;&B?Zu24D;x)C zD|8BT5MXcM%d!r@W_R&!578EP@oqpx-aByB_r%Xbc~%&q6;*2H@O|6t{IIz)qpWax z*t;@w%wlDQH!W6H*lV%1!cA;s@_4?FI&7`*dt+PS_lyL7w|yla(uDgavk z-2g3rlQ3HV=BS`YmNf!8+)bH{M0?y#nGPbK{J)Pf2cbOqduc`LjrwJ+-t!wvELJ;+ zMHZ`BVZO!63YYCy&y*D|SZu8@?gvBZjov~0{@7OdePac>C7P2Wr#Zkt_Nuhz45Zihd)J&lR`eiY-vSOEYb>Vy~JNe3xd9EM%m6 z=K=pgDSiF*!!FIV?ljWgGPbn07-?ynXh=VuhV)Qq65?ojnJz7)NZYZ~9xHayp`f(a zaA~HO!U1WA$(Ek*2LRrsnUh4`rI`^**&_xcZNY0Pmu5;|v(*ezP)oZUMoU`^&`cS? zNLwq*iU4KqP;mj#WA0F~lE^3RA0X0NDBq!C9j!<`RNOn)J5<~?*E>{v)#95O*)LnH zW`Y+iRx`n~7ORzwZtAD zj7mM70PT+XyR2V^g}DSUJBU(QHUxFi9Uq({y5x=zidf0_B$s++KpB*`gDBsXzJqx2 zpgAT`PXjkttZcE?Vr7eJiwS*&bPX7RP|An1*@#UGAsi$65Bpj)CpDRTOg9HGgj zqe)P@Eg;1fmAkAhs!7I#ZBa+zz%0^AqO~m=0iG>35_z_0qf}rP>3|6AAo`@5CV+Ou zS%98JdW7i*n4`u~S=J3WySb98;EX$_UQ9IP zj;U*id{+1xDm6fPR%oOZsb^Z3S9p&^U$j{5NY7cUcBCgQRy)$87OQb{z~XD&k+J5Ohs*>~xW`u0LqY9OX3+QvV@~t@`Rw>v2sA zv|6kG^|96ex>29zi_E0L$xIT2CTET&5$WnfiuyHstom!|^n}%Kq;TNqx}Ah-^;-bm z$=GHh?_{ilQi0t=H-!0CZke4F2Bn@>fR_IPK+E4J%qf78zp&FT>xC+FuLCh)tKNNWjIuGqLUbq=NV6mDZdM#EnM7PDt zBOMkikF;5AJ)+J9$K?^arakhFu|4t);}QBOW*}eA3}i}Z66VY&cj$1y0& z+5nHaGq4>*UJhJx<l`=hxma9#MYTYO(UmOBO4? zJa4h`%QF@$zpS)a`Q-_VtzZ6RyndmZ+An`RwqO3(_=Wz8G02@W23ZrDBs-eSrTYa^ z{4yebxkQpC?3bdh#5DC=B>dux{f&Yy>z5LM=aeEFCwkZ&a<&oq?4m^Kg7Wq#-85ot${wY%*nG!E zxuU$-9CIjFlvu1>QDm`lMS;c26(bAG`qmZd=Hs|#5qhIt@h4-u;!lh#=$6P&ik$o; zM`&{CXcCm}3P^E9Z_c`-^g1^ROr5uS4ZTt#Wzu@8OpOo z3#~{!{H!eS4nHd_R<?9efw(uU*`;Z?r>89`#>TS}ao#syPAc@vHmtKJP zjl82o-Z%1wC>8jk<_N^0^Xi>+@5@Z=tQ{ycalUcc^kl+33d>9GeI|{?Eb<0*kvz-+07hz(BAx)dfEY6;L89l`Jgc8 z0cHnLyx%Sxfa-G(d7UIW<{t7YU?rdAe~L;Ap}d)(WPkb&;^aYd$5-tjj@m10?SgdA(9TuyZV6(+`CK&e)g5GFb{OQ=X_)}vGx+VIPBBwve5qj81lc024K#DEO z_gh;mBN-F6MGb|AIDKRko0*`AL~C2r0X$o*C-Q93LaD%ELmPyC=f{c{KG5#!k!tDz z+7-tE+7+F`90Zt&U|5!Q0PZi7M|SrR%`cNjb_a-juJ|)taURNZ#R!c^eW~Qh<+?Kc zQpuzCcWaar4)}iCW{>Z;ZFU5I+h*J^m81vS34b=W6aLINfv$+;q{TUbga}Rk98FTv zod79LDCo9MnAiP(;e-+j2QEoebz3Kt13V`zCGwn5L#coh>LAQlbKf$TBwD4K3V?RP zZh&?|lQ3HV#tA*LtP!xGTXqQ>iC*lMT|x(u&k28y6AnUoPUxi(sZLn+wC98;pEgGg z$_bBItmcG=Emm{F0~XskVcbrj2iggLKDHD7+&F=*h~%WjNlrq9CV!45Dd|pt6ekRb z6HbwU3C{^56b^htqxcQ$gaUx)gt$G(MytM5h^3v8zslau-0f_CqZT0Cs`8lvrsiza5dp5tvrfpc5 zO8}F$Qdu?x^^UtAdXDIVyB}J_O1?SsJB*YvDBr`?#wXLIY zK-*TbrL}DYc-n3x^0aNER6yGfh@iH8Qcn{=YkL-;heVGs{Q#rws4VMNRG$oq14ONT zG9-qGeA*^a=@OLZ@`8hjX-_I?eY4=UHnR`>IJ4j@7OQ>Wix#VW;Byw+eV}@Gl9vC& z?%UC7Eq`)s`IAO|nlCz&3a2wk5SpAhnna|_4=M5&9keszLOLCk{~GSwl~XuyiN5xr zmA?|;$-jcglfRBq0r?vt?0s+Z-qd!frV60d-w)90w+gcpVASuEWi5b8cR6h{(F%7t zt((ZF{xn4Dhw{`Ppb@F>Hn{M(xtyksfX+T{oS@V{Zn0ATu*Ft=^=^a7<9Q~QR%`XA zjjjGPqdv_SnMs9{nIs5J&Kyl5($$9)^@l|L^K@EGWCe5i+^g>RN0JBaeR}m9E&JR( zd;QjqNy&mY-E;2dH(E;Hw2Bu2R>{jO77*0P%Ph(%qkrXh!L!@+X-_4D{_XHx>x#|k zalO=14A6pa0%*Z&g=qj7!P{k74WQ1wm}U*pdiP?Q79yYEe}OJLp}fQ24q8#A`u>3K zyS^gwT7&nFqE{Qd!{3)JR^q>4u@e7Ti>>(Tf#`7!eR`n9|BJE3{|h5NT@jT@i&L3| z2u=PRO;XauhZOO<-?T&jAPJc8&>x_1VCEksxq9Xw0(e9J9FaHl3l6!1A#-oG2;xcg zlffq*l3VtNY(2x2)K*vxqpeU1(9AM`u|mBpD*?2*yK{?)cDTE9HAKGS-@inq1}M)8 zjkF^5n(3m&Mt=3|+X9QHg6CSS=7fvBA8kA5`_Zr}4YJcNg{2nzW`%LdPY<;G z-yK{2?;82(is(#Qoctt2X!7T1l9Dbzq{v@$*vh|_1ffR_IPK+E4J%qf7G2?~4dvR>1V=^K4&CXXTlF#tYm(`Vk@&c6CRh$v{cLd zS7XckS4L)}>-HWVt5M6dJvg#%B zjq<-nnNv{SC?BE~&!+7A&s;Qj*VV6d4p^)v{9cRIgx_tk8u1+#D=V~FY^^ZvU+EmQ zR`~0&t?<{z3Uo^}Cq+(kk|Q*^bTkP{w*sVCVMMHOiDXRpIH2eV@AlBYxjJg^s2{Pm zC;@oK0gH*e*l&Dgg18)FN) zCHj*hr$5ONnp`@X1f|;oQf$$C#Lf`?BxAz17@}~%7KKNxEk?+=XN!wOo-K-wrr4qc zB4~>$sb`du+7|0zv@I$CnyChuokEi=D+io*wpdDZ*4d(t$Y+c1VT)!cZ>P{gE0(I+ z!gpcd-DY#4T*-f?+3X;c{BK#TW`#o*+gU;VTEn=`4rsOBL40p)`M+o6r}?5Ysc<@z z1fj{9qe(=%{E#Al+fgh3PC7kd`MW6`I6D|5p?YW03-IJWO618uM5(}Sk`V~=&f^Mu zc2L}B>*=GU7JCVdmcJ07nS}r&f0ZmN0PJ*Mot#Uw%YAjSTrKmyIs3P$R1M|L3N?M{ zX9p*DduIp7ELO9^n-(iu?6p|g;x&tvEw);0Z87dAD(H>2#ovx?i@!Ctpj)CpDRTOg z9HGgjqe)P@Eg;1fb$!+r4J0Gg7UO=RqJ_eN>qVU;THB%x;62j0gUEZNvztnw-XsI{->5D{X-;L_up3CPV(ZIX%BleMGuf_I9eLtG4q3~;u>$eb}(T9yq zBvDIV2k5Pq?(B#R{bUs~jNRhnYn3a6qvGh?s?uTefC~RI- zKWq*OtBzU8%K_fxzm&+E{A(x`80B>k!J7iDQcndyOTHVRC2taD3&2R;Bg+~AXWT=% z8;OS8L%AJ9zES=UsB{p@oBVreMe0+QZ!PkkvOKiN$gd{8yivh94DUy*o`H$NcBNX1; z@~C4xTq4gFC2yr16O==&G*8i(n+3H}O(8(LVgo?CqDq*x0CPyt zD$6PX^N-4{q7_6B9+g`~jYPgff`7ynTcA8ww9$yv3x>_Ry+eWx7Ase*vsk%ewZ+O6 z%Pm%}SYokt#kda%=#6&8KaTB+e>AS3TOvOxa`KZLp~~gAjK6OZ`sMBi)5s_ zV%&!Wy%e_he#~SsOrrJvVF2JA5}YLR4hcpm6__jvj;Ed|lpeSB3{q0tVmXYqMKM4# zWdJi-)XK6V!0-{V#R8&tj)*NPiF~&BCv346%Ckistw=q8tXgEApH-I?p0HTi;!%s0 zEgrI1+2VeSl`YYl~rFE&LJjg zn?63=_@KGQpspm=KWHqXB(JsDO8(LD?g(h9mi#})mi#}AIxaMMax|S! zmmE?guQ_EUUrR?PEO{e^0~e3mNurj#1>i}(naGp8gHi#>yCLl33U($KlzLhLTJj43 zEqR|XrvT=ZpzyR^)(iE>UXlDLQR!Zhe1yn%e5iiiU>@bXnV{%&`UQk7N4*OOn=Do{ z!3K-fOt8*kH5071SlME^#nu+%zJNe)v@QN~Y+L-Nu?5`{{YjD2pX3NlE*(vR(rp1L zwkSDmZBa%tQf)Er3ka1I4$K7gBwE{|2H@FZ4UuPyMoI;4HMKwluQql{J+%OBi^BkI zi*{kU0LB)BvaAhI(J8jrLG(nY*rJ!nHxv99wm1dl%>+ZVVtL@SfziL&*y0n&yw+kR zf3?L*{$&KBPMK&_7a|3#y#sBZI#s6<3K3x%&NsCjNga}Rk z98FTv#fKE}d(YUh-%kQk$Nso484OW4@NK-pv(^YBWZ4`07m2*FUv$=uee=G~5(xYA z-R3)3RZ`6;1+^2_!DuH`05nq#FivQaW#xdiyW~`IDbcgLsuzMIJ>w5Rl z3-By*l*qHl5Tyb~4I>bx=67}NQA6>Nt*4KY+7U}&v_}d7npp@i9;uRL1%P+l!>MzL zF1UwN%ZYp*`F~KU8p_)})C}=P0%Z~3{m189%;>)knd>b6|5$q)=P0f<&69iY?(9Si zbNBYl-kFV<=n40Y*=f)2#&+*cMBj*>h>fuSjOp+1@1Fkt?!IM&O@U-65FceEOc{YG zBiWRZY|2PBWh6rx$##KcC?grlNVdxe+hrs}8DX=(bI$volUX@ImFlh|9Pykdb&@>q z^UIT2S(#ZT{=8@te@?W-|C61@&sN*`|LcR}|F157HeYk56h3E)pf)x0HibyWkE!t& z8WR5)gYG*15}jiwjk6Tg#$QH+_|MY{@mJ{;i@$~ue?{wxu4fuy!@iHO@h_{hig0HK zyzW5i9=1lyNgT?TtZdNdR|Bz@C|A1%{ zf4^vn|DjIfXRB@ezwqGrf5FAi=4;NB!skp8)TUaF*W||7ZU#Z$A5-H`-IDk>-}*7)&(Jv*|IjUoKZ^+Q@23^w&(kXw ze*q&N|D>*G0Ab^Q2VvtMS7!?0;-A-LMZ`D$+Tkf$DSz`xg;r$m|0Pmdz$$IM4O4=s%U$#5G`1k9}?+kB49KYi(h##7Qf=KU|5fbAI{q+Orn4y||J}0p9L`f{i$w(yu((JoU{Rx2 z42wEO{QKuMUC%7SLa^ma!D2<7dk8lZ^y{()R=y`heS*K|E|;c*=igAuRb{bUv=@b`Ixhp#*AJ%EYK(R{CW|?z83K8$zFHq za9YrBM%a)i)tN!KkQa4X3Gs#hoyRk@R{ZZgR%t~-{&jL$!U`eR*^1VKeO_Kg zVGi~~kylg<#9vX-@xh)gwITodgG2sx7c!fyX)=7DCIeTSI(eJHCqu^6kQ*BEswsDv z%hq>SQRsg_vjsGZ)jlUmZok4_)e^i%c z5FcIEE5y5K)i3K6;ykTL{J%;3V_0S~{(-%XrpQ)ACOf_+{`MnJ$_psW%R09Bmr=Nv zb+7`%&QGQwUT zROcqbVbOC}mesJ*{{2MPX>IfGCu-7)VDa0ew3&Wk@=xDQPX4n4Ve+4rN#4Xi8JYaY zyPW*lY8(G=KREv1cJZ_Mnlq*FIa36+mm@ZXNXCz;@n`Nz{JR-+*YW4*9GewJDX5J< zj|lM}qZQ&W(km8!2_t8Jzx6SRe^%EsjIi-vL)iGI)tN)M_?LBA88PDDR&<`$3;u0I zHCmDQe~0*QVukn{Y{f1!D?~ofO-#D@P2^*f;dnnHTK4#V)#)D3mfFaF=fRQxj*Fa4 z)@&KRkDP(4O`W{W;FFPKYUE9g{2l}CI`Z^d%hx>vYZ7?|5hCA3D@2~7S1j^8hN-pr zPwoxS_4FfbvIrca~&pkn*NtFW%cWDI_()U_W$Y8X*fk4-@Mo){v zaU6@n0Kz(l5e|iMU6w^W?yvIgr?tgjsu3O0U>uf*MBb4eu+unrVb(;6B1qv8>K2!c7*v-^j8$);|Am z>J3^?`G-?e{85C8KY)rptnc~HiJ5PbpA)Y>5g=n+$e-e0Qp>ymj;Gz41MHUgT*iS29k*8Pe z(tiQtleeZ`=NWf*>3>pJGk~yEyo0b*jH@$+a6A9JE-NCI{39l(Xno`#F{#jsQ1M4l zv4CYiC)kTbH8!I4!NYU@v%$9?Iqg3itna}?w$ASSfArv#|H!4xW@?-a*~iIX)uuMy zX28jmF*W5nDci@VZZf#8cm5`wV>^FuYNOlvQ;3lACR!ooOlqU1EMN3v#6J!W>w0<+ zHs+HE8}pDlBM2Asq%O-LDn8~zv@ZIXi?kv!|1mL7VTG8>Y(;C#Ly?#Vx{R5vvoZhi zgJb?<7c-lwc`{_5Cxca++IX7*Cu7Fcm@BD`F6KD~*LBP_I>%yOp>TGNuOmXtH)w^J zoAinu$y1MQj33GSACuKA)6u4U5XYw6i?GgagiCo?m!%P}`TIGx(JJ}-IdZfjDVz7k zk6?uyOAFdeJk<@Ia z9!$c2b0jbnjhwRh$SH{0)X&=#B}oFNl2CkXqkD36f&#=zSjV(prgQA_-#o>&BvcTA zgp0HS2{n4fj`nqo_zu6O>zPH^;J0iN6js!^hj1wL>#_#cet)#TMQhL>?bG~G1cg5# zrQKL|hqqH-cGJd3_Zk!;*MCOj1*G2vg=Zr#CVe{oV$y%Z%FNl}PqmAjEwz#V$%7;R z6Bjv~tl2VrpDhDdn>u-$!6zff)W~z2B=W-yH1aKn{kHFcPlFWb5PSXbB!#mv7ZLuI zs91pI z)uv9~X7I_7F*W3LkA&REK-U#=mJae}5BJE=aF2wXL- zHX+)eFeci3R2va3AJsa(s>=v03V;4!6#m?yz)&=E%HmO=AZk-TZ&Q>c3YdyQb+hdI z3lyMh6zX)2o!zZbTszq}5CMf-v;qpL$6HWHV?5{X>CrFrAD8v4(9@!D6vv{_kFd@l z!l5v#%QA>(Jqo*M(0 zBE)}%R*1h&uh>k`z-W2w{|Q;oJUwmLJ8*3LYwB#qaq$o6vL?$8`S|bBI_%@m@JEsO z|C0Czu|oX0Cz1z(TN14~5G+UHUyQ^*ACKQW?Ay_SfUUOi|K)?@|4SD?o3A-j3Lig3 zP`f8$Q;1~zm>Pfn35kD%L3bU0k0s&f>!@qc*klHU&yz zfvH$zwg?uxDMr^=?Ef#r1z~UIKfJKpBv5)*EjE`pQyK3F_yIEb$Fv3!C z4PmL6R%Z_3CWU2PRz^JMzv(+qYuJC&SECi7;;#wmCRU)L!A7)Fk-h3(w)-$CXRf-J z?V6AOY0-v?lxRam^L>3GFE5c2yP#RU6|=gmfVkps=srPf!QaqbrWK*$Z=hlhD^O82V`-TyHch${ zMe~%$+8L(}6)U0*70aRx6^o+HTrn?NsOb194@P6D_?rh)@i&eNhNbaSA|F4+QJY$N zn*t@Nz*H(~X_+gQC`Q**H0T^Vf$Z5TR5Yo0pyDpAKt+11r((=fk->;R5;&ymS)-@L z;y8}QVgO;C!w84PxGu{g4*1DpKdpm)vMA7sVDYzLF@Y7ZD6ti-w*~Z%gN!D3moVA1idf{eyu@wX4g;%^-m3`_H;L_U9tqc*klHU&yzfvH%O zw+a?B6r*b_s&tme_uRuj%M{ukLTZSB#dTT%iw3>q5K^>QG%?&;0-k!zU18|mChJ+G zr-fi2j>Vz}VVypN!(vF6r4SeWnZ+hrbN8bx7{%xsixQnQAL7SOsCez1T)ioCu4?@6f-D`1i7{10^+KU;0%|N95W|MxEbRIdj52&M2jQv{8lnt7W-B;&`_ z__Mtd{~&{Ijlbh3Me}ryy**-_g4*~Ci17UQ30mR#@e;ja@s~~EV|S3w>v~2JHvW$h zHvU<477%V$SkYw_#0&nXi!ahD_@6GW(~8Ur|3FHsSRwuS28%tS1&fYv7Gg9Oi+^}97XRR|U|5)dW>Ju!oh%hVcrxj*}JiTIA6foqc-(^;q)b$J?EEew|EEePH zOd%W=^SZ2vc+o#pbc)uff2gQJD}u#8g2e(>z@o-hB(S&?!9ujfLbSy~w8cWS#X|IY zv0yY7i+_AD7XRq5U|5Wm;97L&RxhgkOSEI&l+Q~%EL zBCQA({{$9OSOJSNThWTerfR_A>&s3XEWQ+Nu=rH8!Qw;F28;JauNMnOW3l+B2V?P1 z4hx2*`BNgFKgCg-T6&uTC9%L%EGkdRY%xbMy2heL=NJ|%6xtp{>WF~F4O#(_ zMQZ!TN6TlHhd%gnr(n^)UDmTqPm9Gt9E(LS!aBPV?i^xRm!%PXJM4#qZ*6#F8?Eg- z^x>qO{<-@FoF9S32-f%fy@ds~;z@H3v5EhGWZrlE?MI#}x^syC5xrZq+*|lBS%E!O zZ1)TrTW4eb(Su|Dk&Btl)I1ro&y&HbO>Ml*fRiy}YRtv$a^J}WgNw)ftw;9mb3ZO% zc;3D*TvvHQwD9~BkCf>gi+P^H*_bPc5c5S^A?6yrVlme-;xVu3dS($e)Ga$C<`s4B zA>6geeqGkU`pSQ>yhUrxf3QsRN0Gfh^(|uBjTd(R?2hE_f9XQl{V#|%yZ@V_&F=rY zXj86NM4R3JMbYcs{TYtsBK55YgOU1{BZHAC0#wN(Kz-DvoZhBJNir~%jNA^H01i`* zI2r4>52Zlo7#Wk4+LBR31Ts$13S^Y&6(gg9QTXr~-cfK+CV)j<&p5)8@j1dy0Q2fB zA>46cO_x;>UwAUE&|2|iG-yT0c+8M-4=<3B$|SEj94Lir4twNXbB2s3MH@067j4M+ zI`Vkpmt8)d$Z#wfkF_D=F(HGIDFRfQN zI3r}_5P^(Cv;r9gdd0{nVz~Pn_6ix(x}G6~CF3%}k};{y48k267Ij$(v9CuD4QFUQ z)uV@oDy_)t$u=1>mhb`@bvC2*vctf1xa_cdI((tgC)$v)S+pVJ-g);oX3kg@EptZ4 zmmL_6C1X?U8Up=kAf0Lz`{T=qPo%8m3R1V{UdF%Z<+jhF^QKPz^UW6s%G{TZG ztj-w1%^B0WERT3~QOP()>-3_MQKA)@GkOdeGkD>f&I+5+`r?9TM%|oY2zV-TJ#uH{ zdgRvl^~la&T(Hv-(9?#19wC4cXw+20M@=2nrflA(7D)mym4NC_nHv@ub}IoLf10S% zIrhU?Yn0R;H5!O8H{7BX=7!X+mboE~;Rx6-bHl(cSkJ|s0i(Js zgIM)XukNCC+dsXUrxhV!vmsy%FAz{Yz4d^ES0e5`d`$ly(ULQw+On0xEQloi{8}QcFM; z5eT?KD-ckpSL|!e21d(U4fmPt)Dloa1Om>`3ItT>B?P#4QdKe5^7eKonFE$} zJ(CDaz#W7oU{Rf$2zP$avs;$cux|T1n6J}n`a77Lv?2sNVF=hv$8dg--p!4=E!Urq zl{WmR4I6&A;op<=VbNwj7!+;hgWaMH4Sk}8hX2SvVn1KDyS14iSQ?&aL&Fn71EbN{ zsf?$Any5_)y-i(`G+-(XncYIeZc6aqr{M?x!_RN{9v`4{_H*SAzW>7w|D0CVwf@Zy zH^>L-pLit4Dq`o1qZHXPkw*k3j?oHC6zLT^XDngFe+FY#*E5W;Ok6`)CZ^SyLpUau zby*p4XF+dxK2Phb1-;?<4y}Lw^BXpBTa3W*$STUN{3aVPb!Bkz(r4Ae%?&@~KJN{@ z8OfFm#h)yH=aD9V9A=Pv^oSSlTMyZ)ed{4xu5UeL>qLS-zu_kyN$+W?)4(37QwDKX z-}JSMMp@tVm7`CrN_mWUmBw`~{Rlgda|m0dQFSH|Ztk4bWd+2`;Y9$nis3~7v?6=X z7PIHf;e|b?%4R&%vgfQk?asd*Vy{?^{8rFndvNzbUkbIv@{&Yu`~=ItaBLQXc*UJ zS;Uk6rv>-Z+Tnj%us|z9L)y?VfmhmKF2dPoK}u}LYX*nNi-6yfp9=jsa5yLWXVIrc zKa4&p+8}dWw3%#=iZ+w&LD6Qi-6vWm+yA#yWEiJKCfx>^v>?Nfl?}@0*`RQ0Q)h2e zyd*N1icER0ATvXmx<;l-=TG_EwEya=`vA5~26mdQAp$bjX$52&^opH)H8I{hU@zx? zV;Sn*C#zYcqvc~CjwPlCVVypNBW6gKr4Vn7>*udcw9bv|=dUcS2r*j?F^BOY#N_vF zd~~#hm&?otI@W=MdTrnat%C>k+CYjwicqr6P|}ANjxw2S z@|y4MYwnV_`GWWh(FTl9L>n+Z5N*JCPqYE!f@lGw<1dIAjs;^|8!)yB7>rB_ph}(q z>Z3O0^fon0f`O@EWU~UsAm!*9j69uVZ<8IT)E0~aBAlh2pcT&2O7x1IxtB3sw?CPF z&%JhXURN`UuwZ28=gFuNMr4W5MWc14gfa!N`;Vs^kfvK5A1=Z&RZr z7?=u1>L~$Z^HV0vP*g1u*jTih)tU`1sDzC%M5@-Zh}B89-Pt z-a%L}#?_fZI56gQSrJk5pXg4}y6!*GRcJ-P=rdp}-~}*hY(*;=+h+q9TSXf%9usZA z`0Aqj8w17{q74|Ih+Z!k499}e*9MF}0fUh#0aVEoKz-DnjM&sD2?nNuQCBc-QjV@? zj3%99VD#=6Fj9yB#wJ<;jLiNPFtQkOC~-5!u&$;DVZk_wuwV?SGlFnnOzN^6;_)f{ zSa*olmMQ&MSELmI<4FU?6kY(M%vQ95aj_N-C2xr~V7wvPfbptm1IA0D4H(ahUN0C7 z$Aa->8!(;}Fc_H1}G11OrpSsO*;+V~%ok4MvU5F)&srwLO&75dn-F zv;r7Sdc|gp)PR5F&CMA71G1WBI$AIe;#e?x5!Ts_a9|AUvNYmGNx|4g>t;#8$kB>` zvE6_%f)~IjuobOfG#+zT{>(YXvSz1W+HfDW|uoQ4$PH1*141U`$YsuE8kN+1^$7y1d$Yo>E&dDu@8aMOp!j8ogpC zpLL8^-F;{dj5S@&EW%>2Wl+FaQRg1Qfzhwa8dxQN7uqfJ2mUU!G=CHUV}}7_H(mfE zJD3FH{e>`NR7D#wDxwV-WzhzVl4t`)QS^GjU^o_x9c{qaAz&~vC4ee<0;rGLl+)YP zClsH_GCoJx zDPvxpC4~F%x~9vjh`0UC>{n=2{LSnQT9L1nGlqOk@-+1FopQ-*m;c3iX} zU{tgrU|6&e(D75UY_=sJ(}sYI5WomDYO3L*rVeT^Mr>-4Bmh$hNFNXa`WSZC1Z3$P z`|4=;fDn*FgwLgiXob(E1$qeq?s0}TieR1UEt|x?sQC&|j!qRXWVQCmvXAI%ygK1rsH`XrwG*@lR~s^R2^ow`5ui$*4Cc#>Y-g)TV^qrY=buFqMYVL7`#FBw_ zIri1!BIUI-R1txOE3^U)b$Z3l8yXl3PjBO)S*4*TC+nG~r_Fu`j-_Euoy|Coh5=pH zH2;o&WcDtt$NeL-8U83j!)`;vAYPy$mrKqQPn`+##7=pQf|)0_iZ*0CCfbnkRpfl) zi}?9O$MXckv1IISL&k0)gOMo$RLLVieblC$-lj%LGBA~ld``$1p&VV4QKWN>jA=@3 z$tWQL8E0q(GAi_n9YLxX2MrjPx5zxPtm~OXSTgP)EE$XH+(bAsdY+MGHLPR)v&MB= zBmT2SlU9U`J%)_Ubc}o*l75EAG|gTT`2y|P>lpe1XD4|JR_Lw zrZin+lB09%v~!fYTTJqZfXOjh0h1!VVwjXL;y<=MtLqs?SWK=VEGEnD3sL4;#X-@AjD4aF89PK9GPZ~| zhnD+Yejl0eCqFO+)wLse_vyP zRs@EufnfqKz))f#$#th}?8jLEPV_+;(YJ2>sAp#iJX$3GE z^oq?AO$>Qui<>2S56fy6>1Z+7hhxF$L0G2`Avay?RH2jBWHJS(?}_U$*# z#qJ+`+uYT5oVMM%EW%#IdgR%|)WIw}jIf=KvdsJg9A;RbsTT@^+uI5(3fH;D4s+Ct zox1a6rGR8!{`px1l8@q${Od?8g-rMA=-5MiG>K`ZQ2C3?lq z$;uexubnnOZ7Zkl^SYiPi=!G4T0-xAzgbJ_r~D%t>WQ?vlk@wWtQwgq6I4FCfI03*<(sfJIQI;c(AyiF~V z0AMNrbp_xi!|r-&Xwo_MTS&b}1%MPH0I-Qx03dU;WopP`#D5EESl82oumqe$SOSLB z89}(IVN#dn5Uc*}Hiu~4_HVZ-(u#afG-wEz!V6PFnayaO8lLS7Ct^?cg%h#8qRrH> zU9=(N3DJg(Z+c@_0y{ntV>p(K!8T+J3K@({5ui#Q0qUbR<@7c+N|J%8WK@pI)G$Xm zx+bGW=Qqp`nLNMb?tWdN)b^lJM+7o%&%X8=o*YNonvPc^OV|xQ9%SSF478M)aVrhqmFUJ{ZN*iO|0p9W)YTyEzb!VE9%@s zI5PTmSp#e7UA-IS7Ojuo)w@yB{841ec-oM$8!wQNeJ)AHwneww8!{djZOHigy7SGH z@ug@pWqc~yOc@`FmV-&h=a~%0lJRsKGM*MP7?~nKl{^B}M{UaKZEBPx15?S!Jtt%w zrW~zgbo^CPfzGi@#FLcTl2Js2D?F!Yg)2N|dd0}7VAz*!4t?NWx4EdR8An(!K1bLo zV_uylgaczumsJrTy{wo1uF$H#te5^8v?5>}G+^Ar3t*&;~FFb)bBj7$ljN}d4fqc-LAHZ@9ufvI4mj|mukl%o}l zjvr*s(m8gTIebjO$RPq4hiC;b3iOJdW)?AyUeB2|x!aVcbu~i>3&v%H1!Gd38H594 zQJ0kvXZ=@n*; zi8f&D7j3}UC0fAf{2d3!92mJaVB`c0My3Q%B~JkLQJZpln;Ip-z*I0A3dSns=o*aF z@W%MJ1^vSUMj8>0CEI9)V@Z}?u^A(W5q}lysII3MVaYg+uw)FYGlp;u>xl>~(i^nx7%PBwBxl^pOf3 z5CA9=p5$E-Z-77R^^oiX%edG$}Ioqd!;XaI>>UCEzd!CoI%+t}Py#vSQ zzoyP+9GCxqE^D%E)XxTYX}#oUgA9KZ$$!Y?KZqADN93O8-Hzd6?srUvFAuo(zfYR>uRCFc=_x~`my zbcp3VP3dgTC4|rU3=N-ig+8&Is~BhO2h^7(=Ve{XB*Nx=2VrwwROcqb<=pdvEURJd z^EqFq^_0)KNh^}`VUzP_I)rnAkFo6hb%&iSwhgjyLl+k9MNBGQ- z(eRlU=@ZMmgy9YmCnfV)UCS`SW_}G}GoMyx4&lxLmvvbgF|?!~4$jj$vZNmlYP2Gm zA2FHV#523(5A08@HsXV4-~RR^mtS&unu+a#Xr0(tfdS^H+Pwpj&9m7aX_M^{$(AkE z5E-=(k@2ccdA!Y-li6ZwwoS6NPnX|gc=4n7I(}g}eOx2DBR{%uTyoAJ!a3b8TH%~7 zN3Ym9T^>Uo*q7@ApJNMonz-~Jq1a+Nex5NcWH&B(}k9#GZ2Y0_MeOkN_(;m6dgLyk=8v>POq8epFItt2JIK;NxZNYEvq2GyY`in3{UIAanN&L;dg1-R7+` z;mqs@;jJ^@eWXgK*!;ar`Rx2%L-_goIt@R6H|P_aznd8GV|MS0vX(_U+GO|P*sOaH z*6BmItcP@23bE^)ep1^+Yxg<*q;{N^edkOTVMBjp1m&=KapR+B55K#A>c;GIZ^%1m zSeGeL_)?xfwljd849DmZFP44T%s+c5`m&ktK2qY(}pdgZ!`Yn&VZ>qL-vI141)|cp6|CGdEl?j=IKzqRWa{WbRSa2 zDV=%L+O=m0|O2 zy3e&q_c=+IE!7wqwU3eUs!e&k&6tzvVrsgnQ8~bE9{n*6a2Yzs4sb)Gl5`dkE=cUB z6)s5R=@mPbDPY7;WhQk!0|=Y+I|!TfxH?k^w@=UOvLfQ>R!#a8t>?CC(iK{fq>q`T z7w|&TH8!L5RAxAGD)VeS>5flj*gTu`u{KE`lcd>Fjg(RQNExr%l*ikQIhi!3CSBL0 zZ!)~DPi2~PjwRhYCP}9dA?Z!DLeiPBmZY;7a)nw>WrlStp{L(nVU4q=!w?Q+Q$aF0&b}mmc;`gi8lmc7Pdh^4|IT!lF9Hy7gxzHa%FN!wbOU#Ql z=eV!!zW0s03w2FbGmEeoYguTL%=(tg@Av@iaRW=2w@4hjIabusxyOd1T5;Z5@ORHJ@-39Yx5pG_p8#15OCZOu!I*5 z4s|x8^?8-s&%4yk^C}I|=73NaZD^>8HZ)X43k@AVufh;44aeKia9n6$G#WdV@v&1A zwJD*usY{XuOr@crG^|pBu4zaWTWIJn3JqyQpkW)WKtq;ZF&c6haT-Q-J-rA^!)b)2 zVOX6pggaH3)@6CbUH|mbF;tdJdRFLZX*h~wY3N5-XAt4$hEZLX zK@{HBxnUQr6L0I>kf#-);YCBk7+yF!6xob@Ek}nVV~z&%)XCGLP3n6^OX~l&(<1_# zYEyr)P3kX7>TI>fO9gzqj9qO?P?}0?yD11XSo1`&dxL z_~Nd88^60JdRbR9iLe0NL0AA5)wzjqyM52NEURJV{ceAq)-k`^H)%xx7&QQFreoOc z)8onAeyiMzW_J5ck$cqcUfN(U{jPVnXH#wHqisSTmC)I0O_vJzbQ!zal*-$TKN&iv zhMpOh(04P`u0zk!Id;GEC}p&v=Mf?FW3)o(MS8_{`w~XW6YaX5VT4Wn8p5VNt$4u%s@j~hiHly{Uz~RC0QQ*K}_$aVPwAt;S6fFdF z{850-wgil|Az(}hU<4X9)$mbM2eoG-Hnm6+fT;vDm4JH;yK4f{6DFq~`y!%2aG(P-*a#-~nA)TV^qrY=bsFcpTv zYXZX4Ci1(&Q};un%``C}+K|yN+K|yJ z+K|yBdcD&G!?9!(+mKNdG8ma6K$ScK)JJW~>1}G1Bm+~)$etE51}R6^WaQ~A-vzn{ zD90(aC8L1&`bB;D;R#yzU-U0Oq}RoU`*7fH6To=$)33gMZgF|L+$Nyw8AVt!K1NtF zX4P3hxOrklmsJqg{UxJ|w3hrOqdKj~Jn@PlV-+uu(PT67Egu(8JnQBLL&GuAhK56; z4GsH68ya?r78)MrAL;09f+1KMUTH(aD?$UK(b%bskDZ#RJs+{DOOggmr6E-k8a9`H z3>q?Yj(v(4DhUl)M3^V`(+cxMo?fweqJSYU{g;aele(S(gr(sfgr#9zohgJnotW2U zMa1=9y<~KX)>5xtGOEyu&~VDouz+XJA?^LIH8vv?JBR!>FIaOlm>(^>mvdU~fBl{& z-R}NZHqRz~s!h_TBx$x(BW2V+X~wHIt zQSa-LbP5rY-b5=Toq4?_=`2S4MR~)zo*slv`Xs_8J*3VE!tM8yx-5ri*jLz?7uX!4 zb<4iM#=N4YNGp=`xJh~nFYNbaHluaFe^rkCX1{+aa(?i9{Q0bPEFLNgx;nuNg6PfhRW-*-_KEkI1TH$#emMS^Me)2YmWkTM4;gY ztw2MQUa|c?b*AGv;K{n3{C) zjO_Ol3@@JaI`;cAon!m`Jf*WqR}dlTi?l-0HG0L8u4B04eXq>$Yr39Ugw1u!q$Itf z&OL-nx?h(yu+IDA{ViHE{&=6}k0MFGYLecKXOp&5V0JQj)4=nOyE8%amGQHp%`yII z(dHPxSG4Two!>Mt=?HkW4FRtT0gOPSrW!tK>Yz4d^ES0e5`d`$1gv9U zFVHzgz$7KL1QZd0fK#*r0cCo{2&iDloy0=GqONBgVF~ygVfXcUb(Rp0fHhrKMSS63 zrFVtaihq?}gI46Tz-xwpdw79>)Ku~pyYKF@cPDKyXL+|G=lnM!=ls{>=lmW2VmF&@ z=YZGR5b&B1zz8&Is^O!i4r)_2Z&QmT0hmfadP)fBW7u62kfpP`d%JPNp1luG2?04o zAm9+KKtO?BvEOVjV!W6seE3Z7R{72LXgDoy}-{BI5lw-I<-)@81<|_WQR)%YJX3h%hT^d!>*~wW*(O zllo~%ovqe*seq4{v8zp~yv_KNsbgyD4NZNOp>~~m>J5L1&wVY_|AwTVMugP2(F&<& z=@r}Wa~QMcCc@$Evfq#DdU_Ey_0tHO`mj1<2)Ex)>#{te`j(#CAER~UEj_m{(TeQ% zC6oFLUP!&dX0-lJ`!{d8ZwSnOe>+0JXAuHEiWAWB@3gbomVitr_Q!~)=y)^KkE;i zmG!L9(-LqL#}d$wu+AXD5iqLDGKd=~C14k=n<*tAPb;$DzitQ^!wUoy*^Jh22+q9X z_IvXU!K3+|q+SFfflltqDI$N#rQUMJ>W6rG2;GFH%OEdKD4&`zy4IychhrDRx?jW8}SYt z8~U0$n{nJ^KcLH+EPK;`Ep(UGwEtQt!yiRLKVw24#QUDPeb|1a&z(y?9kBnD3*9{E zxJR^nr0@9Y05;DCeWp#&XC!F0R1;;?K2gT2Hs$d)V@?K*sX^z@$*KJa!;1&Kj#K+0 zonv={PE$G?bO{lHK0_-6U7=Sj=qg71Ign*t&m_VoeFtHaUR38M!d>L;Da*1N)+zsy z{yMD*|B=2)D>A`Pnxr?=F?^&?mzk_uF6ABTb*J{`lK+rsGuaP_Hi!Fu(Pp>r6)n5{ zPj|Z8GXzV+WE&bLg$72Wu~QizJ2g?85_+4uBx%4@8Zu?s?RQgxI1TGK&Ck&}_WjQ& z<+U{A5rKwdv;qx9dc~d^C}Ftg!Jc$a4b19lh7lHqYX}R&v^sMLH`g!gvNB@HKM8rB z)<^zH$QrH4Za-yUxQS=ydiNwdThaQ7{?+qtw>O{YUlP6ED|u|54SK3g&{GmLTdIjN zYM&_MRh#m7n=vPY#?+vj1Z_XY-eY+2px3e6r{8SZ?FZhJpfiXN^e$Q<=p4ObyL}$x zOY?a1`5rm18`t&pBW%*=5H{&ibtVul=~-P?K-~84qd7sV>EB0FrWHy04U_a7UfAuc zY{oM!yZzL8cUJHayYz%4ZFc)H(PpKtgeODoWjKHow^ z2170gx}*J&u4avn7KYfZ8F+O=~%Dh@tri0#TS+~TU0Ykbhg?MFAPx3d>8ei0t{4A{q0p|<>hw;KmettUnw&YXtD_G`j$zzdU#~O+J zI@V#)a^&y$ZOLr5odV9aA>f=4zz8&Is^O!i4r)_2Z&QmT0hmfaVOj_nW7u62P@=P3 z-f>^)&QelKKp7DTI8Q4OP^Fg;FkvqW)i7@Jetqr${l*$Ax|(T(jr%^r0sF!@WK?3nc>%fTc&_rMc4mf0N7S^X94Eeut~Hz zHrzewd~z1W+HfDW|uoQ4$PH1tU8n zU<^`@uEEID`RQv1%}?>lcm0&wf>A&OFiy}4V3g=}%H0t->%Qy9aQ7EK(<|Tg>v~2J zmW+=PmW)|-77&h%6rUqbHr1wnzD?@qC3Uu10nZq7N3o!KGhjs5S)dY0*FX*h^uY3M~*XE(xKJsQ?!X~e;2bqd%< z>zQYD3dqrl&@f|Y7{LoP6xfW!oy6aSTLkZa?es&Wen+$+<8#r5jE_YdGOmdhGCIDK znBiD5X4;T3BV;f#MSv=K1gMYNl+)YPC`ksUl2Lp|$e5rUU6WC!^Ko|u;4UD~Q)){_ z1rf-&NGp(0qgRZKI)(%66(M6y*E5T-9Biow87u1CL%4aOUzato!p$MKXoZ_Y()>|` zjJFIKyYa%Mq--U5De3=@n?u+lsJbq(4X4IbdF$C4@_Q zO_x;>&s^4z4p(RmUDl5d4O)?;-!@6#!~5R%^t*!8g^iEyFh_*QOA&9$lcE0;7Y&#F zQ=;EC+w?!P0)t80*I%-EHtDz9B>lD|&6aAUjM_)ac-5vn-e%0nq%k$=^aV+}kKuKl zbe7JsL;vsvNjirJNgtvWk}l9Ic6GRjAzuo)$3~`gHA4s+^ksw%dQzPkgbR96mz5AV z-_W4X(E98R4Z2Dz67)MJ=q0>xzE@`}cA22vZ%Kd0OwxrDc5NHXM4p$Q$~F^uF8;IG z|4Kt|_aY%S)rS5~o6z5p(AjEDmkRiF8N1q)%G-=T89Jth-XL^)A$*mg#zSAnwZYUy zoq@lSI{+?9=xIaZcJl^3=Qf z7_B@0*K$gN9xZ5MN<4T7Ti-pu9=Q{K7$2-V9_8@fp$P5T6!p$ViDcWHisZ zPX%&_@AwxE7>*^Q(uRzRkip0l0jlH?pgw9-PH$7ABpH}WM)jhQu|PSxCZkU0*u=j^ zsqMtyKm;;w(F$awW?RTeW5j=ZZ(vr|vqDcx#!(zgMnA$jg9t~)s4mMO?)e|s+C}Rd z{{vfjS`jiX7&6B2!hBFs}J`y%f&-w}VOxp^(5JqWa$57<XFxlH1E4R0nHrHxbIH+%^Xk{ZRUWQXfp>?MavxUgHCA}m~%8-Y(v9E zp@Gq8>{Q0bPEFLNgx;nuNg6PfhWwn+FhU8srlCmZ&2AEKM~7+3YiTGU0u5(q1sW>! ziqTNTaMu{8LiEwj3&%3g$hBfA|0bQr{vcCq@q!poI*3ht- zj-?Ie?9YCuntqobnl(72`Ts{h{EmtA?W+3$oS#9Tt8TC_3wRiPTC~CBq-cZ5anS~o zqoNHa2Sp1e|G8647@M6mX4_ygE0{1$<$;oU9w?UD)YjV+EQtxGVv>1RFxgFMy2d0& z=h&fQl)76?@`!-RFZ3O0^fon0l7XpYG?k2dl%s1h(w80N^gI06_Y3 z%hZs;h))eex}G(9S^|#aSONwR);WxD1dQvlEaEkPL3ux|lE0u_pcNtDk|AKi{6#o| zl-Q1w27$;CWbhMr)G$YoJ)+GKSZY&SZ&R=&CYXvz`LbX#LutCkq)KN~R{pzXzffGJ?)C^$ zLj+8&(+Ze0=oLGHG%@1uCF`xqdKT$vq1cCGG3h~Arw<`_DCn{jVvm3PU=yu<{_%q> ztq3NU4JL>2BADc>8y|hy3?_ofr9~I}|3%al(FT*UXoE>fw85k(+F();Z7|7;7EFGw zQ%r`c4wK7mFu5$4Fihovl6f8|mfFbPlBA-s4UUJ__8Z!1Sg>S33i#B9DA=;4f&0_f8^0sIpqvLO@ z8IGMms%^-q3K@({5ui#Q0qUbR<@7c+N|J%8WMtnHG6pF}D;XXC0$-lavCpmJl-iO} zK!g`!pP&_9h+U#rjEpjd`=qj2KB>&>dPWhJjE@nPj9GOS5bij$qRT3X=Cpopy-4fs zw0>@_(~3+W?-?>y@d6o5HX}jCXYPZFCF3(UmzX(YyJ$;>XiLVY?r+STaa;6y$zV8^ zjQ84*@t%;u$P@vpcQ==pqm`X!Ia>#BL5P)1nO~lcEhKWaxtO4B-lbc{)p&M{1S=LM4#B4DzKR=^}P--1aN zBaX?iuBQiKF*%8_m<*{if^e8j>arZ-Wq+c2h*r^`s1|8OFqt=)OyNZ^DYG4|mpbb8 zaH-=1IoULryeHaVazV7ghGJ>cjHAShwS_O>a;;P^6})e%Nu@X!-oH|;b)2cBYASZY&S zZ&R=&CYXvz?tQ`JFs11llLDP%-=I%YcZ*385imJLD_~NlSL_?~3dT3)p~}O3?&i5g zUClVcQt~;%&JFYGEFs+OQfs=bikN#suXbIbb?FJc+SQ;Hq2#Kel^F^a`Rp4tD+4UFNro_JTKaSaYVEM>fYC=ex&|Xl=NK5nR|Sk5B7kv-Rsf?wuNW9bjM$48r*$<$ z2n)t#gau<#of(8XXe{co65@nEw>U#<%%59SX+^-eX24j&3kQulThV$Mbl0*2!(0aK z6>R|M5p4iiyW##u0O7|<)Ms+p42n)bzgau$&oiT(veoX7K zJmQ!K;25nD4?u}l1b~_WU?Enf`vAgh_Dqm6zCj)h@Ooy|B7h5=pHWZC^$y(Dp$)?;&eNg~4^MPRsYU>L*; z(?RZoSS7w=0)2bNooJZQ&(4G?;5E?_`cHHkI-6=kzuqSF>k>L!t?5z$pDtrpyC-5Z z{$%Kw8hZW%34J6!)Nh+-%R9cpP^5G03d1yIw4s*}A@nn}Lg*EG#X_%Q$kX?FGli~a z5@A!ngRrSDs&fp?0Ht*%$ zCHf)sHqmA}*d*E>93o$m-im)o+VQvK49AkO*oKTnA)^@(ph}($>Z4>VM{H`8Bm+~) z$XpjPc2kb7r-K}wW2c9sl-iP!M+7pC(F$Y~=@mOYEMd5lgUjw)@>yNYFv5ay4Pn8U zR%Z_3z*yF0WyC>$c5t57Gyd$LMk@lwk^$o;UI3%PR^~-<+Ve%RhfprWN_R>q7&^99{sU%2u@AoV!QB zFdrzlOVDP)tH|H`O3&w|S!1z$WU}Q=FRq_N-AGIl` zx2aJQ3`_;1wkR{k66NR`j0T-!VDu~r7)@#(z_?2*fRSEm0V9JE17k>6vqnb?#&H}A z#sI=PhY=2pab1>0Jok(~n6;nQ@H6^gR)JPz#`ws9F@YDrD6ti-Ge*ya@IB~S#T`}* z7%QR;7|Ws!7>l9}81tgnJ7X{$3&uxn!1zeOU}Q=FRq_N-AGIl`x2aJQ3`_;1yd+@E zP>!y_sM0xhC|Rb|_E1toghR=7TH#RApjYfr(!_{eg6jQHRmY%ZN5$q(vJrQlbqQ&3X6t z28@Pi0i)w{42EOD__z%i9}5_aObMV$o&f5jHs$m-HA;eksbCa76fnjpN7rDK=o~xy zoTbzjj4~pCah_HHqe`#Xp`?a!U~K37%38mieXi(wrV*Bd`v^M@H{QvaF8v z(q5f1ZqPcpSEq~=e-t63Zpi4v3uI(IN|JGYGLZ3xXhX)Uq74}@i8f?BFWQiCMD%*e zU^teHdK)t8LIxvK1gMfnfcmISIlWDdl4M{i8QG77j6urLH5qw2%O?zZ1q7wGWE2qL zSaO0^IF^*?C1e!cD{_cv>{_mv>{_ew2;y9 zSq8(gWPH+wj8B9NMy3c*C6560QF}gOQ==pqm`X7x= zFkmd;1u$xCMe8-I=jBSJxn}jOXamF3q74jtMH?8lixwDunt!CDFSi(ih2cgU7;Xp* zj7C$ZG9CtMqBbS;Hg!qDfT=Ll6^5IXpzCR(N#__0y>)>hg$M_bO|-%RBvbb=$eSTB z%4e2`KKSy2`z$i7tLZ^l7)~NA3`6RSAl&g|QkUfrU+q*F4$)fMsW232MPOJqFihbE z7|Lu#zU9lUCy$5I%*RC=7`}eN`38nBMH?7C6)iA4+$jtU!NRcI28LyUfzfE{RK}-H zP1L4@-li@|7%&xvN?m4#IZDtq3^h8(ju|VI*B&$Kh%htUpcQ6@CcR?EjMOKs$Bh0@ zWIfCDv@{&Vu{87|tg{>8Xc*RIX~fXGdIfVEtt0R170ev1$T8!lpcvka z^$CXBb?Rk0$Ic<=DWgrjf(WT!q!m)H(JOWZvyRbn8-%WB7GX2qazj#IQRg1QrQWa0 z8dwLn>KEL%Xg#x4zu->uN0HP&HL35$3#n&sB!5Qsj9i^GuLK$wZBic- z)$Z$`wn_a{Nu90Mc&UJom$9q87D=7)CsW7N)N?l^^}`Ic>(mQ$j-@_H8ExuCL`eM< zt&n<|Ua{0G81KKC<=d-_d~#US^^7BI>YpR*zCN$c62hgvrpu~`t$ts>LaW#B>kV3w zng27B`aQgmdTKfO_P|50yZzg|J#bL8neBIrHU#vE76Lkcdmx)_3HYoH0iOv0j6kEN z8lC{^pf+XmHnm6+fT;wemxX{nhTSy*SvtoE7+w|va)>~{AzFce0=;4c6fxrO0h-qJ z3?VE5ml2kLNp)rr?nH1=mz5AVw&;F;hStq3y5Co6MF{xZ5U_+72&l6et+V|^V}rf1 z#mx3Ei#DmhAUZPJf3K6fnb=gD`sZy@|6EdMt2JIK;NxZNYEvq2GyY`in3{S+Q(tAM z+s$dtCjS4?5AF9=FCYAl9qK>hyQ_j|c}MbhA4%QxUra9BPj&q_CFwL`r@zFvjaI+E z#FwR4?2JE$5&u!hQC&|j!X|whVUr$KXAI%?^=Vy}N9^=TAEVXplP=MUB;7Dc&)|i# zyb7DqdSUU>rf^~L?M-gKe~6^diZ*9_uZcEuz{{d74WfmHj=zdvIF^P+8yXry10&Pe zsgjSK`lwAgy-kghG+-(X)tfR0EKrWF=YTq$V;2_JD78HbG!WtR{}!!q`k(r=g^V-1=1*0Efok4^HV^o)A5ZC;V3h$!zf&WqAJgo>AUl=gP@WK>O zWGh;KC!!(ux0>IHSdQHHx){Ij_4};Mtf=h`jclq7{fjoCe<7i>)tW99@aZykwJDXi z8GkZ#ObxyCsf0eoP`eJjLg&~E;1(&P4ZVs8pXsk0f!P5cA8tjV(Jj86P_X}y)vi9f?1MN+?IQXj+%spmdR9{Ly8+{AAV{qKu5 zyZyVO&2Ime==C1@*=$R|tu_SQ5&{^3Mol$*)YL(3%I0lqkt6_93CMpY1dK53t_dj8 zIrb}n)0ET_P(lO(&d>@3ROl5Wpo$ScAS~;8CJ~l^I|xg_qB=JbZolvOT$a_aKAY1I zde><+{H-cYT9H%!6+^&gI)(#6`t#(QgXd}+Y)TK4^i0jsU=9dVqV2^&(T0pM(T0o> z(LzSYZw_WS_TOA-L&l1b!N?Q=s^k%%K5A1=Z&RZr8JJ2&=5rxqH|6M>j2xX~CxxSw z+LDn+gp?C zr**Vn=Y|@s2pOw}jGK6YjD{Ia%LSne@_txD#+%QDQ-#+>8!}!IZOC|0v?1d;(d#`` zU^teH)iz|T3K@({5ui#Q0qUbR<@7c+N|J%8WHgnGdz7PVGSZC}G6ot#Mg|ec*hMRl zk)v0Pj66o1jB#C0Kf;o64q?d{Rc8X>=8RcgRzO_xbH)i;RX=BxX+_BR(vUHSXU_87 z&kI%AjL13kcg(r+)SHe5a}NEQXg!B!1@`=)-7f~Sc{b@U+a&#^B+Zs;q>S1}%6QeL zJl!bIUtY?v)Hv4@zmWCdLb@~vFh9O;+LOkt%Xk-(uod2PbEUgF)cMJ`O@d6F`TN@vJ zwuOfCJKR^y|DL3$MBDQN(f0g6v^_r%Ej0YcPHA8WmWDfRXt*OZFdB`W%J|r+iQ1IV z+tejV1E$hYxFs}IC}3Y5mRZ^O zXu)hmEeO=fY zd2gt>5&BiphK!d)8#103ZOAwx+K_QTw2;y9O-c;MlJQj=GQJWr7?~nKl{^B}M{UaK zZEBPx15?RJtqK{NSAPsLGIWmpOwG`$kdZ}%Pn-K`g-@G#dc`h37BF7e@wj2keaAeh zs~JF8Fy28}FviuHLO3wyby*Ry;D4a*6s@cN2kI)cB4FG#U@YJTFluZ?>j7kSdpLl6 zCfdO8k!SI%b6 zO3?K*(WGk*_#D?-DXpsh9!rQslsrJ)yLo!toeEec(h zM(p;lC*MYEuYWyxPXGL&4Q5663=JcAfrbK`(R$E0aWUM#_`GOC#u3qmj02(#8GA$< zGM*GIWORJc7{2YuxYve^dqM^yQv|4zM}YdMO*y?yjgn+wDjCJwLdFE;=$ec&ont>? zJx{4E85KnM3G0ir!cSP&=ylQllG*MB`%PCJL+(=B?(Sb))Ah_EEC*Ze2pKEt+(WoC z&3;|h!1}~LT6v4svVXKP%^yYPiLVVAyYT`U**i%xK06=C_(ZfJ;{(x#jQ2zvGA@WV zWV|VQy<{*PJ7;{|hK#R;3`V91P$iE5^--I0dYc+0$-q=Ha(9G`!<3_IG75C=b(y-i zk4{o*OGXh9=8RLc!kkg2SL`E51>>fGM^BLFZ0O`2->q^X12l+D}JA_)Md0+4PB0DTO*YXGuzj=g?%xG4bS5CMQg zv;qJHdc^=JV#xaf-Dl8gUCj`}0&p2&0hm;02H}nwi@L0Yn7O7OG|remxTYU8s_~!~G}SjA3SmJE9F3pNlqNd@NePFfZizUMF8{ zG8_xW{Wf6S7cdx^67c_#_P)$3LVhL!$sZ^KQ|dR=yV>X)V&ME@@WLmKh478!~?w)3x*>EDPrlmW5Gu#u1K%X!J+{S40~YE{ZlRoD*$WI4ydsEHE4!snj$7sO!)E;-nyK-<9HXI{)d9|86@Y)1(t6pLF7*HsSO(F-o$4 zsVr1~ks`53IJU$>oepL)&VTNihYiAOj|>gO+deP%X}#<7l6urMXGmjQJYeo>OK04i zVepZxXN{hghT}MvhJJ)~h7fMfFs92gi1+;$are_Y?Z1edrxl@LhoNB{FVIkAGn#+A z8r~D`a~a$de!S`zZD{BfZD{BgZD`nd$^E_1(Dr>U49C*2qXi8+ga$^YX(viP?ZiiI z!s%^dl%xSuX(&As8m0(G^C6?{7l~Hr9KYp(P+Kyph;Yc5rxgwvb$Z3>L<7TpS9Pz{ ziS7+q&jLLy2m5d=85`>K;J8V{pe|cy*|>j~{Ucf*_;=Z7_@f9JI}I5_c!7-EMsha! zZR82MuOm;;eHD3v?u*D1bf1YfWPBo8$Y}dKgW*^*cD5j6r;x$O6ak{-5g7T? z#E`Kd+K@3T+K@3V+K@3RTF7YoaKdmb89gn?=n*m)nIb@xJOac=ZNlkoVw5BUQ^{CY zGBycE$7G}*H=TkGJ{B@Eh(N}ET7irly<%q|d5rU=S9ia?^0RyZLs!#}uwYz7STM%a zIg4;$%<8fN;_0HEf}WzaIZU$U}1Q%1q?3=42(vzPGo%6iHX`15u3OqVZc-vYLBH% ztPp~ZVQA1fRwlZi2n_2c6aJMek7xxL(odSoLXCWduA8}zg^yo+OL7(`fS1mS3y z&}CV~Rexj5AzE|(#+U-F2o1Xo4QKHJ4J9_CxlD9_{j7h{%SP>4d!xB26KkRk8LOgA znOGKW%EW@`t(FOfW69Xnf{a~41|w4hh>|CR_^3@dy-kdgWMC>86I&--ndp5gt68R_#oz#r1*02boj!!zIibr^ zh@R_OCU(-=bzRFumR98WvD<(#f)~KZKmBiBIMHQ0>(Ju=r`eT zpAE7XDjwc)XJ`MI8^{{BTsZzAx-MESTKtpkB|7K#+D|RtwU?=93AF{Ij0g{8T%r{o z$f(lmL-&%f3$|Ac!(G9;zsH@ZuIYNF5tf6e2usGQIu8(X8%1iHTUN&!ozO|=9a?Ws z=*%L;A4N(=+K|zQ7s$w@wk1l&%&kx|rf!9jaaOb;V_dW$^2Pv_YEH4}u|l2Jf}l5vVw zC>bSs#by>|j9AH7(AA6~EEu;D7K~YS77-4NHCeI*|)g~t1W}wOJVrq6%J9vWRZ=dPf-m{}QyL>ZV-eh4wzCPe!Hy~dTEg=7Ddxp-j z><;gc>}C-U59@>PhiLtBSRZ`P(<_$U0)~ky|G6vIle(Hggw5_1gw5`RI#URj-347% zM4a*SlQXo=`d7kLXhpKS$7FXAFYNX;wxW5a@Z)m0KJ}e^xaN5x@wI5P+kYk6MC%LD zCR(3~-s*18a4Z;mT7a=fz+hxb08#P;5FfP(r?-hw5)4cQqYfDMgUxpdN5{MUI-O%+ z^zIZeQi!nI@1zxW`^?TJFtQjY>?_8592ldznr?&z<21s8F|5u>gaczzm*o&y|4O)H zv<~@K!WC&n!00t#OyLDE%4|h57z5>SrrB2xXPP~t4H%mjoo~Q+AliU&SM*lFU^o_x z-WFi=3K)z`2_Q;)!+Jw{F#3%^{rh-xI7BJ2dj%G00e(!9V&M`0+2(<;Hf(T$-r4_)a z(JOW+sbkoAXyF?N#)htD7GW{i-6LSEsk4c26{BC5HL$+%_vqiJb=%*gpXQGu=N5Yn z7z23WSMY4lw#2)~hjQUp@KJp0PZ1dWmr&W1>peL&}CJ`4Sy&0Jgr;)PV5G)NM(500I-P{07$*K?S%m| zpNV{g_1ZB9fJyr0V|q5l4cDS2>Hi%oYwKDQn`)E(a*L$DEJN>XP2?7O{l!h z_>)P;)TF0hl%)4D)Q*#$rE~n&hZiO3IYdbMF#`CeUDfl(^R)I<^}Ml4E0XkmCh049rEq#sXETZ>>yg{LCHR$gkdTUgv{eW zu+%2D-X>s4N-&j@hEno?&~!{mY8MkQccsAHA=ST2C`lv2v0)FbaBRrZD^?nE81Z{- z$8l6AIP(@O+=dKtUggv#5DKbdt*&3bj0 z)P_Zd+I+{u;%m?PH+y_3+TZqHw z>2bU;KP<8t&GW-dCd?0eMVlJXE!xz8jeTKyuqN8juqs+;XnTIha4Ze4w4mV?p@ETU z+KG}+JMmF_Fk%yp_K=X#otE`1(9?3T566#o3(}dAxy@Uw!gY&e){GdXw z*!-Z1VWQ1{Zc@0atC>XDq(4O1q%W&;7vYlL{gN!JVa@En7e0yKtgdDhVdHlTVdFQg&K$zs46>@r z%7}{ps_Z3NSN&IIYqTQewBPJBckxPH{_(~Jo6-D5z`f_g7Xe>9@8(fve)U*BTrvX`~}ML@=8_p<&Lds)BiWeihyCqm|TCxWFmvGq0qOYUWu zx|glLBzxH=p=sXB&Kz)8T%Y47n^OneQP=!@b3(Knb$_)zy=R-g?#NLxxJM|-AVO{3 zPb<{c9KAO3#gF*Z*Lho8^B7tC^1M^>ZsiGGPd~z9auH!M8B^yh!p*N{by)#1>tCRA ziqepmi=U0XRonILOHso!pLcqUZ#cj>C z*lbI{Knnr}gaAgMsU{je)x<$>kW?%4cw_e$2+ ziRXrYZPg=MkNs<_(!EVt&tQz$#}4XgH`f~0^=#17X8m0poAp72bw&`bxK8M@EaGNK zf6hHbt5(ukb%9o-IJ|1IeikqC+f0e=m@;XP{5JDm4^O~{-)8}|g= zo#9wAUTZ2wXl?f7{&san(3Od~7?PZ1W3RdpU992mWOWmz5TN=3oAL+gu* zf|25nBGvwY0izEuRQt@{ZPEJ{o;3+QoOf5+%=>W$*gmQ3-RwxH0 zdd12?86#(}*zJ%z#us!wV+fn|+X$QWS#=f>uG+8ZvI=6}SNp597Jap^(~6XXtjYQV zyig9-*^K7zCp?angP-3D<=_X=rW|}L+LVKvqD?vYQuJ2K0mHFmWLuDt6*3r^B0!Wp z0>npc!s%^dlq3UF$w<8{Wc0lJ2au7WbF3T;zbs^A5uqF$q7}+Po?fwXP{8>3+@1BS zgD<&qFsZ8P#UV7z?_rh#2u7{5wPIP5;5a3av;vIB39F#0y~5*ox-g zYClf9a_~D6{Xsf_@s4N%#+#xI7>7k0FkTZaV6=T#FvGE69Bcu`K>>r2DFH;u6F_{_ zCY;_TMoBO*6^y!qahGs(Tr$?_9J}PwyHCJKAwtR6Nh_3$%szj~WztS7vlzqfn=5i! zFske6Mp!aVBPYPNlv&TtYmP4fdCs&Tq+T%aDQlu3r8HWrRQ+R=lGMmwSG4A8Y z#kdb67vtWGT#S25v?1fDXhX(9(LzSs7vmU?CF4*FG7bqDj7$+AN*)2?qc-96HZe+) zfvIFv_DRW@BOD!*QKR$A^JQ~6&RvjSBh>a_Qb&Z6afenY8SC_l9ZXW0Z7=lo*h%VR zi%Ne+R_54ZqZI*T(139gFMv^CE1JRh z@W!+DBDMJye_ZtQ=#!#N$rurBz!(y3z!(s{RWKNi1!J%U7=r=^BU1v1k|%)ps7*M% zO^lLYU@92JjDT^LaC8htna(jV76`Qkqk;%vT%{GjsL@M~CGIOtb&Ml>?8|W+7#q5p zS%k%4_bUR%nmU^Z2S&dxYhaCfFz(ZO+k=tjk0M|U888O$0vOp>l3+}AyW@uep&>RWKNi1!JfM7()UEBU1v1k|%)ps7*M%O^lLYU@927R|Jd^ z!qG7p1v2(K*0bqw{1Hdms&KCgw2Uct^N3=TsV6!a%ueSi;bpe18Xr_sV&opsRo3MGCSR?_! zQ~=WZ1%N(=-7x@JI>(+^9o;Vg+qP*7Xb{ECJUMmVilh zW)SYIb6J;_5F?-KS?76LZ+@<4omE;90uCDjR`5b;sIwWz3<10N_g~z@XP+E*1ekL0 z;c=H~L&JNb4GnLJHZ&X+Ej0Y5T^bmIrQvW38V(B$j7HN=WPI9*iQ0tF+r%YF1E$i@ zP#PW(f{tlO^*5b!^!E!5X+)r553N8$mR>@Gdy*uFVXi-OsBq^TW4fANgoWW8!oo1B z&N#xAgK1rsM~wP%aDvv`z8sWjMPN8$V3@%R<)Fe=3>p|B<>324ch2$8Nc6XZp&Z;4 zZ2i^v0FDR%j6gF@G<>FsgW816+r%OX0Hy*^?U!<}$gn#Gpibx5 z+Z8tmsXZPv5CMSuv;qLBfusg?u&HX+cOT&gbJvgo&4C=CVmc6o|2Zu+r`WN)zkl~La zG#oWF4B-VDa<6WC;b;>LZya#_&B5Vy`9a^%@TzEYaM&C9(f`HxkN*FDRbm+62P^`6i!V)m8&K$xKu&T?-i1YsOkxR6u{Np1v(=xAQa&J)_HU!+o3j{RS zjOI_eo|8HfzfE%iHuJ>F;SZkdYiZ;X~0w(Y6qk?tPp~Z zX=ujJmFr#A4d9whGAXL20bke@8Vb*1`*a7LAZ(I zgf7b>zVjb+IYevKf6%2sD?-B?hK93vfrb*B(R?1c`e8VaT>j9JVQ5$oZD^PkZD^Pl zEj0Y5T^bmIrQwYhG`t}+Fd9uek@0CKCTbHxZxfd!4VX$pIV&{G5Q2_rsM0w`!z$sm zM~WIE(6B@+(9ob)tTwD;yk+lX(ocKz9+dSg)6?eu0FI@h8)2P3gsTn1x-5n0@79Uq zPFk;a>%=ijD?-DYhK3Qm=gj?W_L0l{!EG<>GqqtS|Lj$TXSV-v)DiHf+_-gHwA{G$ zk2TY+Zf9ZhY^L9Ak?A)j(`>1xlu`SXGG4U_kGC0fGSirv>B2#|on@Ti#WTHy+gVC< zj%9k5(Ai9v5h2r;XoXBy=@rX#4deCkR~FVb`enag)AdXvY+j!tY^GP$d4O=4?mZ;S z>R9#9^lqg)wC;SScPpj%qsY&c$4#dD@WOtdImBq1jsn+u!_SnLd&3dof@o6%J`!ze z!26<24R~9$)PS~srervljN>iHI4)!`GDUzWc?5`$+Jw{F#3)Gyrjn68BsE}&aKy>j z!tE@1I>+8hGC`;<83jc6ner5^@H1tJUa>2SWem9;&Rt7d(AA6~EEu;D7K~YS77-4N zHCD4l($MPCGMjAy$hQC>F90wC%{0;QnI;Zu6E<%XizEP;3P5U50O%R~0|3a-Ier7f zpa76Xgwk+`Rwxa5dc`g#7BFJ(&z;oO3?eK5R}dC}33a9r4uAz+RzzI#AM`mxYsP=j zr(#-Re)yIFU=c4=h8kPZTp2E350&A<^-vi;5^cbEU$g<^ZP5mdH$-o>GB6wq##=4G zcuT-wWJ&;0@&phcwF#%UiBS>^Oa-H^VB94f9ao0+kYaaVbMKIVkwS!buJ5E3-npI` z+7^EoViv>Q+47ydbA43T(~YoXoJLqOhSfQVaC5~;U6w=459sXR7_G$togEZuMM}d7 zL&g+dC=F#c<499!xG6INbD8h zQ%y8{s)>Wzgw5N;B1r(I5>OeE(lE!cJ0_q;=h&=ajgZ=7Lmd%H!yQ_oG_2E0N`w17 zI`w+<*+T#8vYu6XS^|#XSOR(x))_!J0!DRN8u5`oTi8SEoIhL0(TWf-Y6v)q7YHb@ z8O=`)9+K>uCkJ1RWPNWu>%VR{>ujpc`e=)+k4o0rYE3T@@abjjY7;7NGyY`OF*WPO z*Cp#`8EVH_FVi`e^##IcvtB`jtY4)SvR#_#cd;Y!2_i2s!_a>+Lqe#|Inye4tg(E`t@U|D;Y?>?9KXFF^^NF`5(dH;H zFWS_AtD;Q}xFlMR0)N#m4Gh83aIysrCxr$^qiH8HKJCOrZ9?d6;*z8RQ)$Q@78*tf zLB}){=p6fTVUqA#8j6TO!x>tEhBCckG*mF`!!7qSa^|qC>zP1U8tx%%4OmcT1>tDe z&}CIbum7oOp4MLfQ&WRhgod{b4V!qO2BePgi&xW8U|`14U_KB1vS>rVF42a7C)4h4 zgn)n9E&*(|CE)EA1iUQ-Fak|A(eSAz4r&uNZxf3o0hmfa`iKzF$FMslAWP@i1ab6; z5RgLz0*=uN1Qh5Mn;;f3+>gyKx-*1nUCl7U0&pE+0hm;02H^l$)@3EcLI1Ms^Rx#2 z%d)GqA``@S3;-*50f4&MiY5Sh-**#4ll1QQU7}6WH{urx+kUkKn`)E(PK%_!BS~kg zHM>N>XP2?7O{l!h_>)P;)TB2w=?@rc$4O7+ntny<&q>nLh;UlChgLW(%+f1%TA0Id zwdYI+ei>E{qO>7(k5BivcRv@Xjd=KN{l30hzJ)4~$1NYdXmNuR+BNw2UK z%}4&%CDG={pN%9vBU<+KU$?ubv#B=e@3u(#yOMOaTC+<8e0CYT+Jws6j6a!lOig+< zCwuxLL+v=}bvnmyDGx@cq^FKH)%r9>{Oa)FQCZI#J#E&H-sZM~Peq#}|HqCDmq0oYcg3ypZs`=ecWPI9*iPAs_y-i$_G+-(XrK3W_6d~xCh6uj~Amk9XuGIq5ImA4sxGV7R{_53l(`pNiE?aOG}ev?>{&aoOWO&D#~ONfy5 z^Rz$DGc05b5RQ)PL5|L`dN4+)Eg5-4AmaqBKt_>X zF)~URw;vuiw=>I`z^txk6k*A@g|K8yt22jiWUT74GNN}$>%k>jdzZ8x)M!P>7&Bzt z#S8VI5f6o}2N#ZpdhpTFP!HZ0z14carrNBJwaEIIWSydd0Gy$GCOGJo?xpS)b7L^doH6FCuK# z$J9BCa9N+#Wd%gRKj3zX)+zshTbWj5COB@gK8F|TL6yyDzCOJ2dAL5j__@ovsRwhS zO+A> z``lyq4tHKStgG3eqXpw#91F%E!a5@e2gZah%OakBt>xeltsTA`6lg`jc;A3=7B7HN zVk?>-iJg1dfnlDIzx;9l5K5M5FrerLMHe}3;He_5CZOFJJdaEUa;aD<0XhFsYLIxvK1c;JHfcU6Q zIK54bl4M{i8HG26jB&!zOh((2%MzVqFRYv;)Rv4gA{MSB07;Cz$f~Z~7la8yjmageZN1ayWSW+}#JirTJtg{uv zO+PtY`Pdyx%q^?skKM7vz)%uxU?_?ynI8^d{lA&Usdk3+P=@gq;K*zu!)@nB>2 z(*rkNk}2n;u4fQoX}E&0G)$;7g>W=1=&~Z>uz&B`8CtmuN<)QKq)dEhXjsGxG}PFP zx0+}uJ?^r*?C(t0AG>m3%0xl5AtNu^kdYH@$jFKoGX8D5WH222|NO8886OH6j7$+A zN*)2?qc-96HZe+)fvIHFm5jTDqvJBMPUjdIy>AH_DMTm}J86Y7k$J0$j4Xz{@c5}M z6QjDCZiEHnG{S;0tj~6ka$3EwdGoZwA>j z&|juqnK19(xi7ytnWW!||NhkWyLZ@BoAfg+l72>#&Q@!7iGa^8V^^C{d7JSkla8rL zue>GYV2+`7ob*~qpF1|J5k`A#s3Sr-xI-(HgLQhzqpoLcj#DRikYFii&RDwLo7VbI z$a+@kX|sL=$7a13VVwbln@*1EvNYnztR5Wp&^kJ+aEwC*02M6ao{iExST*JTZ?YoBPM@6)>ei6%PDA4O&XXHB99@WSq$9Zmk!yz8E; z_2#GMlxS1m*MD%n+0`4OrM|cQQ!|@w0XW+NfU^PsBhX9}4WDV^pf+LiHnB(ofT;lF zMrBtYVc2m1ws13QfzGi@jFW`a0#HPRUHuHLu&bBp6$7Ax!Ih>dzLKXm8|Zo_5SD;@ z2)nBOP^Nir~% zjPyw%qmOWOOh%T@F)~I^3K=;>AmbRVKt_RHF*1r6aWbZLJ;Mk~#&v`xV^WvU&ePiL)r-$nT9Jdm$A*j*yg){s&1k;b^xjRx0^0Q z_P;G;q!Hnuv4>VTXk_UXJ9W%q$kWgAG6Y>sFT#Rx4q?Fh{mOmS{!5IA_3^!3zhC3R{siB_nbJ`%2`u>BY!z({u6PrvH0Z*48N^n`)DOu0_(% zNz&PB%`Oq}*=6i%k40?8pG-QYCcXN$l!HZv+HunBbdJ4TZG$k{14RQ7%E5hFp&X>% z@kw`grlv9Wy=bph?vO7Xyd&#bqo>XKaU7fVeuQ;~5Uw1I>9P#s_==W;{j}a%(Q=Td z70G(ZWPKbjWWC5{G~b`{NV040Px&d5_3z_Z|8=`rXH#v~OD(cqlB~1UnqDH{v(DJn z9*o$GKbdt*&3fq_$@&yS?KtZdI>#<7FB3+a^(rFl>hrY1u3o2C>>$vh$2atPkq4b(VeO??-+_>$bliIl~`Cvi^z5`Vd~odhXqAFTB>Y zuYV&?BmOyAzZH2(@p}9z#edpv*4b2>^-o%4{S(PLTdnCO0zT`EU2Q_;ZN{I>I;Lhl z|E^^HBtz{u>qR=perK8{j5g~fM9BJiS|RHddc`gpS25%(yRN{m>S`ttHt7!$HtEai z+(o#gcNb(?4eLXn^d(voKI!YUB1u1QlHNndko0tcC+M1ze&~!l+MCy_zbe`s;rEI* zNB9>-%MsqZUcIei&t_Wy&bI*Iya2!mG}A=GXPP*uP1w9mERq0VDgc>+05HI?I|d*} z=h)nDjF4IY@`wPy30eVwBE19vSL{m|v8z6_x|&gh1>hFK0x+%49Ks#pS9Mt#anu8F ziPo?OphhbKz@!1-E?$`WHQ0*g%Yh%i>y8!Xq~HU2kN)%McSM`1-7k0FkTZa zV6=TXkl|P`CR>0pDPS-%C4eY-0*H^=gwxx^Ci1xjX+^-8 zGGNT%mAd@*IjU^Nho&^7`DdSB{-f=~JKP0_|3Ib(ceoFt{tdccv>~Qfv>~Qjv>|3A z6+WQ4CfX3QDq4v7-`g!EjMEY`)q&I{ z$HX+~96OeDpAur$Nk$;%5v@Q>`cxA!8H^Y)!@8OcI$C1h#j(T;BCIolaKudLvMk~q ze{y_6m2NEC)(7N z+oBC6w?qpiZGX{)u~|wkw4mgIP{J@32SVm?AXsV>TW=GvBqf+iN%@peGDB!Orld+| z_p*~O+!g0l;%*N(HAJ9fiB_PbL9f^sUDh$o{>*>wb(_6ovYKT&S|$$QSW3DP*6BmI z1J1B6OCi4WALiakt9nXbp_HW+q2yCT$p~IJ;N-`W2b{C7hXc;IykgUUaZ)(w(-vTSDqt`&C4eY-0*H^=gwxx^C9U~FvbZ-$6%D` z96JG-CDay-G9rL+iB)=3)U2o8m#p`^{|96}L+98OV)%W@dKM9~eu!4cdY)dftQRocJK&eyJxr6jnn8q3 z`W1vt`h+@D2zPK;&}Bu$ynjaK46Q}~j7)`ABR6+a^?WFi+?ibyw~sM zjpiV5TeJb-mT0rvUl%RAecSKXW3w#)pS1wsGXa1RXr_sV&opsRo3MGCSR?_!Q~>G< zz+HyjyxX^Z-|IS^V*vDiAONHg0f3#f0sxs0ngGaR!~hu8)pR2)0H+ZafMIn`A{+pd zx-5sd*r%5skJ0+9PcJ)(wQVTFH2^fq_2_QWiYI{7WBLWzAXaz9V=@qLCsnbnh^q-d1tkThfaRkSL(TlLo0K$PWs>{-d z`~JtvJ+vP9A1`yXB0pYE8!%4d1uzP1Me}zZj-PN~n7bQ~i8f#y5^ccPFWP{yN3;QB zr)UAA?YkQpjs;`71sKx;1|w4fh>|CO_^3@dy-kdgU|=d3#nS@DS;EmV7-c%gCJGCL z+JaF*gkLMJ(h9#;)aVtvZe7Q4-*wRI)*HH>S%l?acTvb#Q)d(5CJOz!tbujbPaE&k z`q)n!)BI7SWXu>c2Jj-^3d|O_y)a{HM&w(8`K2y^dhYz6{)RmKzU%+i{l3+0D{PZZ z?@WvI&PaOMJk29R^?78FY7-N0GtgvuF*UupqTIGJ!jR(W-NJ1v1vYqq z_WLum!hT<-SL}4Lf?=Y{fAVz(UCji-X7?V#?)MAotRP%=H*{GQvB!V5W1d!@|7=Ht zRwTQZO?Ef&YT+_e>OQn!$?RfkcGDk9cKaAo$Jx!&IhNhg4<)-fM9A(jS|Pgydd0F^#4u6iKbPHU zUCl7UX7@V6W_MDZ8HB6q%et(DsQHg5pQp9tKcZZv70K@BCc7(mp{m!}isq{RaBryU z_eGnken+&a>Pw1|?^1OrpS zXaI(NW#j|G5eH)nH!G#iG=2BC|BQfLdX7B7~Cbp4Z>@W0S!ce;XbVZLu#U_N~AI3AAug6koBz5)6#Gp z$I{S`u+9*|9R$X7S;koYWoi3qP5GCl1|?^Bm+~) zC`||%Q-q_LjJD4TDs+y$Kxvs!TQaJMK*l_+Kt`Qju`dKTzu zIoO9|$=Fb*2gi{ysLR$_mbswki;rmSzo6%f8U848TJVJ-V+b#hkvp3t<3TNuakm!8 zSP^Z=SQKr@m=kTtm=V2IG8m2}V5$f#me?4wgTA!Ak7Gl{TdJVaPB zmesk7aAb6UB+F`8)BXsuMC-CYf~?bu)Qqc!j2=1$GSVLr-d15}Mx1dLe&#$CJsMuV+ro^zIG-8Du7#-wNi#)N2l zFcEDJCZg@ZM05m<=h}HRj^S7^W?O(UD_}4(C4eY-0*H^=gwxx^CYPP58fJA_0a4kd2ar>=uI|zU zNSRiIhB-sS9A5aDp~_}N_6z&e(^%xa8>5l;ZVY$$-VHX@W_qqgrspKnY_+D82>6sT zcC`tWw;6vj)0mp++Q(7?R^mh5+Iu$|bdDVyy3a}0*NJB+0gq^f5|BREbj>J(;ck@e zm4m~uu4jXuHtX-=*sKpCtTTdeS)b5lS;R?y-g$`DJN~@0Kr52zOhth3dcULxSr%h=T>RNiL%$*f~)*30K4 z>oW{B0{GUlUZr#FO5rMDw1vNh2w7jE6|&x-SL{mRI)>cqC|U0<$$FOQX>)u4$7a17 zVVypNn-UD`vJ|4vf4gTVt(V`_3X`Q3$@-Tj>mzuf^5;v*%D?;baJ6BlXjAzgT@ELh z_eC2r?ua&(e@S$t@*BijJ`~MxEE!+6Amd9RgOMo$M9CvSeAFhK-X=y#GBA~lLP^LN zCmbD8P^RNeRzS4%qQDk7%>OIUHp@aj5iAIG{Vqutq^FqEZWd; zLA0UaBhf;`U-Ca`YaYN5EDhIN&~RO7U^JR`BIDCeOw=ZX-X<?cCQ5Fyyo zJRna8IikCHzyu++1QZZ&{_3y0%sKt`Q#A6wvLo!;UZRitGRr#`?JS^-;VMI+*UbVJ zbS+~DoB!JgoBvsL77;H0Yr3q0c zLkbaS*hwqUkeT%Lq+n}97Q>w_?w47^sII3QVQDyxurv&-a}wcbnABxC#Pn-=UUH1q z<=1r9P^1;P#58Ycn8LGjMSD@c%w}ZFv7twg4bN<^&N~ABAty)`(Q<Hrezpv`FuQq?gUpJTg?DM+T`jG4VD7O{N!9(_5U9^qyr%9jCWU z=hz)23&hK&w}J@iy-F*jw??nnb)P!M3Hx=v9```QhOTB7VRO0rf@F71olS(xZoe*T zU~TwU>fNXH_-oB>nm>wUchO{b054Sa?1ki)7mk1I_G9zqg`=X)G5(-vvje;$+Ux)? ziIyGUuM~z>uR&r67KX(ZFf0lTj7GCgWPH|%iQ0tF+r%Xa1E#`|yCBE-5ke4$VGF-6 z7U&$?*Cz?Dg`tQDRs9UDP}R%yitXzajQB^smvuc82us5~gx%K{)LB6|8a8xU6|v~A z0L;_6>8}7ZXhmqaVQARI3pAuYP14Z)Nuc3zDIDW}5^ZSsUbLa%8_`>(fgxBLZnU7` zhS0!hH0?yjr=6InO$fbBT#__kDh=sRg@!&t&@l~JI>&xS8vRsg$RPp^$7lr_3iOiF z;EwS{jKP}^-dxJ*j|J1Zo?(Qg;X1<7FsaTA!d)3y)@3EcJ^y3Dd0IdE9}B9qA~f7I zG_2s+WBece?K555>ug5zv#*jv;KggcAWLpMXsQ%{Ji;O?nn0%QU68BdKwY3zK2%GdX`@H zs{hr&&+N=Dhhab4IJ+zD&icl5J-rB<^>YZD^-*=k5iaY~x-5_Q*w6D%&?@$gnSXYfJ|sIVEs=5W7@e{$B}IOpd1=EZp5oeMSKYtg0#d?nh{fGB?b~rKUUNSYJx|ili8fP()1nO+?}|2H92YHM zn0pMKYv1|?^1OrpSD3t|_DZ(BXSrBAE79JEY$EeutJzZ^7A!(R@n(VMVtJOh>lDS+R8seu=)SGMgG5*{4*L&G?DR%CMIeVLT?k7Wd1QV|M|}( z|0fB-mhxYuL+o{9&loPzs{0v3jaCGVWdp`tyf9B}uoca3#<};NOEf3k+wX`rNna8z zN&j`b2LLwJ7J%gzNne(vv(=hiBH**j*wrRf-e&yCq+@E**EQ*z47Irc{MYXbnD(Dp zlKTRtCD9o~PEP3@@DQzcrgRQi zpcT2)`;AHZS-g<+5?j%{d%u6(CD-iU1<@wydC`&GyRDkerrM-`(<15LNYdGA%`Oq} z*=6i%6Dn^r{$$cIHR#;rtrA9C(`$&3^d(v$=?!|tE(NV)#4qso zUY7MN)6?eo0FKRiH^Mr72$%I?U6w*T_LqHk(t7GI`(|lHvi_~f`UsxQy1l@kznr|l z|J2|1^UU^#{$n>|8X|_~T%BX!x8L!%e$J>lKnQ2VTbm6jG z0Ul>~@l0>wS)vl1V?XT85;~jdvWc?4+3OOma0R$ZuUMvQ7-j~r`D8#Y@UQ85rV%!; zPZ2iLtLi*JxJ>tcF3ajzpWo1T;NGECxuHMorTC*rrf-`}_u+;8JM%ej;x#Ay{-+$C z5IyGVgPFf&kGVs+nZIR3n|(bkTK4t7V8w0i>uk0q;C2fFZVLg7KvPXLe5#3q+Jw#9 z#3D%mrV^0-T=w-Lh8-th3zvQKbdK%o6NJ}Nu_^3@dy-kdgWMC>8 zsVhQ8&y_!bj0~M)cLfh$5i+ufK*k|jfs8!8Vq_FBP#Wr zDc^!FDrqszNI=-}}yhv4|JIsIe8zmw%S#!{wj(`EdE?s%QhoCD8_q z^P&wHXG9AaZ9ihda4Z<#wE*Kg0fUh#0Yu3YKz!7mjM&5|2?nNuQCBeT5{`~b#yXv2 zbHd(=fRRFk>A_A~VS13MG=Y)Dh`rTnR9DlDuwa}pD+t(2C^$dz1f7ys)3AW|RB*%XRmaJ(K5Mb$0|Xd46)+>BxTG z*4Y7@YV-Vki#&fXd1k9Mp+vwZl(DN#sJzYilX=F}Jf~+R&wUKF<3oLx&aqFVjLu5V zbBJ)LKSnDY>I?LeIiPzNZV^LHGuC3vTg!s%q8Frr5 zw0|%>HDLg;Pcl7sumNR=T#|33mhjfAq5ZdaIi~*(RIbdo9v?PtwcgX&xD> z&m)6Wo0xc;fhN<7sp+lG$+e(Gh7?cl7On-==^RV%2Jy1>y@3eny-zEoH+8M)T2LAz zev|j$HCfLZJ#BiA@79e2O+nH_xKc(@kSC)(`bJ)&g?|L00TtKah2Y)e3+1py5qfDve_iH1)# zaZsDEd7D@y3BXhWO4p>?PciH`0b95hRH1Y1#BQ08S^}zwaK=ARE1dDy=_Nb3yV&2r zkT;*ZGyd)`Wi<$M59vOlb=-eQH^U!A0Qk`WFob7j z;J>k#eRE%O`N9C;9(?7=&u6y3RdfKDFP|OrFO?)Czwc`M%V%t!P4tf~68)njnl06g zGHRbu#;Z2r@it>lCK^){o&QpH^^*)Qp6D&?>P0%o5`hF3W0IOa4dOC0Z-~N85E;kwSjoB)W%= z;jo^*zU_r~Orm%3PwF_I+_Pu!f5jgC_&-|tJn|6cL22>{kWW6LQF}FF6P_d!n94-vy6pS|L?X__7Iyv|onuUl5oOCn z9ub&0K`Ss(q*siI5=M-PSzXO2!ZL9SVVRg#XAa@2|Eex4Bl7+Zk4v;p_&Ypmv?5Hb z87A)H1tuD7Me|ji+c%!|S9O*|8z|;Q8!E1fHdtH|ZMZluTEJ-gIxxerV63$OV@<$d zWJ&;0@?a1jwF#%UiBS>^Oa)_I!Pq1m9fOgsHho2Vuqt3=5CM$+v;r78dc~%Fc?>xR za7Tp+T}?m2f^iXH!5CBLEW#CwSzT5@eDB{Tc#76N|2Dxgtq2$o3>b5G0gNhJ(G14@ z?(hS__o59L--tF~+z@TRxF*_waar_M!C*KRj0Y{icpzXfG9`d0c>;)!+Jw{F#3%^{ zrh-wcO2t?q936wvptGFZySs(EzY;LkiFp9y5v>45`m3f1V+P}^*KZx+OYQEBWW&0e z4LVvd-o>$C3?i&Ef^c9==&~&0%cDA9JVdK{ROgEYS`jdQGGLs=3t*Jkie@mr+8w}{ z6K%kl5pBSj5^caZE82iDE_$nAFdPfUPc6XsNx)!aN&r#v1P~v!38%M-Q4$PH1*80x zfH6ZjItHUk=NK5PgxVfTYKQ>F60HD6gI=+Uv5q144mmJ-=Vdj^bhH>8z_DO-BdpVh zaEFp%U6w+8HKmt|cG6my(o02IS`jdQHeih4g%gSVeDb@=$7}AYf%$H7t`;r{XGKfW z+x~7cn`)E(bBm<^EJN>XP2?7O{l!h_>)P;)T9^YCF$b~wd16h=o~wJoF$Al z>19Mn`XyQ+=~a5gl3v4zUmaM}^-Lpdj-MiI)>qYefN*CIy$iCej&;o6A9jb}Nu_^3@dy-kdgWMC>8*##kEh;VdFMxM^GndJnbwqz6#fs9kM z0vRQG#mFdQ#3m36x|%VB1>-itf-$SkBEo^OrpqdbH~e*ltF(^$>k4&Rk#ewZz<7Wc zz*uK1nvWCfli~GJYoZMptD+4U%c2b!3!)7ev!Vrzwr7?M$AYom0*rM5gOMo#M9C9C zeAFhK-X=y#FfbL2)S`gVv-k&qk)d-8jNwHABZ~-N9HJG#$kR)}aMv3O81kugcN#jW zs~JRCFs>jh7!&GDA>46dL6;Q~U-=JOoT0VgKWI^*6#?TH1I8j=I8M~qisqjVFC1~# z8%)waI^rf1Ch6~smZY1X4((;eRu`GrRGai)S|t4!Njh7t*(Cx#yNq3JLgj77pG-QY zCcUmnzspcNt_JILjvXg@Z%EQph>-N1v_jG|H=1URS&Y~1LuUPQ6?s(G(~YoMKaH?i zA6Dli!exC@m*o&&hT8{dRm1HAv?5u5WU@Ym7s^4I%@}SvPJBP=vTlA;_;%D~-IRcv zq74mSiZ(QSE?Q`4`!@xKU}<>Nf`&&zL-B^@cRP{sX(uL110nP_aY@pEsWen>NC}uD z1Rc{*qjQXgHNtC;4Ru7I;SQ}p!#cfUHz1~NGD$Psh6zrQryUrJ)yL zodJY9IE?DDG~(MCy}@`7t@@0=eSlVkh7Ci*NxV=43T#I6Mdy#cb8|&Q!2931xuPN9 zZPA8+H$)2oZC`X|vn>G|EeO~U0&+Jsr`w5!Pc?B+0tlP8iA9nCOeLUrQwTWAusbH8 zOy}4ws0)PD5>P<|0cNJtXBJ`ez5A9Bu%^x?!V%D~%Nkho zDJ9@Otwnh;b=USZe-t5L(-1I#7YNASO1^pSq&!hJj;UGC-IA=2Fw~B-UZ8U<>yw1hX1$0ASwBN7WW7wU zSk@~TpV)_wHr)@)%etBggiZQAgx&2I)LB8egTRI^t0G?YcMZ+cI^gdbYS4-#{jo{< zCSEuQq-xs|Z!`b&i!Pg_=Slj$x;Al-?$RPp@$7lr@3iOK21B)23 z-<_s)HNyxC!*zs(VN#tLgsT9{x~zn_>5l>DY1RBOph_zO!xIC;3SOuHb+)4UA(P%k z2LQj_Y~Ll?B>jmzWh6=eH7jdt9>}KJq(5nq^e2*Zwpz1G1blWGyV``x+l)V%bWBZp zLzDi1p>~|~)YtkT*e~*~fv+X$X+%i+9$F#kS$f4PKn^2*y@+0}*JrPb<)nT52i*X^dD27+jLotkKcJa2&_N(2uar5WYa|bCIpsYfcIxKRsWYaVG+Q!cWf?(eg^MZMxgHy32&k zvx!bU`;WT*>@R-%$Io~D{qtSF{gc1{&wu=P&v!ld{GUDF^_N}Gcm4aW)U(^W{?i}- z-FCKAGs>uaMj5Z#gvZ;AIhkloO>}8VetMo_c=1GU;gw<)I>#pb%Y@D*x{8S0V?Zl% zj{&`6yL|)W%OQLI=MMbc%d(mUI@+}E!?B6pP^SmSC3;Yot+VXlr#jnvL~HOzNY)7!)-2?nNukzbYyaFTGu!FVR}uDNF-@0xoi@~%0m((k)| zwY^B^SOu6S)E0~qB7kw8Rsf?yuh=A@iV^$H;i|4?5@Er3h_GNRt8*9O4hP*UvaE*n zlAjSS(dzXx!gX2^Fm@U+dgvIyNUtP6bXlAZmjVi+4FGx327sJs0pNM946QB02pA{9RrY~bL^C0jF4IY@`wPy30eVw zBE4djp@hLtiI=B7Ny&-etgdGiVF|c}umnu2Gly^ltm?8d;%ooZ=_Ojr{;AU%tq1|# zhJd?x;TX_hGn#Kd>YfU>A8k%L8sr$z_U%V(p3QW3i%fS*rrA= z7?=u1?HefpD}*Bs#un~DYS1}$4Cww=z*r~dVHWs^R+t5*zx80ax6WlS}|}3K)z`2_Q@M$q7(A;vYusnS`H52STed1*6BkyGKO_o3Q_iC?4)(claZwrA!C;zV+60%J zOVD6w$^c>V3=kl-iKn*-QW6bJMWb+A&=@Bi9ivgAa}14HVr|hVBLW(iXazK?^omUz zY8Z0QicA~UbUo7u3&K-`MPpT+2MBjY(OZ{gb*zt0>lwuzTIWvd8AXaeicA}J8#Max z!quZpJ$d!$^1Cj(=IT*dw8?r&v}FC)?Pi@#wOQZYBI~;)>uj~Amk9XuGIq5ImA4sx zGV7R{^=w_TKEzO)vmV||-QsK^Pv_W?VuCQ*tQQbr3UP{7m_n536`MkoF=7v=FX(E< z5H{(z5jN?w>MSB$Jy_Fa6-2?;gR8Vo`Fc>N6{!bllk^98;YhL0R=j1(!LCpaW=0(} zrW{O-Isi;LI4jzegK^QO9Gnzwz!(uNVEo&5!C*KRjC2by(gFq}Qv!&RCxG~ zuW6hXEoTvbu9tx!VMcie0 z@e;6whZxrB94i66cO=s(M9B0`S|QV!J541Ziy?11c9X?XT}?N_Ci*nOCVE(%lL%M$ zCv{m4(SJ$rGCW4>)k}JpVUboO(R)myr|?1vD6f0*I0)fcU6QIK54bl3-ve7?nFx0_F%u z9E>fTMbzl*UPph@O%~S(wLLb}5dn-lv;r9G^pazPduTPay6uI_2gkmhIXEVh#r{=U z&ni7F8Aos|8NCSW3?N(y7}aHI#H{~z(H>gY{I`p8v?65m8Zu7e1u_b3M)Tt>(>vVx zrFp#Nf@nj=N1_cG?~68Mye-<0@rGz2qwQy07>*^Qw*?u!LIxvK1c;JHfcU6QIK54b zl4M{i8O2p0<1FFmn2a)=-L;{TBV&P3TQVw$K*m*Cfs7ixVzY)i#$(=*{l@A2?!v={ zu4WctG1z@qz*tjf6XC$<*JTZ?ul=J8_h~KrM;X%mQ3Q-W1I7Se03&-hdF#=R_rk45 zj|#3F7#Qx0HZa@~ZD3duEin9+|A{&HwEV;wL$EOPwSb{dU|=+wbt2=lPE6D$gx)4D zNfoft0K6;!Fapgq(eRlj4r&uNZxf3o0GJ9uLjiceusa4I z^+VI?LH`c|KpGJM*h4D-kfoOZ;I1&{Fq-Z<(Dn2pECJ^bmVi-p#u2UrOzW~dV%L6s zXz2v4^nQJ4sYEM6z&=C33|=?{RM?E>6UT?&x&FT+>-WA3ml$u0Hiv^-q750>MVr!a zMYNQLwoe=xjwNGX3o`Zz8H`L3AW9wq;-mIh#3n{bGBA~l>JL&H770hkWYp;#D-9cj z+8!Djh(N}DT7itzy(Ti!7_rhYcu!WdMn?GfGW=15 zj8_a9LwJFVTq8-w>93#hPez{-ZOAww+K_Qfv?1e=XhX(+(OV^h;aDKL?Giltw2VFUa{Fk6(e@j z(yFdz5@Er3h_GNRt8*9OW)s~%%CZ_(&X>MW4{5ThmHY^^pDB&%$MGD zV3_mFZqWvejW?Wcz*rM)z*rS+z*rV7V6=Un$#5(f`&)pqU%+5wN&r#v1P~v!38%M- zQ4$PH1tasLfH6QgItC+0=UB-YBh(g*JR*Q`f>r>dNUvDQC}A|+%Ao5RMOZR!AuJiw z>dYZr$yn88WyBr-f{jbG?)n#O)M!P>=r?5C#S3IK*on45?>XPl@IbWC@EiUo&$V-+$q+0J{Vizd7aACirk%+6v=bAxXCpRoNz#C+ zG^{HPn}lFXCz|Q|O(&Xz_l1BA!k=jFr{PaDbM%p)pxoD!^B8WHd8XI>Tsfg@=||Z7 zUqsmakEwGO;VQ$dE-N4&`Y$Vw{@|8scZJfq5HG=D2$Szd%_zLjtz z@>0ZWq9xDme=Fg>%kw~sJP$~o*=kKF5%76t>}nG#Z!`X6o-sAgwfnNyuQ1e(_xc8% zV|#t~n&f<)c!s_H5v{P-r`P=9K<-|^u%FDU?U9MXu&!r=o;K_6;@GSYBCIola9N+w zWm&`x|G}(7v~KwiW))~fvi_>c`dPfN*O%CgqfLAL>?!x7l-cX2CDY~@Fe%#X^%D^q z#^N-z{ZIo#uzUThEogXEXkav&b|T}`PE6D$gx)4DNg6PfhVq)wFhdABrlCsb*bh;w zgx4MeYKTC?60JZ(gI=*S&2@~62X1_pO=pFM-UqUtWqR7&AHcCRbR(?Ohj26u>#`K$ zyH9l5xRciECpvA+(u&aVnxSC?FVK*GkUR!FSq;a4pI5^%;0Mu$hHpiiW57+(kz+tx z7oHe`rQx*}G`uD>Fd9uek@0CKCTbHxZxfd!4VX$p;epUFP6#@tp+x5x4YP#T(ojYO z8ZOZaG*syoqoIZor(sRkGmWshe~Pd)tg7<>;bsKAKgqJXvHZIe@6ej^?@mndM-dth z7#jNU0u7m;l9!$*?}ayMo|U7$sSV?z4GkwFGlG%$jNrHYPuiLhFa%4(ffh6z5E>Yb zrk%+6v=bAx38A-%OOggmr6K#1&@e;@wlpKi(;;^0d4iBy0tyH}BRECF&j?ENk^H+$ z&t;7GrRN1*%NWAu|2D$re^#AEgvS~Wi-tka6*KWp;;058l4*4d2a zXWehePY))~*COA^x*UH^a@()TW>amRvn}$Rl{~Z6nouI(6Ux}tCRE;L{K-6HYMxU+ zOP+gv-eR6Jba?WX{r%Cs5PkS($#WJFzLRx`R`^ayZ6%pP3br)x7y?8{gFjiYf6dmjo7DMYCIJ86ZwpLyu_dp9S{V#MqIsII3QVQDyxurv&-a}wcbnABxC#E8F9 z=@_jy{f$aRS`iu!85*YW0u5z0W29+LxNp(beKRNAEzdTZy8krt>%+syuMhX)zdrmW z|C6?60Sv*?aHs_hhlB=3qiH8HKJCOrZ9?d6;*z8RQ)#F?lzK2n2s);rM(5ZkRn`cv zJqFYffrdM@0uAf*ip>I2>y+Qc!+YM@_oDm#xqn?&vr0z`!x0<{LodQQ0|*Dhs4hz* zZu^gF@1gZwpWdpNqZNT+(7D^4`Q@aUE+4Zj0``?p+aFksvfZNOL(ZOX*F zXj3Mxik33*@7e`};aD&RTYxbrU@$TzfGBwah>zNY)7!)-2?nNuQCt@=&JvD}!6?%? z2F3!RwqR5c0gS7(0vI)V#lWaz#K73l)yyI+2D^U|FxJ%BL^v?|by)-JRsVV2`?L=D z&+Df7qX-y728;o`07mwgq`A9PCJC>Fp@;}DoS_w9 zDAOx;^{|2wKV~fJdL|H-hIL~eH9{gXRr{BNW>^^-&6Z_w)xoHq5NA==cBx@dz;O|(I#D%v1Z z5iQ94AMGN;I4v@-w?O7~L53kK8-&lZLEzLT&fX??Nn|h;ne-z;rjIanj7*l!F=R#` z2{JiEK;{^&fJ}j2vHDTOkk9hS#fE8J&oIIwa~)xknN(*6;gDI@WhF$;PczQbI_9St zRay~b4jW`v@WSauoy};zvt{p#?v^)mXUi_phJYtM&Nl@7ELsR?`_2|N+Y)fN1p$YJ z07jsxCK^7~#6fMs=51n;Bmh$hXea>>7ZH(xaDvo8G`LO>c32-rg_5Rj$U zhWU2W;^FhQR}RDMtNiEQxjCk*=|xxo&LJ!Sqw0(!901e0ERQ(pAD%ox>mC2_WQkS; zfFlNg8N5i%sIVF1W+Ngsqc-nqhN%-(`6REY6BW^>PLxHPI#CjBC@G3IloUh@CI3si zb%L>3N{+Ok@gkTM*^ZBzFj-2ug7CkR>KmdBGS@^KWG;&~$XpO@koicoLFRqY2AQ`-3o`#_ zyT~w3i%hNsGC4tpAuAh%&$B_`)F#f}CU{9?Fcq27rXVv#m^wzLLTC9hyDKcqf0*I0)fcU6QIK54bl3-ve82QHn#!14_F&ITU$H15-)E0~qB7kw8Rsf?y zuNW9r49A6lv8tfA-RbC&KWvaE*nwf}u%iPp0JePf+g1dL+_j2=2h zN=f<&AFDRo5jo;~{KS#*H)Q&QCt+s#j%Y*4o1zURheaDoUK4F7d0Dhj@;|p*J{X&& zUu^I7L!{Di^;S)a|l;IR&`k!@k>olW-ig%sOiZ}jaCGc zVS~wCyih+HY{vi3-upmVRbBa??@v+xfv3@E#3Z+#bW%o)cK)Ejbj!076DR3T&u@CB zvu1kMWUZvgjMW&I{ImO!)uB$k3&3dRypOF=CGwFIK2kWdP0MKD$bV<{Lb zKw?EmtO$wo+54P*?!E6-@rp7@_nOtP;O?`}J?EaY_xJ3x&);{4pd_&s;^%%sONO>X zo)$C=dRovh;Aufazo$JKCOovI3W|o+RnV~7qk-C(+L269J2EjgA`EQgQi%qbhK5l? z!!blKX*9IIUFLtRc-y0)10qJlb%bIxbdf5BhHeXR*J)xV!(6*mY0u5^f4ZGpRXc(jz<1mIKnG>}QR6)_OrV1L?cr;KOQ#+CgYDXr#CTZCdXw6{%5qoD&v8V##0pQEHyG~5SA(XawSIcp#s8a7*8C&Wu( zKJ;cnFNgWi9zqE;+%9O?0xur5_EC(R#Wp0)W85|5dJsXtZT`mr1OYcCel+0P^p6Id zF;N6iY(>EBRSu1g$2m;>lwAg?Hp7u6i!U&+)ihw(+ zAm9#<0BT^WMjAoY$idi%EwGVAB?4d?0(!3W2-rxqCyjtU5~mQb3y~@U`XOQjJV_`< zz#yqo2pEEqM!;dqX9tAp`)vqCz(M02fpBi*k_A3)7}oX|%|AFm=!qB2KWO8n1Oo09 z1T2LY_Xr&erd3=A-usg45#&1X`xEORcO}+AZcD6#+>~AiIcuW!fGQ{&?yQ1_J3Shx zjj0{U1hpd*V%*kX*eWXm`q8~>3n)p4I*9Hj1 z#cL3Xi(SUq3*m5a*y08teiFu=&k`C8%@D;X_oI$n>8??XXf=lt$C~#ijy3O19Bba4KGr;8KZ+`7tLd)N zYPx-^p*Ge$kW6SE$i&!)FtCwJWvhW{t!7wsG&`3m9YO?Sx0+;|Nw%0odl@Bh%7!jk zp(J(~f6dDdAUbP6r5HT7K5Q@<- zN~)CQZ2NXO8kT+A=W~#hiiTU^C>oYPC}%l@vz%)!t{r0I(}sq{gdTj_(9lIFfrh&U z4eQ{=Xy~CBtHi5LjJUTYHXvon#BsU;Y1x3T%RnTy^M+3DnwIi9J zc4T5~L>Sn}r4kJ=4Gq2D_Gs9G2quk&eiEn9um|xf8U`R@G(1ZvM#B)PQfL^4k+uy- zEuUQws{5<2@@P10oMR9U4a+QU1lCpIXSv=W)V|%eA-D5V0u5^g4a?!hXz0AE5)FG2 z+mLr9wju9GY(w6f*oM4$lG~7}f}&w<6*R2%XrMNxb|e$jj!cY=2m>3rRH6ZUZCrHxp2c`r>CXY z=TMWQN0G6v3NqGtWKc7M08$DNKt9GsoPmvuDv<%x zkkNj%N5)dbF==FUlGxvA@+(~lUVF7iMi<1$8atxCiqIQtYy)WzsczOQa(=#7Q}x1N zTN>W`k`8xdX@}*r8bXorJcJ@+t8sQhI3Hr4#q~if+h@JTc)+x2A7YPLQQg>q` zs=%iHm0E{sS|2g3AEBxzv=P0neOh`W`m%Pf>2`=$?>9{^CiL33c=fJK@DPV1Qzj&&V(H zKd&Y;^56BewEJ&+S`hI2?>pNd2>6YsJpv{?BTp3+0ryrxz`Y&;)W%eeWP+-ZiLnu3 zU?Z1G1i&-|47U4rzZVfqy4??x*dI%9o6U|QUhNS^AmSe34MK5`(Dt3Okz_jzIixiB zMu%UYS@9j8&tXz38t#OnXjlfJoRts`4I3=31L8*k4c8Is4`}Enlt9CMf`*Oo+OlD@ zSuf=nl`f%!e^*?ZN$5N2(h1 zNF|MpOahyVR;m}KskiStoUN3h;Wnz2R__U1k~cu&RENJ0d8v8_A!7BuKqyx4FsV`# z1tT!rhT|K(dKWJC`RpO3D)SmRs@|i(acZJ1`5_elTjqnzs)!{Tk2QMYm+au~- z32!75)Z4Xq+9gAxUa@#yy)XSdQyPlZ`=yDhmolk(d#b3n$E%m(nI5TX&?A*JHZlop zDq5*tn5N$D#a_MZsM4g>+e_kWVl>=MC`LmssZwa@gOTppcUeAbAruWSK`0t_ z7-u(xYwQOtt{-Aw@a~@^^lI?#hX^ImuwKw`2wsea5sFbh@_)WtJ;F?crl0A~sdq1E z*zRdT!=s)SG(6;KkA|YzhHAg3K@}7Y>#Lw)y+;GJF|{L^pmtI_rXyFtbkC?8VF|(Hd|aL z#JvFlHxud!2uCf`_{UW#wjy9- z6$EVb2%rY0YNQcVjU0@P*a90_R3ZSTA)x=e9sxV4_M{OoNa7R%4kA+R5r!aQ1iV5h zM!*QEQZ`^zME{+ItTWy0-M=N@^ZD!}rRw`eIEsLU5XxB!;SjLe;@Tkou-r!V3kbDc zZ=?E7LJ0&sAP86kFGfK3_bL&vxZBP52m%%)dV#m@biISvfHyqtZNP*PK(Q484^%l|F|5pdY@*#V*Yej7p&aL_nMAY3o7WnUB=l9;Sg}x;szi#1sm`zp)JeJ1`HEQAmAZEz!7+{ zS2#*B%IAE4-|u>XRy6&ae&+{7(7*Jw*oId(AW$vmmkBn_P=i3A0kw*`VKD**OzgNaq%Vq_H0^=D71;%FMY=dyX*kf_M5Lbp% zr<({Z45v;92ql2gE5O(bFE$NBlww(#X;|+&hv_JKZDLrkIz23S*F?<$MOCHuR#AGd zS30FO?IMAoUFvRZL>1W7zf$QiP3gm?^g~p2(&k{4#Hk6tCD(eTw?V{8UqC2UddIav z=^ItYoiMuea=I&hhp^W2SqPz8e+WXgzS=nJAe>9E)#AD!4uo3^R}nfCZY}I3l=!`z zhehk#;Kk;kpJJ>PttXa;-x_oi{U1c@hrQt!b8yhpVh;9sT89gs7IU!6)7~7MGf`wv z9Yw~&Rgm$pM+P-B2q2{Z0pw$B#2MJgs1g}44H*O1dULQFaZDN+LnKb!j(-?YYez8* z5hLROp%@vXq)Iu9ZP!h^WO&tsuf2Kacm3@I*ZFJ?l2CzhD;x#J5(woihj74HYjN!m z3&Yv4#e}{c&W3dnN|=L90*rO=3Nllu8)|we#Zm#r0{-btVXpL?HwUuq?5SV^bW*t4 z6kTmnnBu9TH&s#eCa-8pY8s{1L8H{y*vk@Z>RhR4n5O97>-?NZ1_8uRT}<-BhCbf;otACq?G2p*VDdvi{Tf@R9)evsH*kN zRkXg@Yn@V?dXYfTI(0WTq6%#4U#WGNruD96zIm^qs^x2a58mqT_?Djo>hZMw98jr; z1gT4>wjw&!bT34>bZQfUaOqS(X;OL~fRWboKFeh@gzEWq2yM}OjI$rYwdkW3Hwba# zF7y3gAav6%^ZiE%CG@;S^n46ntmn4n(<-i^+~Rjm%Qch_CU#Wco8D19;cF-A8Km*Yi@Unr_`EFbmvC;#BKiyWH!%3nFga zs|dxdyN6UMt@px6Yki01vl>FR{yc1r z_(2t9{J{Y;<_RBg!49c6M8Y6x9KC4 zK*l42jGgdeWDHP@a@X&5e+i+ue#8EPK|#ilrv({chL)8sq(pF-C z#HnGxK18j!7=(y_TJr@$@lR_GlPcAJjKH|t{S2EM1}wbMXS0Wd3WIClC@_v1XAvA{ zBvx45C~+&ohLE=i-4Zs0bnsHbNc0IXR>F&c(RE`bFpj;L3qN=8rl$oMuX|d6@tUUv z7%zERfbqPiPZStbM}g5-1sHuE7}U%VfRq9PkdLtuXJ8|vN?^b=V07Q;fw2y8Od1%y zBu@X_0isr5^g+bk$K!EniAbp?y@3ZYfOVvG_>0OK(M#v&5N-eh}c^+Y>|ThfuY1hF;e6=Do^FL+;AycL zZ}qu%#AdwVX@SfEPYYyT@wA7`97-ZMtUBnVo(h@At3c*)4;iX#*g$*%8wk$W$T_eP zUL|B;8e~QdGRF|pq#@IOQ<=?Jag&Ek2Sf~+>j=e==^|AMGTktqliypsYJsyEn=PAV z5Q>=X5Q>-$#@PblY{o8&>w);~5*v%GCp5am#v=WM5{TIl#dxU9lsx^mGY#i~hV7mf z^YN&s1tkx8T2OMIrv)Wn1+)6n>|W)BAQ8~WRS$Exr~FzU3;7%h!`cW5Q&<_zK;7LL;0tQKyLckD=)XlhuEt?$>s_wTT6aWW}a|FTx zV981!Hw^3N!A=|?G#ueJM9l$JP%!+c3K)Lm!9ZqsVO9hn##5e7DLsRRQ|14HLZ z4~CV9VA5ddCUMFE-Hdn@3_TDr7}gVt!O%yllsC~2Bkh3hv3xc_C>maaP&Di^&Rz)D zYaF(?0f=8dWfR)Z5_lXxM6TT@b$sw_~g# z^k%pnqnA(u4NnLfw!w?NhJK1szVG#c7abbJ9NhDwLxUjTc25feZt=87z=U@_Qfx)Q z6IBrKghv21FjXUsplak`Y{VAW$f6PfFbx3%-}mNVH`Sgr0)|LDBKw-|c*X5(I*drQ zqZo#W5paM|jDS&6rM!l=TiHagNFC5W=-kz^TYWYMNvHt06^;U6350T%LpT7ewYYYO zUxi`kVnQQf*x5xW0e~k30PEnz=AegClzR=|_RU+ohBi+N7)HH!AYd5rw18pQ(;f^H z_8O>yg5k+3V0hAlf!dhXkxbA!GBGwH3~c052?m%3hTdB}7`7mSNrR!E#Hm5V9>l9) z7=Vbu@GPMi3`3+!Eqe{aNMAvD)biN{p}N1i%cJ42agISaG%T~Y5m?{dU`riu5V~fA zEp@c>QUVP-1P#mK#c1g4s_YzA{Uq)jZvIK!Ib7#yLBnEC3mO)9`b0Yis-S4tQ3VY< zJQ}EtsU67#wIdT_Bf`K&E|qA2X=v!`@@QCt2quk&9ulX}uodwt8hRmOG;AUiqoJQv zDbp|jBR!IWa137D zIkeq2?UL(dM3Fca^XMLjfT?JDlcz=N>pktYekz$wXdaTHs@8W_(fUrWbxLjOMFK&+ z)ZN&KDzK@4rPg7Z*4uCMT3syVp6T*!g_E}sX#M9v@%;SUx!cmw(LJ1r2lxTfFyuM7Bx*nz+<+l}g z{n|}kpO30L{hbD_&>fzRpxZqyT}7Lx#W;*6_DGGS_ejZY#f6DXS5r5I$x~He@|1@O z)igXHvVaGKWo%>{*a)l=CNK>qBLvzIYtuKR6&PoWU^$ix+0kJ&Xl64)S8^SGF-GmYb;Th5TMtHGP&`UA8q#H;~ zEIpcV1RhE_0{0~xfjiTVKr~SVP;5oOGgT1qj7I=9FjXUsplak`Y{VAW$f6PfFbx5H zt33j?QSC`1V1UFaM_?Z!RRjz|#0YqSP>g_KQl;Ac2#hoW7OwI6>>;J<`x-ckfTPA) z1jji7D=co5xJBVE>bD4874D+$;H3lt1_S{s;l=H~YYoK^1SA}RH-8b25?}vCJW71c z(_#Z&^0c=B6CNc}Y(>C86$A`;1W*H0HPQ&GMh?bCY=Mm|DiHwF5YWBGBVZlXo-_h_ zNt`+xw*!$X0{S3g1UybCM!*26Qcl4j4EI9_*ZTGBgO<-$2t~k~5Q>0(#yJGx5U}ue zA2$T6Gq{4U5V|?If}?~I2>7ueU=axuPC@(a(<**6XWan@0dWe}9B>d2r(mV0#VJ_s zX>kgcdRn@QMV=Oz981Gw!atfr-4rH2t^$)Edzes7!vi7Cz$#$^(_qqZ zyNAhgL^Elabdfk^C^jH>g-JI=43oPF#W3k5RmxEG!AKj5U6#*U2!+W@5DJqW#@P+w zU~5lfNS_OP+T?UfT~tn;)$V~wW; z8Y?|5&{*zifyPo#dkb>@MEelxqtJM^3N)Ve(4cCD0mKwAfPjpRJOdjcRYC)%L1WaQ zaSU-x8XE0)ltE*~9UdAT5HU2aBNRiUi&QCSbi+tPW3%P63__u?9YUe8!8ltW95i-W zTo1&7FwwN0(4jEV)K4g3L3Rl=cEd|RV~}!`Lt}Vh42>aA3p55jEzlV7v_PZZ(*lh? zPoF3>sEvpRs$7v+{7cuMWkurKo|Z=c`^2Tpze!xm{LA#E%oARb zpbD!0pH$KRPrUxAjVT(*1VtkgVSV!xlFH z@w>3c{#imt!yfx#LJ2fHFK9RdFGj;C#pn`;GBNqEGl76@o))ve#nWQ;H+tHe{RvM# zP;5oO^HmV=yhi{vFjXUsplak`Y{VAW$f6PfFbx51cY6dZy89gBcKx^ zM!?O4Vgz)PDusX^7-tRnRIZH9neLJ0)?R1mNYUW|Z#ic!8sz294S=@DM?wDbti zds^(lGoBWEu-((%9!$7LpbCnHpH@M`Pdyr_jj0{U1hpd*VBl$;%V(0&`r@huE zd>0EvRjt2JMe8qkty5}KFA@mqrS8T?RDn(XE42>OwBEbUYkdn*I z^#O=j>(3I3wLU~Dj}>-+@dQOjo+gzEU}d%V^U8|N5=)A}-t8-cYY zc!h5edL(#-?YxxG`X15xa(F|TuqxSk&$LSh#1W8-H?DA(FK<7_?;XXr^Zq@l1Sc)k z?%AMBs@^?S)Vs&4m*SZoscO(8l{7Xo32Z7_sa}|--mZK6JsWGNQd+$yaL+~$iBn^{ zt;kE&+Y1qo?KTmL$9DasN;&-lFjAWm_gOZZAym7sLui}cW1RgEPP<1fZV=*VxO(jc zLcb4JuZ<8&Xm_t@_ZYmsSi5caPP^n$(QabiuzQi49J+u;eVeDxhrY?vtg1*t6OC_`3q`s=%iHl}d+cN*}z>H|f1pHLdg$Xwt(ZPWACe5uFqGmGe0YOd_IRssan4ij%s}wgmP9w_>Be@*8$PD*tC9~ys+4`-c2acre6}R zZ-f_Xy_aH?U%=UwI5xc^acp{7;@I?(NgkWt(BlyBQWXTey6&(1k=s?Bil>Zp z>o<4i^mYa5*01xljP4eD+S`B$|Hv)HR>MD31pz}I0o1@$jWmL)k%O@jTVNxLN(8_( z1a#l;5wMPGC(Iqcw+&{agcACHS@ge%gt7kH*H62oQ#$p;Mw10M#X5g0 zq4PJ=IzOGvB%`V)-zlm};pHkif7$DtQk!y-Ku|7qH#VXQZ0cXBbC{;{j`d#W%c<(5 zb>2ndhn>=Yp*r7y7**%p5JBg669_u*CC#40M|a8PN}8q*hBE^D+nvsLSuSfKROc^2 zsLpp7XE%h?`9X{8hj=hty89%d-f-#e5TS(5UlE-jf*0$2gkqHcwD}JcZT<&d&(h`} zNa+8bwEidD<|(%7|CK8Gf5q#c8knMyMo=_zFg9WfY-CZXf0(BKQPcl1sy%7_w{Hk% zM_ijHX9`#XAko8N4?EQ3(}Z--F*Z!pdl2&eyD z7S{u@HTV- z`={8d|9w^Tzt8KR8knMyMo=_zFg9WfY-CZXf0(BKp$)$M@2A?6*8d2JU3dM$u(sue z8@>KVk!{fbTLgms+c$|^uJ&9zXe{b|2~RQ-u~C#6!-b76ZU_Fr=`zd=IImd^C`CKe}5JI z@Avwr2Bv7F5fqIajE&d=8(CE9AExQQf1}s`PO3d={ST7Z9T$4a>Hi=iRr@~#5%m8G zfuR2p(s;}`{g1*(>wn1uK9_wYRBhh~NAo^TpPp>!_O%$AhbRFoMI=T zg#KR@{jY%+&+d0WFs0X_$i&!)FtCwJB^F>B7J44=SlEaNCXIzY5X8CAM^-VNwp`9fNm1IhJ0|J>T)w8RRr`v z#0XeVC`LdZsZt2&hml6W9?NF~gd*TI2t~jy!Tdo%gZYDkhTGFzgTYr^ zMW{C%K676$K6ED+(Hxr2WPT+XkwjX!u1H zH2lJ&f!dhbkxWoKGBGwH3~c05i3XU4hJjvh8+IdtNuyzi#O}8^pLgTN!-!XVieZRr z!w!uDgqDRJ8l$92d5&!l2baU!hGh@?d=8RQ(QqpqMZ*#ZPQ@dP$?uGBP4({%5{emQ6h)l1I{pTKfZKZ!G}l9%=% zGS%<^#5L#p*}!KBTzkIOk{`IWcXz>6RSg^GsHMJolUL_qd*>L0Q|B^^8-ewDSOk89 z(67TH@U6VmFej5KwL_?0ODmz)ypi#xSWal=8@iUm4-?-)NQx3=O5`fCfr4=`&%LbE z62r$eo5qt;F*he8jlb(gnLRC@dO=2-f2Rw*`vUULN{%O$ddNa$wUwMzR=p4^t745@ z3c87)N~<_UYS3@*Z-%e(8Zgd2%i(nhh5sIVXFr6K*HMcbgt$Ij`1Jyz8^eWPS8twH zYLu^yz;^Ol1nW6>hbVxShydo#4$Vn(lil&pd zRWxhKL`BoJd0M1GSp}iu=&^TJ`!bYzjkCj2JrAMc*lO?WgmB{6XK{TH$99-Cc%0B5 zc9=DIolw1qV-UiL;}Dcee?Onw_QKGP?Z4df@T-{%m_E;x$SWm;5nfiy;Z|Bnk=|g< zPdw=FTL?^Q0fzgvi()K`X{EL;UKY!?cv-YVIGE%FCW{F=nAAu~JMH}?@U@^_#@S#w zJPM(5S!?fXgm7}%VR79MzY3=-?j|%6PFFlnNSjq3gpy@0=mKgZWR_%#AXww8fT89;$Tee6wl+qI@ZuSIkRP-bdvnDnBz*xURPJoTNW1Q!30K`yJ;OsZ~6i&vdrCw$cjS z(e8S|2)f10+N__sd#OH@p5;G?%iNP^GzcTUp<%!QPO?-Y);`7I@a!QffA3Cwm|5QFN zkP`nWGdqXwl0Rva6X8C##bqyI-Rx=MZ}4;m8uK9MWjY?E_kKA~hBfmFBjaKrKPxl6 zl=&>E&bQ`j0EV=*sFGWHL8Y_D7qT!8?j796ZY`J?sajsDmPsxXQnh^P*S-n`=wF1Y z`v4Oc{sT2$L(zIq)-v_qup*=bQ-Msz3M(XtOD7_NZ*368$f zXNh|gG49MOM+V%!HtEtgJvr^|?LBYKSJg-CsA zu$(bqul6Tm+?VVpoFU^6iA9mFuX8YPYCvBYKSJHKNam zeh90a%Xv7#aV55Q2g_pyEM~-rQ6t*6`SP_J(E*YEQkO+_8quA2N59=u&givQ`;6!} zVxaupL5mqNV%UfwBierG%Q*_i7tbBjYPXm!BRU~cuXI>Uj}hHQ^p?LnP|oNtXY`db zhG3|U2jdvGyfkbvZ9lT&m%lP%uXNZe?M8G$_7JvH-2L1EMORljqZ7u9tL}Py z=uWqo@3h!SXi-%HQZOXNJ48cehsJ*|e+HK{GQOm5WJf;(d zvl-vk#zMpmrPQfkc zdct`;e=N7)dwKDUuaW<8tB&Iq;NVZh%TL zRPo~;t?q#%FHD9I@?i8J4}4f2xlfAwIy?6%7y2jX%>IK5eZ@Wg#W62;p>MgzB8HHX zeyI#4aT1sN@Jb0YJnwYj%x&(OAD*J`=STc=)IU2#(G;MIrxa`0zdz!iqyE{JbMLkD z)c5>z#6L&E=diu!%hP7%^Y4%N=P*wx=bBngpIhml z%l&hye=g!#T30)-B(7^=TiqEh*%4R0+#&zm@1J}9b9Y_Sr?UAgWU3%j%rZ2{w&WtJ zju&0bf2L+Ga|iiSTmAgP2a5S9E5mbrwI#<>cEZ<0IT=Va-CLKfxxx>Ci#Zu4=ln1^ zC&T0%BWS$wH|yN^LnbEbB%Ne7R9DRL;am%ONqB!`OU5t78SnNP&&sThnVo^TBxbe+=G(QQTt{kMxn^Y!$IRitd@W|~4a_|;b09FE ziJ991b8F1(4a|pP<~q-8MbD}Z6>=A|9VV@g1Ro3p{-OlGJ@98`-kuUyZHmjJG(2Tq z;YO@Df?Ed7*|gtLA649x(kJH?PodAw@w)d_N_%m8|03|_ zWXAJYO2>Hd1O7#MECQeM{8RWXrIGBsViUQW8z#<6sVz6Jc#daE@sH=hl-ij1o|SxA ztePYe_oJ<5Uh&*y_C!i>EMKP7Hf3J%!^xNbNDfWQdtHgDdo)p9scv>o9J$g^-Mp6b zc<$y|Nj)91Cw3@DF=i2Z$M z6&w3n@Z4r)Xi9%a!@(7hM}5?Ac21E8)talHovUvK^CWG}oi6{KS$MU%IU6_)lJK*| z+8G)bHAb~F3j3SSXre4*m13qV1rII7d7%`v@d=hH^n0JnQ4DQN1*b`ba}xbB}MrYy%7RQK5w93(<7x z$(o|ts9_%ZJ-JkO+0;xPy{0pgP+Qh<8E9xM1Br1yAkERg%xFbl2ITsr!D}MgxQ2)Q zlTnI`=c&z^%;lquM)XMwcJKQqqZRiaPkE2ghkMUINBxu0ihGZzzUQBevNX&nOP_7E z{ym=ho_~(`=cvWk`S<;E)IUf3bC_qTt$rRbsCAN^8r9NA(F9Oqttd8AJXx`EYBYUb zv9`q6yKosOX^y6r>hTKBEM;2ib8}V0z~ND{c_^1$PuIYyyfUxYAl;FI>EtAsPK_E2Ok`Y%feC=g zSD8}JYbiv0?F(aNB=Y?aFi9ivplS2Z&o5W>ib&8l~?vL-!MjNVjV%BfPysgzP|W=pN~5SSp0T~zNv)4{ob zm3HUKd7Prj_^5%h`|(k_i1bRXh~!_acVf&)n=HsD8>Kxq%r9j=KNUBkr5@NzPIZ?T z=|Jgos7M4=OXH3ECvC|Mmlmf|!P;{(O~vNEmd2=I7TW=|S88+*Z2sAKu$~d?ANP$K zAfc@PxxUdj5eYwAY@DHSG}uPhHzJ9`JQ{LgUTIJ+BA`QxJ8UUKL+MCn9-U0BKIv1> z&0JBO-q+GBWn$H}`_A^Xs%+4*!MRgc~+)DpkrDIu_$#Qv#dA7k^^dTtxoWi*g4Q+OAC`$vX zD-FTX0dU=A72dZSdDYFz?8;GnDp}W>>vyAQnA>CKmcZN)GrI%x&X~C}Ft3i8$8=Dg zV^S%4ulQZ;VQwlm^kIkbv}C$PeJuBQZVRy`jgnMrF~(Gy==e?fAkRZ})c$?yX%=%L0(CZPya;3xEFpsT1rb2SA|QF0x9K_R zOsEKW;Y@~$CIaeQ_&zpZX`O=x-=8_JaEm&)Hph0BRqd>}YLLEalv?B{Hcr7+TDni% zL}xN3Ft6~V2E`f3D;+yHt#EZ?F;{Aoa?>czJSmF~#B`5=K9^(RY2EhVp!;-_XAZyEQR{&LEFLc0^Mmlz|fm!p&Qq94l959u6pT!O#D#S2I)EkN-n zQOFzxD{bkhDNS)DZf1+JbeqWca@s%rLR2rkK~`1YFhd0Y%_ti+pn7@96jdJ-m8eh+ zijs*R57(OU6*WeM0EH;39z{_mh8($OaYd-Zkp}P>P?l+tdckXns5mCCCFh1oV-Au^ z*Ii%RQj_B*uQgyVQ+$u>xw9>&iNjhtWnL7~i~(;w&NSa0&ispP*ORs_rLVuNV%Qbc z&&s^tp#^!IBK`_sp%^m4gLAqF@cqSU(X_tebl#i6@C-I?)47><;hxm?70(bho`vwK zv3yxs>NZH4VzcaWl;X+wZ7OZHrBQ~-4X}-tkGmR3XB#yXUab2xZ)KarCBf1ZaYW?N za%l^la@6t}@K7sqeTP;sI20Dm(@#n^zGmK6_&qZ zHQfvy5V_MnE8^Y!O+Vd0OHO7i^88buQ9TPCM**+TQz=}@bMpOk@DHu#DvHK)@|jhi zkg)Z3=kf_&%az`inGWo(xCCNL$1|e8UJw4qGiQlbQr_&HM_$FO(-5>IlqeJ=w8lS2 z_Yr?~y!!v_ni?_Z6Y4~+KDYGINr>u%3`)ZCixoiwEe%+Tp62<*S{Yi@`k_Uw3@vJB z;$fG%YOpkg^MG@0sgt?EkBIk4gp5Etup-!r+R`F~?*Q<6zc~QMdHtgy z^HwioogO9iPHf+~nO!W}MKygzwjF%7n4KZExHY#%E%I6p4n?`XBBt`Q#hi8n#C0(P z=ztOBX5d?8r30ufp&+`uX`h~&!>VU7=i>2aJ~NdZw2NesPv5{Ln_sNK{)$;{{6A(atGR!9$1o|8pI;wnT%S?a#w;>zSA zUdrE6SQ+6lM)6+;Ax-wx>EnNK%um7O8-E9o$xLPM>QQ9<(&dlfWtBauk$KCah=2xL zWb9f~oaSZ*YINW&brxqu3qTq_^oDW+1w_kmgT722jBsR3Eo)ykrmoRpEI&NUF!qL8 z;$=*oi^$wBK3Ypd2-&l9m&-^8sx|j58R%%PSGdRJuB>bm$oeu*lde?8+vrDn(;8QB zlpU{hO=ihAhdgQ|Z!(vzS&bDS@S>BC)r!euc2#ZOVBS54{FB*N}L#Wz_7oG&|>P?9RUt*QaGFdDZCT0#1|a3EQa?*-}Wn5`-$&sHG+^Uztj{ zx$qHboMSA3l7t-;HR8VKRG1`IVb)BEa!p}kH76g+6zjDDtPA4Cgo)K`G?iIZ3YB$p zs?(x++$5P(#dF|qJ#(rY#PM^g_2M>ZTA5Q7v&oz)dk>n5>?CSNchi8nc-R!{6b-6r zl^Ir=lrHpH^=ju%q=K62l*$UKuXPIb*Ck?`=o?E!`a;=6AGkaPyTqeVZ1!kV3C=Gf zjZ?(j#L&wnCi-$Vi$ZL5bgu^L6J0H5E1x%+r^) z9AOxlVeH#Hzoi91chi(U%JWEWUdzXLw)6Zr&)v8Rvw705wp_sTWAj=rEDdR5M*Mpn z(aQH^pi6t#FEq(YfNxZ?hE=6e9a&UU`in_4s%D+i7*hpmlvHzAB?luABdq~n{}y^x z*U17Thpudt?JJ7YIir-l)VW^)f6B(sD{akO+JZwTVS7c4DqSFelC}hp)6AIX#v1uX*wx&ecLNXcwyhEF%rf#gj$Mvj zLvwwcjkc1sWGU}^D5x4~y7Kp^;rYn;SvFW_j!YY{Q6HsP5cJiuEluYjJU+!Ew6Bu0 zv_1ZlaTb%bwFvT}>|SZ!Oz^*!(-%}m?lqPM3M*41AjSZ5Tc(XW08s1kvEw(f*K$E? zoXzrnb(w#B{2bQGQi{{N^UQf&)Y|WM1VZi1ibEIgRHJEO%2Qo6;?|Gnq|fudkme!4 z(w>bGODNw&3N7%dD4O4~uexrJ`RL&Gc>~FRy8?X5S3<<|QI^u}rd*Due2XeLh(?-YJMr zTkt+@L48_R(v}%fVP;16ZnQK@E#2OoMz@nECp$YDqZ#xF2(3AqfzkVjn;>~UoLLp=+!LF(ivYlFp8$KGf!B}ZN-qe>hM9x_mg7`@^#O0WjUlSig_rtG3( z7CSoA*RS;d{ue%4JW~hgwm~2lrUA@6P{DdX4FKh*0az53X#joD$H+85ePS9wmJEdB zrvY@9k1;Tr`)L3fXsQKfVC<&>p!_s|<|+e7zHvF3qdY9QZn>f|ZsaO8ld}OQi@2yE zPS2Uz`%&vtrNZpQII~1QAl0q?hCDBw;m5NwCOuVwS8SAX%V&#TPL0lnHRW=r7uH=* zfz=qDJ+Jr)8J3S6=YN|o(XFYk?cnTM{wq|l?_&o#+i~9UZ8IJl_KhnD488mermi*7VfNqEmfyIaQj=sWg%?G(=^zyt0`^hOk-)nOs47$W1n<%B0Th z+_$t8uze|1rp!U*{H#Eu&I%yCdd!ZXrsYhOJae6rY=lfA%B7J;42m^rIEcQ6IgqM{jve;nU*$Qvp_x6?;<{6y@|Ii*Nq znFMHbwJcz%s7_H)GBsJ{sfj92wW>}{Rn^R-WvnvS&omdO$|U7fYAndYcDdRC^TPOh zf2K!ghzh1hEy!?Q)T%CPsppqi_TAX~D4LyZTgAcfJNC(J{Q2DDyBBALdh7Og?_4lPT@OsP zr^Eo)+i4~NKmBd0L6|r&6*U+RMY*er(8lUZY- zbcWQR(W$+047D@<6s@!HGAr}Hg}VQPw#N%qRGfkQCzB1i?W&A~kY3>D?`Nqhr zBcGUtuW^HE8#uaYlraa6x~_mx8*AXG>~k?n&$xl3gq_CROccGRoJe!d3d45w!u;@2 zw#^|=8I#qR&oS0WH$5h+DSTAMr_?B`3)IfOioNtqnd{eDmCZAaC&z|D>+!HDllfKN zkTtnWqSFc=P_1iS#ixyr;=y8yA{@m_nDNRvb*aag$Ef0^13c}Vb|&sqViu&6VkOX> zA%oq)=a9Q=3xt=4G22H(V7d9lT;XqMCLx~=?eTF|XY;PlM{0y9dz#siE7rfkTmJ^J z{tYuT(M(KG;;a~YWdEY}RaIs~rC0QoOwZ!ReU;6I>PKYDFx|Tz71R9!^n&hOf-IB{ zW6;^;B%6R_(wiOK8sdB#jsB1i$#$=itk_UpnblQSwtq=7Hsq;Ke@^~OZi&82*X8S_ z`Z5Agf6u3Lpb9&DggeCC2eY8vfR4Q!U3cnU4)|WV2|FyH z9CIO_4Q#$kp@6%c*<$;_!I(LuOtCZYC-!oV_NE>!2Q)%~ms4Q3u}$~(*~T_Gvzge~ z_I@{1rZa?cj;b_24dA2TG5T$p#t|1Y-rI-qc6 zr{+aovH=p!hbU}CG}@W+Ss1?PM4`WV~A#+nHqQ>nV6)3#Ls z8vzsTU1q{-*o7o3NLPph47xAMTv_XG{>h1}{w|`nY^-Uu-$r?0W6jwa_LNFPy2sNQ z+4gA1Vo&nkfyi-ou9tm-srxgxu$hH*#f!2?S`m5>iOUYb|!Xe!>2`Ptk zbd#BQg=3|+{cr)l5A;$&z>gPOvMhT;H4Ahds1R-EPH%D zkryQUg`G^q(FV*7qkpYVM%)sbftw%d1N^!rT{#`=%$$d^8x-dzWLWgsHE>%jFD z?AVQQ{mnl=u2HVv_a|H9MAsZGR-KPXuZR~Q<0|n2#@%tMI6joc-XWQpy!%l^k8M_W zUJ#;#6|BAI%6sElSKVwaPOUUGeE2$ysCFNs2q@_~;%QDfW}t)QM8_SE;AM#C2hN&@ zbp4#CSG~Gv&PE4wIq~eOPIo3|*#3f1T~sJdnLjO;$&wxc`R+uv21=9ryzImHA1IaE zB3nPBlov~pEA=w~mBLU6nAe<-ZIf*mE|Ycg$-2@a`kj2?0iob&N{uCCH(}I(-kPZKiEF=x?n>s|)V-w84=m1I( z6J?lBLUOd^oLJ~=?ut@2!XOulb3T=kKW($;{`1t#8JMG(@f8-iEI9P{bN^X_S&X=) z$$WV3S6Ep*!`^ATlss~rD6uRq)%a-^?)y*ac*2tYJr+Ore@@2}miVa_KlG(^JYk7H z-Qv5xl8z@V@y!M8oCarN{8OEQk0>Med8J^h8n zkE5qLiyuc%GcA4`J=I$LIC?tE;>Xd`6pJ56PeqF#M^7~tKaQSSEI#NdU&>EdPbem- zr=Bm5tEb4mGmf54vG{TH^nQyUM^Epv_;K{~K8qhmPbXXaIC^@o#gC(>lPrE5J)LRs zd-?*EP3G5tf40SI6H27_UDAgve&F(SdcuKv-(OqO z0f;zA!+s!kD9hPKoFO+m#;T&%Tx$++S(Uza&d`J8-4P1ab`d6Aw;*E7by6$^aR8yUWH zQC6nPN*r_9$}@I!@tA zcXwvCV)E#uIIELv`UWcuO#TBo?+`ir|HQ~y{M;DGx$3!hj+}!}{&@1p0goV1p^br| zxon#WzKiwzkVFFDeKWy#ktvjkBV3mM+^nR_pV^R9o-!fhayvfAeLiX)b93Xr0(eHMFz2>9bB2Xyk1-Y5C26ot>L2`y^z# zH#!L`#iyAY+sXu#d>vUZyK>3T4?MBt=k8}hGJJ7X=5O5GzML(eE87TkGLq2Q`3t#= zD%)I}FuSetz1G|(WvkMZ;}~D^6x+tDdbwMeKAM4aV zWaRBwGUr#9%*Y#MlJT1akwt6n{8%ilDi+Us#G`54>Y!Va#nIypq`w+YJoV)d(t zg{8I>W*W-H5;?J8*aa|WAr>yc8W%8UID-Gl8QpR#Hlu!?yfsi8ak1OEnLU)Wk5U%7$OHCnSqx#dZwQxB zY@jUZ&X%Krd{=$NzAPrm-N>dUP&_;`?Ze^R{&K$Xi&VPdINi_~>1^?p1+J6K1}Dmb z?FnVkO>OGLh(jpT>HN?Xv$sH;QfAM~;%0H|$dyd|P^QiizHY$^m_Il3?m3yaq)cvt zU*{bKb5Y%S*;6jcvP4CO0!O#q)3pUz-W%T&mPt#@!f{ONSgXFrd3}d>GXYhfEfOCu z`*#J)t@EeihvQcszn>&;cY#WI>!Z_=2JL2IX^ItPm-bmvLSdE_L#DvzunHP4gW;JU zZ^`#zrXyPZjMEWF$;~l?QE-1q4}o&(!tKW$d&dNOS>#O?t2h&WPCk+#BQWNeqvA!k z73auob5}Nkyl7R#3;dFsOj&>Ow&Gt4)sc-LKdDh1=Q}5VdhxGrD_$&AXEuWTt5scH z(O*Y@y(+pmx_DJr#ISl**R9bfBhvg;L~L|XbP=3Ys|yd+eS+-e=BC1$+Lk#qgAVSI zdQWa{{8vi1oZFD)*;!kxmBra?G{-GzW@$ET7SWrrvUYK zo+`^aEUkgRa;TAgYknP8PF;p1dB}JPw%#wnGFd7gCbh1-GBl$AH05mMZ`UTw7ihCQ z5Qwh4N~E4XWso+TI*2)tLd&RZcCLd$$rQgoPp2N9SIB(wk!xq?iK}DYVA{Q4&cOVQDVY4fBf)U>xeBJ;3x+Gu6N2%eHLQBk)H>0Kz&jW+^FIeM z?x-yX)k-9Gnv+ zf7*S%B%AJeN0zShGU?#9GRlT={694d!Xe1oZ$35+@MM-jBDk0lh(}37!Hcn>C?xF! zF|nOE{hgT!SFIB_3S9l-H~q6igZ1!fG~x<%avGbz(^8h95zC;51ti@R$k;MWlgszi zD3DN%g6z%2DDZ=K6Eq6!w^pOT(dluGg4kzn!jygZ*{DgLY7Hi91=5n3^6y9zY6XzQ z*jB*f*hzvNFCq)>8!F6e$wPDO4@!MfHKT5joSUzk*MT^{j>hJj>0=uSHX&Cv4Y=Fc zC}A47WR|U4*2~mYU`brrny4v-rBp8?Hz>qdYNBki(Z>Ud)Cwry%gDDU+{>tGVEQ+0 z8puF~B8==!7}CL18qA5vf=rGhi`o;H#gspRAS-()tSNCM4$Hyst>BqSArwgeUTAb%b26Dsi{DWr#Nhc?1fm)L-aqwqF=m>xDkSS_xhQIq_?Q3NDffQn z<=;M95kCj>QMha>t`w&on@ichok9QAh+l>PxXDNyw0brDpiuXzUZj?WzCrc@eKPT3 z8DT}9G53F=Bs$8XPM6M*V$9)0n4Cjl%tYxWODWg?Eyen8qm)ZVY0@1`PZw9%O21{;7wp)_*rexOdqvqb#w|*ku%ajA-x<(E3$%F&4D8T_X2~aPA*~r$*tsp5lte`2G-j zP|h3pTO0juX-(rd1C(D(;Wqv?TvmCyK!>LOf&+As_hpj;G0*PG!#$DjusnHoD{=QK z19-jhR4=POerep8nXTK%Qnqf_$_0|Or4^54OCMktZdNv#U(Xet)3~!#_6g%Rs_c;} za+f{1tYR|hMVy?t(-*iuaYixQC$ngIE>M@77I7Hl`j59ZXXQGUQYM+LRGWSAnr)n6 zL+MO$QQcu@i6__T#o9!!lv8sp$})%F(#|#uy#ZBH+wCE>2t~B$g`#V&V+-X>yFEmb z%YF^uBtpsh>rcl_6@Fq?it1;@Wj<@1muI*sC6ShYS+0#{gNv@E`YeRSi*k6|zo@U+K8OFVTMjk;J4&|nIM)cHieRH&CE~B ziJe|K0K=59to+OU&Rn<34Rvm#1C!VEb~>xeS!&HyVCAQEX(4j3T8_TB99tNrxJ-55 zcKtc|FSYzt#N&%Ce=U!>;tkkeNy22gn?aY2-3(`F|5=^wmtIj$Q82}xopEl4-%nw^ zm@g-CrwyMOaYf%*-1pkh$MFXi3QBYr(s7(l$04ajdazvv62(FS_p&xw-tt8ZkHqh+ z_yFeROfj@)i9@4SBDQVKpmbOvR);_c*)z-%g4Id++mDct2;r0qmMC-cqd1C)v5 zQ_aM+%SQBy{pF`??(VzcK4>ipQ-3o^DGJC4Hp(+5FI|(+O1;C6@ChmN^13;h>$CoI zS<{?6rR4o+PY%rhB<^gb+^8=n>Z@TRe>MY_2KVHI*8|VpxiR3M(<;(MaO!g#r;Vw&P z?TgW0plGi(xqYBgYqDx6H}^;-l3FXsgsp0gj6;#7ohUZ`*kAE#TZY=c;k0(SQ`JBn zXUR$<-;>i6iS`YyXy2(tCfB~@P@e<1wC}ymSOmQ+nRO4@Kckn7Gr`b@vb6=t3f_K= zI4B#c{B@gp*(NbV#OP9$Tz$!Ho0Lh?73F&6s9vvIu9XEvxr7r}M`@DD!jkSsYLNRh zvwGpOPLe9u9i*e_f*Rz`uS8s`(=rXx5;30cVh8aAQ8jL@+}0Vc!PG)YZ>m_X)vaIB ze%`5=G`k8}Xv>f@D@?|Vq=w|SQYR6(SFUGtAPs|7O<^fUFpJrQ;i)i**c@5WmCO;N zIuf#fO3wwu^y{iax&(&A|E;R`_V*`Oy=^B@J*iy0J>~5wvI))M|N1&tbvXzjZ;i_3 zUw#xb@@UH^+1J?k{OYg$RpWNXBo~EBN< zv4L9U8^my2{NROb8_7f$@%$K1?Rn>9&X=;x%6!IYEF+s>_~|*K*7C|ea?rhtv$7j5LxN}yIe*^ed_ArGvyw+#N4mOD6=1?e0aA$M z%hKsJj0L6yp}(4MXwOT$(< zsnF~DvsxSRTaH(mY+M<$&;K?Bv4QuKhfMTf8AYCB&iPl_r34?_QBhdsr-9| zxnIWOvS2NpCMvqlTZ%tQACO~HM|qE!b8`LD_W~;8|9|%c$E{*QssCZ~;+|!a#`pL( zZwylh_T{!rY1_;6&Rrcycuq&%RAw{bTv;pAnraEP%Pj9IX_Sc`R{B%&{WEo*CtPI; z%a20LS!X|!tiA2mb z$@VFAZOcwC9cRN<#gG1w$G97|fI#IhR-IR%FCF7Yui)8lx1Y~YR2+VJ&wjf7eF+$QeU0hY+$}MXL zF`qRU$Nx(b#_V=uf4K0$=v@BI;@>&^`(WxdnbOf*XBJwc4;9YlJ{UdnE*sHA9e(iO zewzt>wly-NBA4Kl|62BRPRai!&+%fKfZp^d9$&=d3(f&!83x7D-_OeU3#VjEso!Nh zcXqBh+|hrEyv=vHvCBQ0HNWipF39rhy7KPn7jRV`)VZ0~Ihj^onk6gm8F}ajE^tnD z;sbe^v7$IksQKdP2WGhsTtHejn`>Hjp~?^{kv3}^!||nf|3a1nd~TY@-!PR)S+%O? zWj}RM_EWBCpA}C$%UqHxn>_Uc|5)(>%dV_&pLd1(M+!G+iN9Qt81a5d1SUn}wRG9O zoGRN_F3NsI%64A%s~2UzO1Av6IhP-OLemN@lmF_bi_*R}JNGqtTPD^0O($|oqP~!K zTSGOkZ(fxBW>Zf-TkC&FJulG6`}>htU}d|*%uH^s?wHNXRD7l|P+zP)*Zm$FV&kK3 z{#~bcYFgM(%4TJ~p#kFa#VPJ4n7mA?)VK+Hq0J~wDMir~^6(S%x-UO}Sw#tu1h=<2 zo8(E>ccw7dV0U$trG2W*%qC?}cyhcPYv&feGj*J=>2DzNHQtb(M81vOneiXHrA9Q= z4`xq8V=@6Fs?lO(xfmmJdLHf+&~ZNcK>a)npj6bi9+@zcD^#PrHfNb3ZdM5w?I))B zJxlkll!rLE_JscmGJ%9#$x>UfP_AV|`Sx5R4VmBLbJ^3F-FdV;>>_vYXhYTmY+_d= zd;RUtS(5$vE_-Rs;=)rp+OwO#&P&U+(y`S$l#Z&`N!knLKRMeWGM;i-G{s|hiePxk zOlApZWxQn}v6?Q?FEdK5vd@b0`{u7T(dJ*H%|BFyrf*fj92}=EpO>Qiy|0TjeqR}y zzg0%s`tfS>Maklyj$a#Zippxk#Uw2at~zQlv|?g0R3kNFHMoW}ug`k7!*}f8bZQi1 zQ6DurV^J$sQdU&iXqG|dvRY82?IFtIRJSxdbw1Y@iTTx4-NvX%u1%%i;}=RI9vOMC z1$OS&*=@@z0U5MR)eM*_qpy>@bM?XA4f)t9@-f|-E77&A%E?cD2z5G?ptnAnDnrV; zmL`D_kGwPl3RUwBtw9T2FJmCBJZNt<}L=x~!-MY0`n6&3!x<$PcGN%P4)e z%v~#gFZ{ip-VMFm(>tMedU_l5HcxMX-s0(v&>OP|fVmjm5zPOEPx9Ml8EFhmn={yP z*I&u$;+A*uCST`n8&<4zK29#Wg~?7TW~+UhXy$IF8aV@}EAzR_qMWx-pqd$|nXHg0 z3PCg#(6u@{^8ka{MLa!y%J(Jf(l@0g9i#Je-}Gge!ngDKZ6>v3qj_F7#mM_0AJgbS zqB)JyY%=UcM>I5I-9bxYisrcRv1Xz!PqdIwOoc1&A(qxDjv&m2p(y!A(^wj#s*-I`p zmW#~Yh>4?oB_fJbd>2RG7&;z_Y?a$a`G1S$vW;A(ST6q`dv60}*LBr-zIWee)vGE! z%O&YaCENF1mF1Ex*-mUrwv)7ViLF>G&<@kgkZBkegbZXPdO_08S{YW>at#Tf#%`hp zH;5#Vvg{_B?ko^ZAnwL23Sx*LCQ)}h%bt#j1u;Zx;^|fshp55Rp5K3;bMC$Gvpy`@ z>eW)>y7!%X?z#Kyv-dvx?7h!EvI?mcI5Xuzrp?z1YZE;*zYu>qNBfug{mRey`eaeGm%8SxQjPevFZ60#snzeE! zv~reKra~(rQ7*~FQywHU9+s(?!)d*JX3sW z7v~@E(;3Kizs&uzzki&2%*j@MlKYd~r%wY73U*}BJnx~I1R5SB8$HG*?d$@-Nai7< zZ_qqz(A1@!o@r>(;cxpbU2JOUi?qw33(l~r9`ZwlnGIlLHjQmkW&|GNqO(@dsnt=F zOQ(G;bH%8qXjbZjW|nYd$N1X8lB;ExY>4A)2OF>AI9IM6tiRCgDryJ2aAA=#rkBBD zj6-l0Z3kO&VSzrT?OK{t2K%#?t1H(ImT6S@m1>U^`J+G|Iqi*lVdT_5>V+%p z#L7`m+hd<@82fa3?9-9Uu~DFG$N6t?MgS+gyp%hEUp_DI@r@9fQ)D(^qB zLBfWoO6JU;4|q{iIvAJyBDkbQaA_VhonOZZ$-|x_+?%jl3wHn7 zI+Co#$V{8OrESb?VkKWVI)rxKwY4Ffs0XGi9%DbXUDd>lY6sc|rg64>S9F#W`^)%W z?cf}%>Ts4*jg6f(Yvn#dhiXJdqxzz0x3n3Ca6(>aC|o*W4NqPMy|14-FbJQ4JI9G= zcJxJ#G*G)btY(%OBa+QK97j8hq^yEJj@Iw05PD}58_9OCW8t`1dWq2aI%9gA>MQWN%aBwJHSnC~CZ*7uYvmcX`T$qqFJXr)m& zL;_>};V#k7MX18S#@Z_ZWy)e<<7Sb#O8S9zrq8y1E-F{e3|`-_`H)gpnWauy9n;JR z{@!fXaB|CJ`ri&mthAxv-vR5mY>7O>iJ?Er`Xb!S`&HXbfzrzqC1@LF&o-S?Dw5dL zNS#;b_5Q+`S(SMcSTqg+$zvwM+F0RI@?3*!;Q#)aapzHX_jCuc9p=yh-^6qmT;z#Zp1qYdjB z>^H&+3oS4yT&TA7P=CS_ewfe2HP?p^+3jI?xiJHltkDy|>Hu+>^oBKv1L0$Jhhe6^ zqjf)1%CRs|KG0bl=cN?u`K8d=k6-N0Vz#?vI(zhDcNQDnCDYjtU+m6ekh^3$dw#=( z=2-BwfBv6K>1@88H~r@msgi0* ziSQdn!x>2KUB9ijmQJoRAVo@0h)8kwQth)dkfb|tCNF^;drHr<7Kp3Ms3PR(bqAjC z>}dsgheW{5bY;WH@j9l}xI5odHP=~(01&UXYNy*> zZPmD&^i<9D$RPk+yV|Oq?#^*lE9pu0Sk~gLcbELXrTChqcz!8PmU_r8Uh*|&_dl9! zbrBb6nDE=S!mC#;#dAw>cPZXktiH{v$DKmO?Mw01OL4puUt6r$xudeAoCMBUb*jv5 z)eL#dx+O|usfC|`dp94Boe4kkST&s{r-NVIf&|I(Pb!r|B|W0~s7K^hOtRN(_NqfP z@>5EDjW|)zn#jXDS38^X-E1~>_kfYjrm_Z(kh%jad8F=8;T@9~=tN75e?#SDOI(e> zZFM`Eg^#ul$vKSBNsr~X=O?q$#k_PWFFldpF6XzWvRk!zg!XkkhV;q~-@6O@h<;Q4 zcwhO+zTc;Py>ndStshP1?x>vA?Y565^LJFv=(h9GB)+5aEVtx;&9}=v01tCcizK-5O}j;6;#6>Ng-i+gE;?-!X6<5ikI?s4Ebi@2hu? z-ziZw{5?65LFg<@_MrW1n&;0nGbqpIw~HBQ>5=T#plS9(d0M}L@_b+UIerVu6M_~f zmvjZnV|`E_6_iV+lb$AFu*c(!D|8Sp=3pJkZ$+n6*1z*2NMDY( zvZox6rQz+Yt|B>IMQ?rePV*aV396$xR0Phb(BUngZbnYyNtMK1$a^kv_gY=r-QI~} zg;#gFSFdxgE~Lx9F-aiYYA12``CYD!-L8!tbip7;KyHn<7RBV1`luV$+DV7GfZ@D_F8 z>Vlf!8YlO0%H}Gx)$_rzTT|M*g}^LU(Oul9aw7q55XoA`TGd@FyiCb#lZ zvMXN5>g!WC@??8_3xBVP@8EBjv|dZe!tqCv(C)dr;v`Ov$GhU|dfvRj-h6|-dAq$S z%<}TKG+^j?=?!{NBdjrKL|inskmQ z+oea90hjx$5KU5ww(7?3$q+WvUBgeRF5~?UTs;Khh7bpX-=g&Mn+4>64v9?GH7^XmVfdWWJgw zvqKbE5Dt{nJi&-^ubnJABMEV*o}$j*)jrl>?6-?nt~m}JiAqrQuU1jwin=Q5#@DK7 z!4+Mnq68wQXoo9;7?--&#@DOpMppz)FEP%jEW|t!Op|_?h?^@?HVMffs|9-gKWWNG zK$Z)WJe*eFAJ=tcimB-LOgGbqzB-egNY`(zdis%SI**Qy>sg44`9>;z{XCJRnKk=f zwl;-u=|#TeJ#Xi0oO_btC6>pzo>uQqCJwcKR>lI7IidtRu;PhBte`n!!b4RV3)Kn2 zgR!Y)P_-817R(G(4mhnV+@KXbgT3(C0VLKNXKDwUQypBTE{Wa?oCy6@Sjha4QvSF&ha%ruxDjX0g6h>E4_$Y1zUw~`1O&nIp9?l zsaYS-s*m~#5PhRo?Bk0)ef;Z>*jf@IGlKGc!>MJY0b4?B?dM2?D@vI<%-=XSyYjWQ zFBBz4g4xyGuX3UIjanvN&YA@ZM2tb(hw52%0PSUQ zXycCm2P+=Pf>u~ri+axwx+Y277?bfTYg7 z3?Z$N?!KD0{_HARA4aBFTrn4mh+tNT3|$j5vTj$7GhocR6d>^QfIsXiAS}CzKmRyE#_z zCkucetDP|Ojwz_)ZOZM?Q^RJ&PlGVI6xt5=j|;WhYLYbAlEs)zWA-N&%wo?%%HEl{ zriE@t7a66ww9V#^PeZCi%rUlR?R@*oDL#WI zq$SKNX<8QY#ok{@VZ$u3Z5rw;9yLpPrgFDG}E&x%XL!2tk_jh0_k> zs>sBmi+VqE0D|Lz8VG9BB{szxD~%U2!=whRHUfLOQ!&Gx&{gm&4#l8N?ipA3>C6Uk zC|*ZTm!_BAYnla^M>pEbAcmRB?IInb)cJj_Pz9m?44TtzG;Y>Lm^3ttAdm`l;b_M> zRGmp0f?fr*zfMRVOl8{-#HH%ufFF7+2Derbo$gFst8OH*r0|nr$=JlU%px z`HV7|b5az^^!RzieqvTY1|O{^=0e@7AIGZ6+`A;$(qpbltkR`wGOtqmaTFu`Bgu6v zALkxPb{x02z|kYgT)bOPI@l}r9LGK}$9i-AktDV%OQ26xcJTD(<1AX|Fj>Uc#WBCJ zn=DC=UDbUMeC|ji+>p z<7r)Pvs`!Gz445GneFVzRQL9HRzL5M0b{A&y(`|VpKO%W<<5AME^msr=#tj=dlOp{ zJY#W>>B~%_oy=|4YZu!gyV&*F!-bwVZ_vXVvxhhLJiJK{-{>u*@eY~0c90H-%MI~O zx?m4Yk8Q9KeX~Z>-M)p}qweqb?$UR66_KdbV4oJIC;8jQ7|xxS+vq}m-G#XB)y z@dic*UP<_SZG0_%F&=V&S$CV$IBfs8?H7BwoYYYm5P9Yu#OJ5LbfSyTTXMddBC*Ml zszb;s??-WC&L^!8|DyYpdtvIzRya4s9a4ts*LO%+orrag*9fn?VQN;{0`fCtnj9aX zGh`YL0wsm#CyZ)GF~X4X1OTF0@Ef&F03J?YiP9Zd;q=fHxw4%7+MceH%GkV4a+bZ? zJWotV$xe=z0q13s#Oit;m9-W8po>3*q5aY0fx!4_rqTF%Y<-#G@CTErIi2zrvnNdG zYR2Y!KV#vLKzCnD3sNDQC7>&b<2YM9hMDcG?s<>OAT@;Gbq53 zp-kDh*?o_lF<4)N$S~Dz648cOZ50)lxiGp+r4(JdCNhgMa z93J{9s1eY?u9hAOf})@x%SC5dujsz*D5&YuG)0@Xjc=et&o_2`)JuY(3;>P2I^D=S?b&8{r#%f2&|^YMT*G!1F%j&N@r?ROlj=1b zL;qp!0{JWI$B{oP4O6P9K;@DSbvNp_o(~^u(!V>``F+c-z1OvpdE-`4F zAigL{grW>Y3S37XYZT14;1rDCAQ#IH9*PUkbW+aG>=u_f_+wSq1@=1ok%e zZv%#6*-rH&+15Z2FFe)3Un4CR^Bcq7htB17pmWnY(Ybj%Is+&d6P7$|&qFDiyydzh+w zO5bWF^<`(V)uVG-Uzxx2=o1z8p5GYb$Ze+of|of>O*PKw|wG3;2c>cP0`HVYT)IqmlzUWq#srKakV=2 z6h9{UvF)`4vW2;1+aulW%z0V>;5U$Pb|<;lVhjISi+sp!Bx}BZ_eKF<^V6MK-Vy#U3e=$UAhcwr#r7 zpRhxG7(ct_OL%BSoNuF6aKKL zP-H2QQwqVO6|6bJ#swL;5FB10z{5_fUhxgvjDFp?Hg}i4lYvQ3 ze|#0ye>1OsVx{V>jMORz2h(9sws$JoCA{9S$pua~cPjpt<)i|Jyh9M8wsnT{sr5Pp z$w#W1QUz2?xKy%*0ekRCMV3$ zL^jI5^k09m9JL>~$#Sbql2AvvRr-}qZIZQ(vQ@>;X)aDbJsI+k$&K0nl!_$MU=Eafy#O@$ z&ib4xmqcejez802bE;eton=GV#T{9nQ{|HA?1wLQXMMo)CDGaQ6Bl`8iJVdB`6bcW z7cY2c3+52SRF662Bmb#4fyDBEsH9huK|+g+0po;TUbAt6monpoyDu6ikf|1dO)#R8 z+Y}&0LXU;?pMIf|)-Ku$O~o^DOO72Veq;n9V}S+MTQJgbfnty z$uH8B+AqbGrtIu&AFyR3ZS$MFwVuw7f|a2YA@N0FB0QQc9jSfcC&K3pL;*5(BK(+Q z?4-7#=Y&vQ(|`KQ{Y2<{%H~MNQI|kZPhZrY;)&jP>Gbuw@NW?tD_`Fmyc<0$6B+0OFQi?^(R+NulrE8tv5O6`inLG}A7d4Ts$*n+j0D)GRQI%4abA2qE4JTw+Hk(a8o6TmQ&4$yEyL3fa zCuN5uHpN*X30Q2$vkIr2P;@&#oAGA*sRx^MH>qqk)7o|5!`zz(yOW@AgINzi<9)<} z;uYse=NZdp1FrJ0_jBN%!%lS2a91Cg(|$Yf&Ce~N3xE~{+-id|h*)sBU=uBvKmk+6By zd=)eV00qges%l5uW>;5LdmV~Z^OeaE0JI>_0T@$N*=$x>HSTWjshY1Ah5&HYYO8j% z`?mn=m{wx~SBq714Som!@oKBu=HUVWV_J>7^F6KRTJ;bB$iz@+bxc*|^I2t8Wi%?s zn=>OE(VdnZhrBn}Eydj>|DZ!Yoy}yyQ0VAvq4E~?rL#eNDUOwkr%-v8R2iy#O}wd4 zy~76frFe%@_Y^B{x}!oGovOAppI~{T>q&n-<*x+9Te%cZJzw(IMSmrL-j%DK!fE-Z zOd7}hd&_<0kMld8{b=$gl4$65^GB06lg&l9n?9Pn<&Fwb_B{;|g>N4qlHRUF-s4Fn z#RfA)h^l8RuPaoFmoNY->XR)PNWE-PsIKUhi)fKcn`~5Tcr|vfUgut&4=ERNd8NmdDc0z@oaINHY@OZw!@yal^ea*HM-L^n&tjb@V|)>THmbb?9INp zK8ex~<1W|S4X!zDF$k?}iZ?AK`ct63Edq4Y>RR68TE5Y>d{e++CPe{sivZo?o9h!N z{ea%=ntOw5j+7u7poM%Td5R4&R!7ioU0w6HxaMzl&EFQF&7?EXTF`sPH`gb7`k~$H zn%n1^yS)G{DIEev^L+z?c23Z4TV3;axaRM4&0im&&7?li&Iz}3zPUb`)(dUB`}bUP zcj?k$PehSVdS9jC?T8vr60`e{7lyl@RW z1vbUXi?P-6Vr+|*OJlo2{E(t?_SRCo*>)9diIqI06DwoKoHBNF<2Y4!ucEtkL}N@! z1a*bH8ie;OL#Z!#Twy&BXZ!^qAfX51qxND-j z)17x;&F6RlJeGUou1V|;v}XWc+w;|4ekf8qxz^(DPNiJybQg4KD{+bT<1Fz_O|D16 zT<5P^B&mE+bDr{zOmfZgjp#>~Z$v+cuKXNF>cE3;X~jZxGUOW>vBLS{WM;m3a#BjX z_hSr{)8s>}){6N?YKQK=#r}Q6@{P>KTSR7r#cnkMV_My&qV29|PN7$GkTgZHD`M}@ z5(42m6=@?8FV3szs<^A7Yh4lCuY4mrRkX_$!EFlTV(%^|>0K$%xDKQsk;Td4JXmhB zIgP&$Rdnn{NJ0Wqcd=n_U*!yhuKOkK&-(jC?iZD@fbt{UAK|{J--tQ%>?qIRnx1Fp z{Il~_0z7n&T602eq3JB?it=-;uf3y@hK;VA#zEw^3bKb0j91ty*qIc$oT$KLTu)Y5 z>u`O%0-ISV+db2qrd2eDc559SURq1N0XO^o%t?!4%6@be9{2Z>nSto9&u<8D} zW++R){?lxZrVe1xCYy@!ErdeV90xBe>#yoXcWGXMZ}UBaN_G znRR@~$I`8IfFEeFK+wL+&eEB1BSy*y9qT%TKevkNU(c(bSw-~+D;Y40!EKB+ zMVTrf7LIs@fd4LXMz;-ARi=t5J$l+6eK~TpEuo!MEK>!~PV-Du8dv6QU@VEW4JYQ5 z4SA*to%f9G$+A}P+Bv%K;7 z0OKkgz^e)eu;&=Ki~XvyoVDyQCCec!rRnkryvVc&Lz`0p=TMP#orRTyOQ|gJ8{qK5I%jD<{q!Q<)|YC7 zr%y_E(xjHB+JFFS8T~oMD7N4vo05A*qiv}+Tmx=aG_D#WCC~G|pES;8Qc{fAGii*G zQ9(HiBURAZd|CvXNld7#Uk;$LZoC2Zq)k!vaO@S_9RYVjSHa^U79POhP%%((Y%Nu% z53iPLV;GS;zP3~w(wJa!wzx<)u~BfTHio=6BGm>6B2v!+erSSpvWx`bXGRxJ*+C9| z5!#VN@=4AhD9BO?&i*3`RGUa}c;OspQxA>Xw>HN)oQKWo_EMI61E9F)qgmYkm>ZuFO}UAD<*S; zenw<*;MyUB0mwRECr1N6kCwZ(0y`R!rGek=?rnO!*dRXxSFEx7ta`0`yOr0wcUXD7 zdnc2o8z1Lib%WUBHAi@ung+*lYie5HI5*DgQ?H7em1$>z-3$arLZ(Ay5DG_`7F98& zWhkJ}=765|qJiWg5ab01)Ra`yZJk^gN`i!NMotVu18#z+?`tHbG1Y_Aq4iAJLh3}q z8^M(5@utsP;;y;`j5|-`1+cUS<-v(_QE5opb%rOVe_Nq*LW*mf@&oskHFl63HzAk@c(mc?OwAYdeJE%ncPRUF&qIIVjig^aG ziE*oQoK>Ax%+e+tf87hP29+@#Gu#qYHnIM7RR*wz`DS*hn}D^5H(h`)5==S5*p-y*psecat*0bgg`@!daAg>SykHlZuQ=U zBcm3jigunXMmdKwa3!SKK{u&wq3Z2Zllit#{Zu&eIva2!Z*XhL?Rzimdz?xE^iX33 zvYvFW)l=(;j6CU+!ghw_%Qp1y4dYHV@A=wK@ty!Z_@2;;S!WkO*5u|hBH#& zN3?prXsds&!5Sdz03_Ya^ibzjCMk~hD%a&z=BM{6+XJVEdS`O~-WK)~J6+VYY$s}a z*ZqY^-5_d@^sM=Ps!o{b!b>n|HpZWR{Wn5_4V&FYiKI!>p20Bb?@ep;Gk?$;3n|7# zS%RQn@0rN-9$E;R<1n^%gKRqr{IEA{KT~DDWJ>O}AJp8nZE2|Ho^b~0HoWGpuXM?T zJ6ZJ8PZ)>Ueu4sn=#CKqOym|>Az$5WhkFa&_?!UKt>c@UJ{tqNFx}JyRH=2tvOHyk)f62toU&}~D zXULfRiDdJm?awrl8_lWZeJDxr!r}(--F2=cd8#rOZLjCXa<5;TJCK&TOe|y% z^Nde=xJwUj$R6I>^Ud9QxTi0p(>8n`bb>5SSK*YPYY5o6_*(o2q-nzWyZx4<_k8ky z{|oXxnazKT^>CAVxB~|k7cxfca!tHbmuur)y6lX1>$1>kGv1cb$*sICW0NH>B4blc zIaum3?rP>7OZbv!Y^wLBA7YW)mwsqt*sWY!b^4(z#cIW529uV|py41088;B1O29$_ zr&XpOBGpDuzMbJ2n=DYpGB!CXP`;*F1`KI0=PlDH{-7Ple;ZO_7%*RJKp2KOZA6wy zyf_-acl@`%XAV7pDS#jzp|Kg`$QK$dl?}F3?8wC8NGGXfs3fh*`;#%K9GS&uAd?HI zRF0NBFGN74LGjupzq%23TXz#^$P!u+q7cv!@;G@~BJqV~Z!rY)WXI^IrH~jSPv$d_ z7y|_KZfbQ1sKxgEd{e7ZbQmr9+)exj3=unNII>h$BXc)FTSIdDc%2Nyf~Y5V)3B5^HSJvXxtn?k-Y4r( zuXB2*^0=&3SZ%l==p0f=AO_cQKbf~NocNn z%+38=?0F{RLeEXcMWd&S3ozye#5!f%y2t!_$u-||OYXGV)KnR@zlw=6P`d#U_B?BnBgq_k(=QlopD)@dXltdU0-8rssZ8d`d@bta&|>BL)>3~VearjOAavZ#;) ziAGr7FuqLtuQrd@MaqG6k#qE50w#}_mX3e%C;#q2COxyWD32G0n)J!Aj2x23Ys510 zLgn$gNGXq&eM+&5BPl>5==@`$^Au+m=6Sr>z-B0|v=& ztgfqTf1)oXw7*Q`mx=sBO^2@uk@pGeQ8XObc?H#@XGwWkvIJ9mzX9;VOoSIY8P#i( z(DFi0gjiGE*~PF6#^qu}Ux?&OeFR?`GSi_lJ*P3zeqGGfU#sPr>3DPoC8akr-K_GL zh0Ju+&>1+Xw!rf8mwR7+df?^FBR$*#cg&XRp~iXjG4pV{dnr{}X1bM;5HizAZ&W|D z@lrPX-hQxSu@4DKE|+DdpX3#Ttjx-*JGU*0&sOU@=7fGJlPZW4$n#8UcSH#G|J6o zwiSglm6U6VSR^f#ykmbz+>8sZODz6LFAz(;;v1GhCnRYb+U9N;&8^lHHWpF`2;>pf zznE8lauwCToL4`+it1m>t3S75b>*bUlC+Hg_gmUD4UXyEixVp$n9Nc>*oNxoS5f^V zdG!y6xcxD>`&eH6=qjpzGOzyeRaF1Yy!weyePr;KOX{YTKGFDge3cUaDL&s8>@3QE zv6`*oA996P+7@LVh3&<>?b0r35g+KtE<0CR7+kop9Cz3Fq8dW<#@pp$<%rNdPukNVTbKAA zFW3~4-0L50wSH6}m)n2U;2?x^ue|a~0~-!HY?MywVA@g~-ATYJk&kk-MOrL=uG zDJxf6*(c~ND?x909_Lm%b%<63y4#@dv;C?(s8m2_UcZHC`xRw+C{`~Y9Nw1KsPwu* z27ylsRY|FS%L)M*3PtOim2ypB#)p$gU`8IyNMJ^QS?W1BC{iD*aTF7dU8*zG8hTJb zC!80Hc#y*h`Y|G~eX}siobks~i6sREj}CK8J?Y{D?#LUYQQMjEK+muFWhr6i=Fyflbh*dXyTq^qkj_4pp{Eb3dba1d|5skLL z0|*72V*6+jM3W(b=xjkzwp-d3jRoQob;KjE$=Hwh7%)bAN>w7+?F1vFeJODfuz`0< zfp-c_&R7;WVUf%YA{!qAQtrvzATlzhC}m8cFY*5_JppbMz09y~G?FdG52T2Z1%pNtu}$7v{V7>IvqlpvC1nR&1OS4KB9l|9 z&i}i}7)C=wQr4i^kbIxX3k!mzj<|}8f&##|=-&~u+X66*oSp2mra(cteai+TS<$e1 z`}FnE)(6T;-*_@QoHWJjP0#C1@p^N9fY;f5)m5Tn0R0q!kJ@_iSfqe83j%4v2IK?b zBqr?`(B_BkB&{DMIb=hvH+<_2wcen0j$jqTPph4hWuR%Ki;8h&m}hv(P_@|xL0ZV} z6zKy*@?2P5Bs2#y6>7|-rH`-sCM=3rOl9s4Q^?(W`wl~{M_{=?R2#}(hM zm#pf|*-Hy*l8>_i0fX)NMiqdV_LqS^HbPM6VGwB(#G^RKKbIreRIi1MD|8|?Y`-V zyR)Sq(S%E)aokG!MXMgsCEn!#r9;UU-;oLRphPw6&jxiwy$OApbM05s5KnVGmD zT^rpycBUX+Mb0-ycn!uNjU5B|$toB$Nj(xi!$nC0UC(A6GSPC#$} z&%|+=2G=+^C>$r+|DzM#Gs?x=K#X#b-!PFjRR_}DrB}*s9D)8Nn?pF0K-rOb^kDvI z(LJK@fvo!dHb$F6ZJ(rE^2;97r%UvG(%#UP*G77TaMvqL@RjJ<6}FvXaZ;mXQdrT; z_v_CGB>K|0i}gn16E_Ir*CorqPX>f49YcTw*^Y{cP22gJEz;B!j=C zWfQ`L#-k4=CyWKt!~jetj$1iQMk^Ui?6O;?VKxX{IRvIF4JHV}qb7q180t#?#wm9b zcAYqY3Q$ku1N@HP_Fn&k-2wV3=bG;Xf?!$#nghhaqnpxg5^2A2sw(aqMiC@FgJ&F3 zOhZ1m*wT7fO_2=spj4#xlmrq8*v2nAmLCEKY2 zZ$ZS4Dy|S{P=(2fVGUE0hU?nsJtIXPV3^L^w{&dWc^dRRhYteEz#Ef6`@7ixGHNty zCVZ$y*iB^GV%*$a`b6Y-62w02Hu*Yx43GYm7co3qaw10c^TLOVB8f*gxR$b^wXupD z1e~G0?H@4@K*Q1nH=%mem@JXkHW2#5V)Jm?e1EbTeFLCxMu~*yn)e^l8>w2P+KvGMkw;L>h4k>jzlwkn1F<7nn^-| z8T6Y4!Eg-;`Lp?;S&l%7377hTWP-pA$Mhz>>`-yd+a+{Oi0BHs*+8<`f_k`Q$>$sG zlPiiTrhOV>{cNkzE1*a<)f^>Hs2QXm(y7tDWr|ItCS(KSXMEaBXN?sajK32UQaT9q zGd^wW&L(%QwCIJx;`OYgp3Zwd9oCy%=%}_Q%J2pFG?ZGKv&?xk3`200ZNN&I6Hsya zpJ3!q^-%i=Y3AB@jp{bvyvETsz|9sIVFZ9)6{m7g#RXtr6DsPf2y~o*qy+|fRW&tE z88*5z2vh8MlTsTey;40XrFwE+I^9e>rO^4(x6^$Kc|-+K;?hkbQ-aWSsU|H=jNfjy zQS^wz$!1j{9$v#T!!iWzVlr;YJZ6^;jDV4jg?rovaa<V;Hyl=w3|=JeR04w0MAWn-b|*P!a*m&mr0&dve`6+O@7}>TQiRJ zRZ)VII&OReoV8h)t-oJu68`5-5MGp(nPqOa>7b4B0FO7a{T2o+iZUSb6wHwM;y%GeRZ5p$a*^@rr*(sjPM>@Ua541D=!1FIyLr-6R&0ebUttMmrtd1x z71emb*OLVp?M7ZG_N7{6(~s?o?xpaltleg4mD1*+L+R;4)5}?{p07V$sFFeYkU*xI z?*yP!+rQexk#q9@bq{1fy_M&?fk*eM+u0kvnVNF4{M3ZFE*j!xDeW%pbCaUwQR|0*GB@8~GxO$~vMk(Yl;LqO;qcg-a47U99Lk&thc`;u8(v-Kq2ajYy|q7I zF17y2k4IY`NM!jxHv@pu4k}(dFbi{KUbOja9d!pw{3iNjrs9&bd)nnav0Z-5T|VG0 ziy%-{k8oApv(T%q=lu1&zn%qQR_?E4<*?t2qHnz)>iKp^qi4_A`snIW-|9tXmuGvh zKs9u|84akSwwJLm>iW39p5&@`NMr2E3G}jh{(8!npHu*t>Ji&w@B8v)e?8^PPx9O9 zF}7CEmoNM4DPMk)-&PNLuzJ3H*t+XFl3|YA=Ccuq+TrcPscH8~5t*k&nd_ek{@_Du|sokEI-{`s?4Q&X2b$WXyVwr zFiEAKWjh?&crMAjWUgva;U_UdQFcZBhavHMDn>Zn5`}+lHQI;AR^)}nBXNy3@?FDPGR!%8F+>w(`?X{ z^kMo$PS>hF<0Ob|JeK+oo&N;QlIS=>sajH8j!CH{p&x`fG<);gP>kgwDX9GgN#zfP zF-_IlJxRNjl-9#I3+@db&KDT|(QqEk;XIPTdE_F&3Ce(z)`4@(p#OX>rH`2Qcp9-J?X{n9F`e=cwRiBKJrxD2ke@M)v2-znqMtb3m*xo0g8(lLAV2~T)a zVz6pRxb`s5L_l$M&IrhI&!Qrl{kmnjXB%0rc zv8H^TR*|P1a zd_@1SD;CQuciSSc>cN3Sc5zmGk9f(dCJl1MM&0XUu4kj}4Z5C+y1NxcJZm73RGc^( za+KWL-4iSMSNBF;O5K}uX?AbcD`%9Xk?ZM*ER7VugCvby7P`0U(&^r&OWfV7I_IM9 zK1CpP@T_u)$hpL^7$R)(}@u(Z?x*T=8s(5qvPW@brx;u0|5_RWw zJsNed)#KZ{Z_-baN$!l>`pBGqE=Aqz^izrd`H9hNLEmn76P31!@@WaLKU0spI%VOS zI5{52%H^~~W}aPa7QcfBSLwlarQ+deg{6diJa@*|s+4?D$K!dWgj&+M5O0bXRJzmE zy-uZMh$5fVu1APsn){VUmh8$&56V@~=XU6G^X_xxl#2JnH!9l?o8*=J=Vp6%`y)v= z?%KQCfq*+S4T37L6}OZG^=s}u<{_iyiF~H6rf=p&%@xd$qI3BA z%DfTEWpGv_`jWSJ;ShF{wB8PLbe%aG$3&Q;P3#Wi3ccf}Xn)K1ZBJRl&(K5P%A6|# z)w^tzq8gWrpQWs{z^ul~$bXxEts|~)lAjd%*}2elD+~%8+3@w7F$y1y9`FafD~j*} zwi|D|`^E2k{OX_lIzdU?|M`#4{@UCA{IBnN_j_Zcs}50E_xHYlB0AWQzVAKr=#RZ+ z@|ka3i0^%I)b~F6OZw;f_mMwP1l9%V-}3-mRGKbMuID+BwyFnz_{A(LWjp%ni{vY{n?;NszvK%p-k|VEzNVHmc zRYY>3k?4r!KN}MN^eO#&@d6@o1dU!SBxd1;P{%mRztBj0OicagIYZ(u0v^A)a3PU6 zg7GdE5{vBYI`h(N!p_FclixBV{*A&$zj@YE;}RfU5L4GA?h zl?mP!+F^qKx#eU2BC7tP z);yNqToErUmhfS-ULnw!SO~?1>PQG2wNgm!^r{XTD8Jg>ZD<9x%6v#+fO~1vm+t2%E1cMIw=3Vf)EG*!a{QaxBRI)8g+%{EYcfv9mR&e zmnlYzGczKYJ$RLb^l$%ZHQn{!Hz9$k9#Trs8*$QkD~gn1S)j0`oMzeUZ7HX0kCQhC zO2?)~2%I*<)}T!gvz7~-hB7m=SKWe?hnNEaN-I>QXjY841BOUS(N_+P3w|sD!^4-@ z>ZZ)DK91W~y%{)J$}WyV7z9U0Xw>97_sXq-Ds>ugsunA)mAqo7EkL)bnCY62nbr^1 z`}zsluaf+J7ddtv@yZ;-o81~AsV3ZJ*RSCQ2 zVm3jKkgBsHBECiu*3=Ml^OUzWziqg!8Kn?}<1Of+e0La%9|@_xjdcD;WCn&FZvK%& zgkrjd%?Lp9{My+dnbkXe_WvrU6^qRrLg`Ls4H^CwzO{Y}`(U>%hGD2#&l$sou7V|9 zVYFDzF>Ezm(2ui?8%}X?KJ?X@bi};T+y*u`Uh=t2^984nu|I_v%gLyp);9-F?wSt|$nGiVZOb@aE$N zab(m!kVZO+NmHgdOPuh+8$opbjJy$EsgWyGV2wf1F;IkRV<@T;?(g9|4gG!0q%+2(6VQI&#=Yh%xu zlrvb1yM$%i5gzbHubV3&!hV#a%WZB2cNm-xumm^ca2%TgqHO|0UqZ8MrqN-|Rx4BG zuYb}`Uc?jy(jEtCn;nS;kmPrJEzu_SI5Q*Rz7ZMDv?o7aYru~ew@i7N!WF2n5Ds5N zc5Ba`>B$qO;L?(I#wpM+(XJ+D8lvLGHl`?J`S53_Rh^>DMT#;PrzlswqAU}kB7>zt zJ4M;{tn$+<%J#r1%JK@JoHulKTGgMOW|laNZtZP;N^Crq+ zQoDyoZl4`~QnbeR%EE+CX8>SNliEk2w(n=KU6%C=v8DnrpGHNLFQvDloXGe4a8XR` zkconVo`lp00>eXFXCCV%9*v0wJ;X51wQ|;q?dgm2 z;Z^z_wl<}-#mZXyT-x4Sm>EQ8-cKV}b8!y$e#$mG!uv_!wkX*7J`qI(zZ1y~q2>Ne z2%^`Ui3&E3UBU)w9hHXHv8I!JloeDA0Zy(CmX@>6479uk;N#RHCfeD$D$*2D5kP@Bgzr-)m}x%2PMVBH^J-GBI^fC|n4l{nuJ zXz?CR3_pt8L2~tw!aMZfyWND*O90lzG1EMk)qIc7< zaGCkZ@0o6{Oa|M>VfN+>vkL*U3m1n7ZWUq|dPpFgANBmqI1mYV^=6WG0Fe#%7lTf> z3q(A|W5YP+vdO9K>3&Si$6Zu;F(ik5BGZ4NpzWP95$N1_4As*kb&zDyQEU+f+<+{!yJM#j(zd{GjG9s$9I(*D4gY^ul{gfzBYBOuME zk3?0}M~EuwBR3OgQk@!F?>hC%NK1A52uMYJWTK)zVo-~pKy~YB^1?*tOnTiY>YM%A z2SzfZbpN)Fi5;o5fkd!n(Q?mHuXpCoqb7R-*nkZ#h6|a%$=1TANo^YU_cV!S?yL^R$KmjFozK{D5I!xDxYxoygD0R?d#DqY3~h@jnW87t{-4 zg0+LO7P*5L3+t`;)iQ`&wY38TjkCf1lcj395d%lRwL?Q8kj7d&)V5EByLz)DFJ)#& zcVFZ;_th1w9niv1YX|0DIR!IghxSNcn#K;r&zhL9t~k5Dx}L3XM#K(h%Z)00V}^gl z4i}9bp~0fDBRvZTR}20vXw>U%XC(SOi=ej+y0>KZGIq^E-jjm8BV(^2_72Yyl59Y0 z_6`Gt4XLcY1%gXW1PEsGfEaA_&F8SJylf++xP;{}jbh~N(QER^dNkDJk@aYZ$;0(% zeI}0qfcs1y*kLce$pcG>DI&Sa<1E7~lgF8v+~g5RC=+C2Q*ZJZM!1ML8?%gfGg8Uj zRT<%q-W}mWsht3TzY*)2@3pDdMdGq5ttxXMdlv|u+-Qbu|2y7hX}k&+na~FuUCy3n z>WG>er-!JcE9oH;)0*50g4w)8(nENEFEP`>;<5%k1b2&4`8bq2my21OPH~>RxA;3V z6`vR<&wmG>O2-+jpIFJKQgl15%cmk(F0lL`$?~R~g+%4Uv>pZ@TwUieXjk@-*cB(% zb<7Ofran?el-dW$6zB4CNn}Nt4)cWD;bvNu>4NAQJvPvwy!k@ED{VI0nwd9s%5Ro) zA~DprD2{kbRv$euwC^{#Q9s{BscdyLun^#KX2-k69=;QBu$7~ zEOwFPkiH?)D;ZFS1Y{IP0DG^d}4t2ml#zc95;(t(`M+Mk>!qbzBo zHYM7w{R?$V%j(+T&GuiS)vxdduVOvxYP+wURN&{D31RCYxSh6a2b#4tPRkpOU?~_Z+BSG)6t?uXhdbKkdhTb zm0xKo7~b0iLK7;YV$t{;D=9=}!Chi^>9|YVU2yWL3OJ1GzkPdjyLZ$XrpsWNS)XSM z(cKy#P#f2l6Pw)Kj!1pmVZLX^XT|NsPXJEby|(|wCH2@w`~t#Ztvbdn0eU?Tz}K3t zp2z0vr+vNTX-!!002wMu%i>WjIE5XEeXjkLsj2O28glToj&E#R*EgbdVNp@&gQGcs z#cW%_g~8(bdbqZc>b!+9j#u(NRSAoSWKHFij z(kW= zU0fR)r`I)9>m%_ov(~E^9PL0GCV$ZOisI)2&xJGV!rR)$#w?j@9{=^}WveCeY&V!A z@ob~mI!W9ND{JoJ+R$h@>(=~@^^y1(mEz))c(%FCjm@i7R3={o61SWxYaW}6OXAsH zJ%`3HH?CLTvpi30?&8`=+)~=CJLzC8uoz>kt-qFubj{zePOoM4y(R`2 zYC(~?L6QX9J{EQhaw@L*%eLls_Nlw$vg}h|S)0@!`PCk?7Rl55tPL0Q%b~yXBfg3? z)odIXS1&|=F)88cRtCK{JL3}}aI#3_E5x2F^KXTG#@&c9V8Pb@`9C zrm&i}@0;3&<~YPOc6nfXj8~4FF6zL3^f&+N+ydB%C2bc%k? z`MVE2^SM7L%s5wG9-B*sar(z*omYUbKja41tSCh1_zj3w3i3?bsFFv#dA#qJTjVcaDa8R+2uL-5}1R3_u=PO zZ?~zeK2VKq>6ZuiQsCe<4e-cVZ`oKNg&kQ@ClqbTil#!*kj>sC z4IqG(NLQn%3)M11bDG02hUR35%dHy(K5Ii+SsTjp%C$i3?G)jM z<#fs?V=EsVsAkF7sKOB|Lz`)Rp-kohPQ|D=Ot3ZoC6^C_{0x;tmd=9559W^-{bSyV z@^@U$4c;L=2#L|u8V9TU3Cpdd zlgfKuQgY&ETvDPQP!d<}BoVEpZQAfYrPpq@|9FZlV?0o54K}MQy^?Y;6J)#if%oa% zx^`AEGD@jXwv)>U-EM!D+|5cvRnuLK48V7mN*h}3+e@t@WfE`fD0QQVQ50yjtIP|e zj3EDp02kWl4!G2BrASB5w(p)Yg(f-}N1i$&QAadivSAl60tJxO3?NlG zH6kgI|2ZugsP~XiptXVRexJA|+W0{7LFnxyIe04~xQcI*?BnFFg5YSx9e^tgEs=i* zaNKdHZV2COXLVLY)E2~_`Xe^JOS!GSC(m7=lUu@R6C{zf`Z~BpXF2zsukj8IDX?;i z2is%qj9GPwJV!>+SM;Q}ucRl)GPu!iW1A*ZMdwhLLk!Y0qz9R;0PI5akY!vuQcg;C zvh$P%p5n)>c!~7*AYVn|E$SLcf%C=a?Iga-GQ)ikluju_d=vKNJP)NhMm+fxN>`9O z$q|k)aV2M%mf%uLJaVM0!v&N!UenmH1Un^nj43d^TY%XMe1Sf2UTI0^m0lZjX?J(( zQtDo(OOt~?xxAyhOP7W2^}58}8+7S(ckA*_&N(e1#PrUMD!84aPPyF7QKzJykGq?6 z>2x>8k)56T23h2(qBZru7jXOG~ zlv7E!aS|!#kIu*Qu}&4;8gJ5rEyv@{?y%6U$K#vhu1a^PG>JE>`ZgUtdbLVpSN9r~ z>d{g>|46ba-ekv!a*f}>A*Nk@&JICM+~>B$TjFcuoiVNJP*Og&VDE0p4?x|*yBt2c zCBF4IrjccJ3cj8^~^=e_aYvBfKq4P+xIo@nv7dUEqb9~$JcrU=(A*P!| z3*VJwr1?%ynVUY*y1V55xefM}^hs#0ht}9$B1T<^NFu$bbYFrzSWZe32*!oRT|B)T zM$x21o>q>QUn)rC|(%B)^fX7z>>r{t!yLk~#vE7Xzdh;!I2FDpy}H9P-+S&MFI z*g=O)0CBnSc~V^Y4^JCay<p=a))dZhNT$1yUzj8Nlmd2~m_odnAP^{$EYngc*m3A+88Y>P>h>vY z1For3JgIYt$Z_Y+N%6=Yl%dAF0o|DlWwX8I4W%{7R-j)(3G?Z*jPrWu1j5#3 zf&+Isnn;I7juMKkSO8Ql_plh(=&}}XC}bWsrZYzCqgN-OIA-S%8=h^* z5w8rZ{T6L<7`X{hKQ}QYjGUU{j37I7%UaM3@Ty0yZ|3B<15GUeIfj<{Sbn@@8zj>) zE%%8DS{_bK^_-e^Yanj1IWkdd>p)ElbcEhmkx`T0NhXTaLJ0H82RXXkW4p7OFA}h<^|7E|na5eFj0zh6aeO-O|osXBbGoS<0)jecG+$NadKI z9{F!50XCWPw48U@LBZ%!*}lx3;rL>F+P2^^!=dM8hU##)LqM3Z zlqRHiMF1f~hf-;Z80?4rQBG-%$P~FbrAh)d`WuEecNmwfRY}!1!JhHFiHh2r(x0|( zg7tgVv{4$^;Tll($_|I3`36vJ^9Fdf5U~=~Ne~W(c_ldJ<(u5g+;iw=Qt>a_*+SNV zNaB^J3(>s(EcjV*h+##BEkF@}2daW(Mf4*odkZ6j9+oiUY9svAbQlhC14!K!-Mo*5 zlXFE?Z!jM3|pNcNh36OdtEfELt4coMIWfhN-NA9Vo56pLtY=-PI3roMyT#tJ!^XNkx;TwQ`>w>s7xW<5(@l zYQ?DyI;&YnJJmV7j=cJ__OoI?8+#cam~d~@2H}jCr57-jr*<%|d5cp`7N^?0)KF-J zE;K!%ClxOT7{~qeLpHZ^dPR}qw-+e>s^Wu%!h>DK2e%d;+?GFx0_XVeSBxnfF0~F1 zqgiUTZ|1)@Fj7(`yUpkUW6H!SNJ;$wl_RH@Pyy=0FeTtK7Kk(mA|`bwa^}aXY;A~m z>duCTv-T5=I0l4M2I|J4u5<_4zkFSoVxaEsP?zbHy6}Z-cV5dcecZpoLr-kem#Ri79n4ZE9MkxP&%M+T1Max)3T ztBzaS_qk-o<}#?ZKIu5s7Fx|iIyV87upDpd*z|^d2PK)$mBgcs_uKKVv6Jj#Ld?|& z7Z{Rr)8C&o-#(Yr96klt0kI(yGWWW|C$)@Dt6gl+aq~M+d@(+Y3>i}f2I$J&N@YJB zIKj|Y+iz6I>IdVx=fAr6uMYpQKJuR`PAiqdw4$$T;zfgW6K|zwS_vYOX%`4RWCnyJ zTL2yVDxlLzM^lDPfUE#<1^I1bLB?zc3KA@5QgRAs+^bd&Q=P;y4wPySD9jUH2jEM_ z%!YGi%ZATHugaEPiK&iapUcn_tV876D1GZ z_i1*fXDk{k$V3T1@dXzvXYpr3D~{ZF=&^Q)6vm@GdOR4cRgH(%wL`~)xy>P=8kZ5K zn&usF)#7*rQtBNKiMgC2R!}r(KS0o{Xk-*YUy_U>g#XrJwOkPsR=_xOHdCQA2B>f# z;rLK}qc^>{sSV~R0urSd=OCaOqpMWm0GAn*1Sn-*_AyYJ|GiS_%$|yM%LZzcbr^2-9p)~B1DLR}s-=APVmeUjg*UZ$$27oZBaq2K? zV}v#*`6yFMbU2ALRbh_fe^MNybn(AB#W6y0K#53aG2ih@kDWtOL+jD(sHLQk#RRMwyd`Bw+K-eV;F9PEW{@9d zQsxc+eVX+RL|sBvY__w3t&UVvMs7P~9%R6!C_{+SUm^!S)L>t8ti!?zwe_tg;i%}A zdHPjK`ZQX!S&91}V$OOET=t)-$Yn1yCUprbFbnM*K9n@xUfs`xFcCMpH5Rvwzn6^M zNhoLyEL_)|P+*!CuB*sIo@XabNUBLBQsxAsvDw7Ic*5&D6Vi7k=6N#{)7dmdA;T!~ zq^~>Kps!0dxX*vkK99)AJ}>509ceWzg$@>`Suung8fe!vr+SZ;l6@DpQUw;e6@NZ} zU+7YfX~TjD_=I8!IHrsPdno5`kT7*-UrJB{exc6uDb^)A%`DfP1iMii*jtD`C@gYk zQ(@h&OgN|9f2Z!gQ-$4YtQ3Qi+4|#(EkbQ#m1^r~uSu1#_@S?HQ)8MbIHsn_*Ja(S zIAv$p;*XP>9Htl*oKJqm?IJ*IJk8KEWXOU#*);t|LubddyCsWM7z9?;n842GFi=r1 zoyhP4BUg{3(GX^1St(+6P(6mvgEG{s9%r%~q3P8zfh*Lw<&7vv>nDjB@wLv9MC_P+ zVE|3q&>NUOW-)9c+ty>&JL{#&5k`mxt4t$PDzN&jAgxszX#F_4msLy3juX8E(L5+R zv~P}4`n6*^U)bTGt`m+2ux^Qx^C(lrx16` zh=X!6X`t#4l+QFZt;s1$pJGa-QVQ9nk2&XWIpV?Y(laO}c9@Mv(Br_QDIXR)sq-Zf z6_LzvdW?YN6w2}#Q;=^^l&Sh+CkneNe^(&ss}E3WzjN?0TD z;DkN+^)iEBUQVPEnz5cI7>#Xo7*qLcRJJAa}SG%=^vFn}}CnESycf8I8&g)Wb@ z!m%1!4klIjLlb=kccH$zthR+{Ttn2vHDq@5l*D<@qi*w1B!Wh6BoeUPsSYO+)Vn|= ziy595Uj?4|zK3L@+^G+z7+2>j4%&wd`Fs-OcbujH2CS7o%llJ~CmB*t_EC9$uOPvZ2jR^p0? z$OT7CI0;b{Fy5&=f=Az(Az1+uMtbrBt{2H8#EZ2H83Qn_7X^z%V=r0kHjiUJxN?I7 z6q+jxF>dF({k&Vcn{P!am|MH%&30c(*^T6_(2nlOL*a1tn@7(V5aP7uC~n?adQQ&Y5$|b&*h7t^Y!m42(mzH`a#QJh1fGcF&eET)*utOXE&QT1 zE!V_DE|A;W_{xfHd?jx~CJ*1nVxf)a$F!k-JYOc>ba(03rC2yLJZ5i??!T%(npZ!z zit3-wt1qvjdN`PtF?1)e0*tV}fLjlc_c@Vga?B}C9Ti{WM4m}P)&QzL3-`c6R%A+( z-brds;_a5eb0H2j12^YTLxx&cYQ-~+?-Dn>fAc1b3EwhghhtQXx8K5E+4$z7U2PlHL6;o`R3i<$c z)qO+-^R|?=rJ&3oQ*Hx;3{R~5N-?^i`M|XRg9Bw_kxxe&gY)o; zN6fS@cSU#P?i;yJk_gmVyQphkY=z%eY+pq)|KNM^a+oLI{66}2@Bu1n#jG@uC7Gvk zRW4Cm;>s7HeDy9fW$v>zt+PY*J8=hZv^0vxJjbmmR!I+=ab+Q^ri;UB-;@VVu?5 z-8KMv=_dCscK|&Y3`r)_fK*El)rzHdzPbC z=Lzng@b{nQp0l&9{8QY2iu;1`{riNUm&!SbpGWL+Z_9#ly?h!ONpn!Yk?)yrQI| z6@#}@gx89+!OX!Mz7V#d^}%b_Cxf@r4=+B33|>T?zPHHL!CPH5yhu@lSDbp3?ONcs zT7=h%&Jw!o;0<4RW$+8aFE(RDB#pcz>E`XJ4!`&`GI(nqUak&aSwLXbLhnb>gF=~v z-jisv2G+{=IN{s{Nf7NtE@556?shzfk8x)=ru?LS;> z|CnpPax}Dmls1q0_8;b++G_t;);@0(+UG^J|M5cmOU3pdbL~^X!~b#G{J3v_iF<0R z{l~KQd85#NR`&#TPoQC?pQ^ht*VV@SGg9FC#~g#C$;cl0`YFB7n14ps$9+4xT05T| z*3M8l{kU)Ev${U%+tJn9`Qos4hQjltZ|94;p7!nNYVCY^SUW@EIqlo|vaZkhc67CN zzBa6#q3}HC+xeQVXMH=mT07qu*3M9P&iZz~q3cV&9bK)RSBAAS6rPuSJFn=v*zmm0 z)!KP5*P&OE{dioA*9jI94?T><|6#k|6+P70$A3IO=G)iR+JAJ_?H}{)KkC~*P5Y-^ z`;}9Tef+2I?y4+vzwGZH=l*ejf0Fx?{{95_C)D249v)o{p67?bGZb%6dw8Cw&4uVp zgJ?qxcj!>acJzTpaBkw2Z60p#M6J#IuxIe}h*Oy_USQX4CWp?_)VE>eKZF0oaCnA3 zo-vr!qSY23pKSy=#2ZmAhjk zNcx7H&CaWdWjrW2=sDoWtJPGprGtn~-cJXtd9~@1^~_cNiB`EK&&|o^;iRsW%0L8} zwW>Ll*WT>DajUzatg8_;K3!1LbwQWcg+&ayKMo&Tz0AnVPzNshf~&M| zQW$lN!?gXsjOux%z0-QGYXq`HLT8(a@ym-@6k~&?SQd|J#JJ{c6AXgGDGc78syJy<(8vh+A=}G^cX=?vq_|B5P^CaJ4 z_1k_o-6+SC+Kqlhw4!_22(8u^nx8 zY^S%ncwN9`6Tn?bZQ1t&+}|E!J)fiY!@pWhH(2c#h)+;3fvf(bJ=Ndit1Du}@1lsY z4*$`F5uE^f`Rg<7pPnRIeA1%a38=rKOf2Lm(y?B&zhK_aaL?dX+h5W8`rq2AmBTo; z(*9q)QEu4N4ecM&5Im~=u}&-=n?PVelbC7p!iTcL2Yq3iZdt{t_O)RU)xtz5rvZ_X z$|ghEbo+-P?Va0VFGkE(It(mc-r(My@$X9LuzTlYzDeZnQ8QbkIkyj~NlFMX;A=SW z84zi8#6DVp5t>tUxc#04Y?+r|RpsT!BqBlEuzu8$u*COB!uF>DY5l2-!O%v4p~j*h z4rdKFx zG&YLUD}!DpF9O4C^M|IK_K%M0bOBG|E*txrL+vP63_{ZowJIEaxteVP8j7Mm-me}` zmzw_wK2uy;`r%KUFB|jI1u2oBP4ll<|3f^I1akEWu^^ZoCgneic>n#6yj)@vP?cED zsx>3-uhRC9gk3<`6U6>F5>(0-BQdppTP?mK_NP$0fVhDy-bF>qXLk@=0tAFJ5?>1Q zYd8~#Oon6=V78y8+AT?GV26VRc9wbhFfxI^u)w>z#?;M&anlF*H5K63oM-5evQF&g z6wDBMac%SfeQIQr65OizR#PI-rQCb$3O8{LFea{5RsM^z_E!>OXG1J-5ZB(QEwYy| z3ql8(N?oLagow~;EQ+A@g^DGu#q=IYSd{=)!&KHFS-AypSvgvoDk5x4Zr}JYUN%AY z6AEE02r^%|q9juH&4k464I#t~#n~>s?}UZ4M~`x|7Ne-`K+~`YerSJ(Q<|_JxtOb< zJ3%bgJLjVjy8Wg-r>Vi1DltRZy+nZMC;QTf!!S*aZ_c}Ka-r^?(oOcwm@i^))~7~) zk-Zky{Ja`nKv~NRdcL=if3NiewmQoR1~T*nBSB*VO$1{BZ30MiI)q?svxA!~P*B0E z#?{;?t-G`JUr!_13b2wsT{q5u-0L=;I;#Gy@Dv!0l=2yfsBj-?1kf^Ar$L#)Nf zaHO?yY-GK^|9!7Mx~pntK#(9H4RJVC{i@#AefQpXzuv7dmCBy8{=tDGS?;f|N$wTG zSO}dL+P;_-K4)$h)j{y|xxc(8k1Fm^J-s}XwzA78i=undqB~sC3ZR$JY`O%v%lr}~ z(EFGUyK1;d>l(L~=bhlb4V?rAPBTXXg=$6Gi4g*1WPbu*%}P;=#fKymxFl({cp?kA z)rpv77pTS8W)CuRZ^AS*kh|R&A#QkNGLEg*4NvdjRULD4+$?V)7(DemwMQtKA4b|6 zJl~zbQEyvaZ;btpthdc()+KfqqT!tx6Ixj``I+k`Lg3RNKb>OAU2vyf+w3e1_!u~l zpDf!A>9SeU6`_zn8A}b9dyk?aR~2Hwks5~;)G7{Y{c*M+Og<4mb%MwPU?c-4Y&-|& z{jw3k)8m6|4lqk+V`(71f&Yj|9K=(hhh*saJ1olhyDI32*qA%P<-|AJZUldOMPt)j zU=&g7;@OTKpYOP^))RCwBGJ8Yyfu)m!%K3nh;d}h8Ar;ZsV{Hih!S>Om~mu8e!>vx zO{ZwYN6k1=HuKO4T)Z-195IYej3Y$I&{WeIN6H#OT9paJHqofV+uk^0I*T)o*oek3 zjxeG`@WMEP1d$m>+QDz(o6XVFJ6OUvZvBM7RPqI=)=vN%_9d#Bf zE9$x@hzwQ;bg04>Ue)7BVl|65>4b#&fP;8uR-#Xuu_u*Yo6)HE4squ;aVoKP9P8HQ z2Drl=zOLugxw;&nFy}AF2)y&xD&6MlZf2Zs#C`=Y$;>`$7g3oRNMiQE@~R#F!p%N1 z+4e`h*=KDunwov;&g@f{*=KaI$M#)f_Nn_>b6_?TUF-*}9!8X!efU8MoQ2*n`{)@$ zT4MGQp3CervLcfYTppHU)}H#J8dRDtS$h!8i`E|BGq3-nelz#_duT(imsxu_$KotK z=;azKt(&E%`b56B@{Dk0o$7fDPZ>UksfDNP>7}>ujA<{(TX@Qb1p<^ndQ{glXb0StfmQdcTrZ~(qPl=dJq{?cn+1`8|uv7NOaQ{CHY z@7Y;;O+bY(kSJ5{LVK|{rXmw~g_(&@BXuwE zcAi$8C7({xwehxnnVkD$-o1dB>S;yiL2;jjx*)oWJ|`D@6UATodz>l2`kX?7$@RHu zpigW7>XVE0d7Jeq$a+%%6%D{k%yP4Olr2CeCF^nXV2?Ao9$A<)2TH@|MF~+0ApoV) z@3Y%GYp+lO%gCCjs{|aQ(S*(y;ub4c`0N2AyTS&{^LdMxOT zrqF8uJ(F$Aq36ht4suC?UV+pz5PKea;EyxzvRk1^dgy7ef}X&Zp~n#PEc7;A51&amm1VkT#Ztn9uITMdQ=3iX$qH~gyGFX9L7mqq6h z_UC?C?Au;q-*{FYw3bLSiWLvyC!5wEv1ar)*X+KJvi+`%_%OkFPyK3Hwkb}Yp`lf84?{kBF zD~?Wh?&9g_`=fj{A*C?|)eZGsHSfJ><;0_o=4p(wfxe%Vw?3gUSV{?o7?Du;xOFz=LI4d94g*n^`$rcBu)%b_)hENIjW{dZ6yRsMvv@O(- zLUs!+Soh0VaClRZsft6%e3m?QE%8L{Viltumr2f=V!4nSaGoWZs&{R~82L?ejHgUCRWTdhG5nJnq1!s64NYcC5i zG6R%oP#|r8P7xMh2niILah=?t0_+&m=VF0Eb<=MJZAAf%=pArZF$1&>XrCR$ge2@h zilAULt`pniJLL^NHF8&7@FMnvpIrJix2VYwz#pDdwP_#8QGK`8vZT3Dng^+{f+Jc% z_8G5n5U4Z~hf2%GNTUWTHxd(~}uz`>xS8zx1Yku_$q7jdEZ|zM80W-y7EM9olQYxT-^odPm zXCfvon$&h(pTEzn8}YooVk!ok7b*sclAGd&XO&1{%$~ah5)%>j=Ck*wkG2GVeLvO} z2_vm(J^Rl6*hN}$MC?Bb8DP}Wuj9t^+md^OZ6&FeV3oQy<$_xwwIgw{J(Qk=Xq}G z^RWhPj~H~Ejfbf}6DI>2nEE|wDt!a#{M+~ljUY9DkDB7Crhm_1OZOzxXH1)!0n^8( zotr-8$@Ket{3Hq3o$vv>H2k(SV0RKXj-pb%8)s5TUls>tmAoq_xo4=8a_3C=fZfu1 zw=jM%01jl+l2ZZJQP~Zz$Jy)g3SQrpy>1~N%d~!P_WHfcxBl1nr>~#2W9G}WjtxJV z>V3ZTXsiSTRyaISD;%DV6%G$tg@vKnn{pzsaS7Ho0LVke1!C*Klipe`7+ZCQV3D2U zDnuJtLVcIBZonMCgXe5tS{&<7S}q}ScPhgY%hn&%L?(8-0n(`P=cP7< zPb}8sd+_p3L>ZGvS%g5FxOzi)1Z$S?2n$6horHCnG6^*yr!U{tOSnXbz!@5LdSDM#)}CFGh=!h;DG-=sM?A5l_25B_KF^Wd+5FO9qm_);r_ulun=_0$K>W9YOB?E*@d8CA*-GFEJA&J}z!+wfj!+-e zYb%VlKd$$EwZ+g?KjyBSqf~3*{d$#1{;Tt^*8Hnn;}bkw=O3!=lUB$i){C(M*tX7; zZHPMZOLtOVGzDTFK!-cqSnUHZ_JjA}X4ui9_APPIeHFfkSICtDh}R&Qtb;j-K}LSy>wI;^mf3RgQC^k?E~2RPcKjR`BO6Q- zkIeX7105+or1ECSk|!*~ErZz+JfSh|2p)^tI16h1YZiNJ1dH^;m1~@}Z+*1Rn`*i9 zV8DL4UgFCMAc?P_=55DG*}90j5BAqgyQh2xbdC4VwByqfd}31iBpG_IW>0ccU=tkI zV7?gkuVyeBiXx?Da`a;vPnU!{KNf7R)PfI#74Y;>V_|$rStmahFz0GN77^;??jnLt zS~hXpA)yzhY;V-qd`vc-nt-k%uM%wVuor6(ZSXza>&CBx!Eo8IO$o# z34cB2uZ#YA#9t5l>w>?|b2Y_Wm@ElrKYT=pulobpy^6F8=sIV0#MhHLFs-ysc5iji zt*wp(*ag(pv<~&tI@!I|LAA9y(#xeer*){G*2(Uz4jY!$ky^ZPPgaHMX_f5Ws-X5- z743BkXsO9;?#XJTw^re8zJm1Sg|}uE-j-EJZ>_>xeFZAU3wLJ~-kMcNZ>_@Jz5*5F zg`HW2yR!=EtyS3RD^M|B*pXG(nN>({t-=mpfr|0MU0H=4S%vi0D%|BOP%&P(Gple{ zRw2E$3U~SnRE!t4XBF_>@z5*5FgJbklM68MT+HpZQD#p|6IJx@{5`?Rb2RbuVl559* zuh38FvY3p0#A%7i+_>CiOyl|Tv3mT)pnGd~r~Ujjat5H&nekSOCoqM82}Pg9GgE;+ zOND;d-Pw74RS)4HxUL`!xS?uFS0V=Vmz&H*V?b2Z!6N<;Ey9qr$?= zP2wX658OM^o0z(d7>oaat>?@B%MK;nK$f2F2YFRK5sv4**owpMlM|iIGUhSq_&nYW!KBhD za)>D>qYdMyc!#g6&9WgD%$Q>#9ar2F-OFnQh`YRo3 z!6k=U!q}y3cvN#h+|wgZ)}?3ZwZx~&UU?WfjKA!dY&6^;ZJ=myL%0b_$S*bTsw)hJ zU5A}Q<@d~5p<-m>1!7;i&op~edf@M`<^G7j-^l%X>`ENf7PJGD~NH07*6 z!SZq-W1G~tiBz%jV=6%iM8`{t5PW5OFUhTM^dmCev&G&Z4O052U?;`0`_M#S!j+UL zy->k!OZ6Fx)hg3Oe4MD$s7k9c0^y_`#x`X{1t=i=y$b{dFS!%0wliE+sc0_4RXd%a z5{K>fzN@NG(j1ywB`PCirD(1nsw=6I%Uc}*9JyazT-Fr8`uPxbM!F&z`25SDf%s4U z6^9`+S{XCCs6-E$EJ~@u(ON&WLj=l9Bjw)YS;FxFeS=&e+>uyhgu80cA0?BB7mwgX zbyfT!vrvr1hxjGjHAG$r)zT03#`&ewAmsR$%|JH+90le=Cu&S6rkdm3$Es#EZlRY| zPf@!+Ur+5Thb*BgBvJKxxLjk;H`2zAHat&ZbkJ}~N5Ie?6e=nCBgya)eI79KuR`U6 zz$t~NzD=LOQy(=?;mLPJ1Wwrq#E~8RR9Wz|H~AF8PgYI3wcMnWuX@5(-B&#?27;do zQwSb39219P2!ddtqXdGg^ss@7S#{n3`5P`@G{T+-at^={Y$FZg9*g(#fV@Qh5NN|< zna_6< zA;Q@*WAIpC@=W69!!$_SeezvhJf=TO!C>5f$a5(eB;POt24^hQyn{g{0}^s@K#1|P zaQ2s3S2H5cNbvYZ8m(F=)*<=!6=QfQS%=Ek)%S7@e#C#Zg$B=CGEDjxDZNPA4S)Lb zl=}>dfk=-Ea8O}kU{;u6%}XxRri()7{Q^Si{lZ}KjPCV-v5L`=3n*iBC&@sSF}maY za=1zTW9$hRS!u*-=xMizeVl|iDE0S;T(b%a3-x5w&=qTZI zmiK5vuwqs+Bd=QOF{^=FOIqr0Ub&_IW)VovQhz;BuQEm`wAR^A`T1(tPc6n4`>Bty z&D&39jPS9wl63Xv()Ls5P*cGUvS7V7+>dH3wa zG5y!vmYPF5T!|Wv%g*8t{VH`rt8RmhGFIT5g1*1 zeBa%pKv;H!aH;GFuf73oBGH3}>=BEdqCMh>OSv5%anA!)-G@c;k#SOf0mWVPe5O8!${9QJH|Teh?V@>BUSF{S5*}#~C8bP;-#f z@8dFscq7GlWH~`FcyN~o1~09^JkePJFh1i0P}u7hEX|1nMx}Y;C`*Zzl{v6>_LsRY zWuDOEWy}+w&lcoRvLIFak@dY?gU?T-D||HZ!AP6?RMyc!_x&mZkscM`pu)nytT1c* zkTs5>Kwm@S{Q_pGurQdsd7=jxtIQJzL7-AI;rw`!EDwx3Og!M84UpvmWkVFXm$r=- z#~HxBwh~fhG)NXHPlMd$(TRJARqT`F=?Wb%oiw4reT=n~{P=FSkbZ#t=2~vj zeBN8n2FQ<(dq+c*ca|cfxh|7F&zHQ(@tV>aoH#Xy4$vAet$^0LE1s=)8-1 zFsSHJVd^R@49p6%#`js{I66Fe6_7^nYcLN_h>oBatQ@PRD@B9>m?ceDZ&J4CN z-gGs+YIXU4gO_D>xqH=gb%DtNN=#Q75U()PRjO`Far|yEU8R#!6x;HXS~Xp1FMO>| z7F-`ThrmMTX>FTZJrmLM-N|55kny%`r zrmKA5>G`!4I`Uo~psWst(sZ4=c&=;D26W^(yIA)1n66HBFS+UJ+sfSN!Y0nF$$(L5 zx)QDsS;HKNtg*k$eJRtG9xr3M`pa%QhL@5Bsp72G_i_z>gzTAqQs>tup?(MrFJ>K` zvX1acc(u3y2WfwWfmvaOJ}+70ndz#4S$e-Pn7rvqaokm=t5YCQsp;zUWRWaSPC86H z>7EUcI62^Vbj$y<3$ZKtNIqm!51boKk0(eqehQHAkjrYo&Das3R_0m98}Nz)ZmUyd5SlEM0T z0_$q>qW9$*d@=%{r>gs>;C!qoMCVPIC6HGbS0&rDYZq|y5t%)=9+ zBcRvWv}(E%H3=|Fny&gQH(m9IOjp;enyy}^>1xNS>FVN5R~ZnmFw@n5;<&t(2ZrW@ zCSLo~Z`Dy(>7-U>k6Sfe!I)n&)78Z>{maR8MdAf#y1D=(%&O@sg_^z)T_pitrlzYM z-gLFI+;nx<_loJNv1+=?o34&tU7;f{URBhQk6h){#Ut+7fR21jWhJJoc{-?yy1M$3 zo35VaQ)k|=apbDJ+I)!NSDUU5Zz$@{3mY6T7TmJ|-T8>hN=#S#>7~MSb?~Z7Zo2x+ zh7=eJ8!}*2ny!Q^L_RSGqOR;Ob6?7IrN_&du0EeF$f0CGsyM6ly1r=+r>3iY8!ox&>XYl!6*{m!Lpy?v7;CBNYX7<-`OU3!lb&scSE}>FV24DKO4VWx%L3T?to+d}0m`UL-6c=~`uCHTQTK)74*In~ve7WI?KR zYx-VJxBkd<+Ti((ep1rrUd%c=WgTUvs{$PKeqmr%n4!;0)_7*RDqxo0FAOGcy1EK5 zR++9&fk36EtJBvM$@1hi4iithX9Hw;hO!~k)go=DrmN#qm)vyqjcd{sI(bcob_5$S z)>6~e32df?sH>~pq>s601LSv-vLVyeVcJejS4Xe8Y zfFSCMSuAO~;)Ug?;VT)ek0-FMCNFwluE7^Go^dMS8N&4EvyP5hN15rWFm=6O7?>4i zjUTthGt*T8Y4pAZ^YDb|2zu#kST$XVngp07O;;ONZn{!d!2E$hzBa#_rs-uJ7`$WE zbanAjR~ZloO;@Bpdu=~;T=BI9pOWpaBqN*D#%jaW<@S*)&bJglwJh_&J< zqSq$&>NVXkUs3p72Dz`s!Ggng`0pLO1(Q~0${JS&COyW&#?;J+8rWL;mOUN2r(RIiU*=QPbD?%9BPeN1H~R7 z;8R&g2d$&b>Q#V)-Y*Qy3bV!!S>u`2tAJU0zc84*)oU$atg?C?1c6GeUh|uZWO-nd z!^8vb*#KECP&Q=s+DqH1)ob7DF1gj~lbg~NIgTI>Qz7*y|2MMJRv%Q zUOL@XtCtW*B3m84y>kUiDp3EC1=#R_@cO zE&FsT=~a_Yr>-nSj;Ig+MFmTAxN7xc53|o~P3S8ob64p1MJJ}NV1^&;2tFpbKl@U! zvu2-A4|lM;QIdSVTKSe`4YTys`h>MCA7<>)7pz-Lf5EzJtMtaj!WK%i$!NZKfuq4% zPs-U>Yc$V(>%w63rdMS&s}@P8)vWx3B?&gI;&!SJx-V1YDDArfw=V;0vE-%0w|i^x zn+B}KXid&qj1k$zLnhW@tjm1vSvB$7nf2K0#)~p0yKqToT|V|*Z%7`!5JU2lA8W*u zgI^Mjf0d6kbhEM!Ul;uzFfO0Jp~8x_mj{KA%Dyw`oa@`O0V~#=-Y+pOpSJSykjfh_ zxpDbJH>8a0TtBn%5F*Hws*THMdqwNknVtj28TV|!x^+%vCC23w^ipA5KGnbE#^rDK zQed3vWx%L3E(=!(sbmfgUc^lHmNYKw@iNBczwD=Dcqv(sYU>w$FW2BlHm41qzrjyR z_Ldj3j!s!enQ^%Q2fbeym=$K|^O7~58J7!~rS}Vi$s3nZSt^aor$C@mCuSOxH@_IMvWA51i z`JJR}$hdr%wo~Ks(dd#Jmw!KVOB_pl9)ls3tO_BO4ATLEkVK3mc&%J5FeocjRqcTc!!I;GWc)64&q^cB1r4(&b! z4vLbh157W6ohRj*mxVz*8O;|ja5OkMUrlGh*(%|t+>x^N6&cOL6E(Te%)Bej>NSl7 zUPbM(8%B1&UmqD*L6H5Dey~;4PSXFSo(o}@j4O5!2An^DvvLbA%YG|rE%x=X#Qykn zTqoCpqX@53Q1*LY5950G4@M_~xYpB`FHzymt7+|3D%K^@KIX!-?*{*~KMcDM^~R;o zmYkN*xO#Z~TZ^gD#Lr{=?HZqyo%m;dw%*-gUe(OyDj%yp_KUlfw&VF*J(n0?+TGf^ zCGa0YW(fTbP0Gp3Wa|Un!ZBGag)sG^*(sgfk?5 zdyiPL?9-WZTeRAa5_+U!8ZTg6Tg?eD=F2|}MkVJIPTnuDRYl4kc`lgkKGW>+t=f3e z-%oRY%-?U~{)E5RR|!t~`|G%$_xIQH&4<^0?#^%n*G*izT&KBqxNhV+#`RjR4X#sM z1FqL|-Nf}eu2UC#P+_dfzjXFrHR83I-)IAVqxhQ#8u3_G)==4ye`!o*pT`e1eB*RfimAF1a7-*&9=K ze&oiy4g3(pul7S7enZg^zVHSIj0N{>zz}{!WhH*7{q$1dhdOxUCHF&p<_#$@7T%Bn zqtXv0T;Y%dbKsDJ{blY;9&+IEGJdGfXA5#DS&+*8TzxOs;PW%-q>j!c`zU+-r?QR? zT1S~5ssIPc1ciZFVb=H|YdrHq6);Qh7Y38}LrGGoV%-Nppi)27{OgNkdEoU96A!p& z17x{C*^nP;D?%AxgTnB$PZP2jqMYO;po{_Ka{>!wzAmulJu@95|?R?+*Lo+^2r^_>`wF9 zl1e3%mK?@sYP0>57HtF5uRs0@sezjJeUlX?O6WbImkbH^W(Plq1Pka>GvrtCWXfi&5=ea>5K<;W- zjV&c$m6iScEfrSwy*wx!!g`}KIG=l?JsYsH&*}XV=htZ~FF%BJ%O!Vyedv}{*gN;e z%m&S&BBoUB{5pGc(fWSoW(SNj?%9C#{hZ25oL?vCrNa4j>W!D&`StCaQ(&CAIRi$e z^GmqGAuQ(L;Kd=Vo0oKc>G3koufKd_I);~$1*z11)%S7@eq>A9;Q3qpq@)PHn00i@ zI?9}11vu#a!oaLBL!Xzd@yz*Ez%0FA7);*zMbKNN^Xn7{ROceZCCe~b$} zZuIS~v3`BG1{pQqVS{Q$lid&W0yn6}?vj?H=C-h5W1^v?gBS~U5dYf)`niQ z1mwIo+vA6>G#Ju&+gk61T&db-#0~DUby=e)^=QP{>Pc<23ZMFnj+U$X9Et&Ng-|Z4iiP95< zdxAy806PKz6XwF$1P*2p0K|}?0ZlFSp6+`@G-|3HDfq4}(o#FLs+PBj+K+slm ztvH(Pk80UR{isJZ>e00W0 zHn_o{b{pCmh#GV^ssF!^r5Sxk;|UPd57>Cn9%vBKuZf8=K>?C_Xh9D>N^9?(?S8o? z!XB|oqJDrNJRK39j(98@5f+Vrrz3Ew_=Pc4f$oo}8uS+L6+1lx@@pHwVKP4k!zs^&84$ufD`?B8F*`GQ8>gErk&9*?u$S`QrGN zFQhjLH>QV83G0W@ZGrm6`dKvSr1?+<>xXp+WC`nMuMz8KwGEICLG;_P{{E#feQ>hM~Lu3+m9QJawKBt+TWV4Ghw;N94J_4Q2>UUn6VTZh1Kr6 z7%z4AMr1sq;@$N&f8FY@xBKgx{FP8}d;bo9?@d{~Hx1Rxnw)n{Qt!=4y*Fp|-aJ$cdfT#k+lK08P0qU}skc3;w>_)3eW+g6vwC+A)ytZkcTH07tx3JNX7%1WR4;3C-Ze?Rwix7Z&vZ%p^90X^R7)Q!nb_I`?8An4OPtAoOf+fk&_?3;{930`-duKZO*$k z#URBJ_y2Bya8RcIw4a;|N1q7)36k&_`>M%!!M(xuFwjQd+!a0%H>6Uq72k|((b8cO z3BrxpKGGglA}*$mv1f72<99l!q`caYU>(`(>|i>I!j2}XV6fJRb~;&!qeic;9z(>n znQ#VKqPAzU8HD^-LwKUavHJr4`@xAun^Pjmh{kl-C5%SsP<_~4kc_dL_7+OEH`T() zJD8y9QXQEbFoKHCu0P6#%1u3Lu+>UQy*cc-w(6R%)gPe(!m~s%gycO)7vWF#N1gPu zm;V~y-`LgN+G)1qzu`Z$s<`%(Xt>gOCFX?jd5T9-aYIzxFixx7-XWa`jXjnKJN0Ok zUkFv{Fw__&s3T2j{tPo3No0Zs@(TMumj=tELF=Ijtu|vVl%GFR6iZ>4gMgdPv^zZ0 zCJPz%8k#9R(r`M{k!;vo5m5b18*Zi}%yfjAHqx0km}w)cay!7`cX6hMH#Q8WW;10D zZl(;t&6MAJ`ix7L(9cv4{Y*V_`I#DWHEpI^>UiuO6XDSM7G}M|^-X8J^7UobmFw$g z{R*!ybIq^thRb7xZ5Xfk3JMH$Kp!qpOztbF*?*IZ8tCjv?lBXPH!$g#BiWdtU>qv>bq;}oE0Ey16dUle1t_-bNWb}8X)eBJ+%6|wa`3)yMC&(!VRGj(2`2_qY}!0^W8ahWG!crB~;TX^qIQ&Jykao%H1g{mWV;2H$Tf z^nkPlvf+*+KZ*^EPXx@+3ZdDtwe?_XG-`F9hv>$-|ADD7*R(gON}yWTv9_9sFKp!c+;4r3sLzpnpPv}+GuesELJ4yF zK4nccTdJS6Ghj;V^L_F{u1`-u*lW9gyEo>x8Np+|Mye66&(yHh8?BCY{|@;?%uHX( z`=i!2YJnNHnH_{G$GShjdQ>ruvF?Az%dFjayjPB)c^EiM^KY1^=cV7NIYuQCPfUa# z%^vUdk8cT{NUJ=S)PTc!qas{5&zqSrJ1dL>G7RtJm$c(P@Z%m7Ko@2nu&yYS>WVrl zSqgZxkNs?*Bo56)65~pn%pEW%CU#gMlA2a8wr?%by6JeRg;dUYzk%nR4 zrV+kflcGn*;g0RwgBWv5;0=v{(1r69LGKo}fEs5#cM@)#F&C5Dv1n-sJHAtU<QvRpa>!ruGU;tR0zzc$&6Hr)~k>EZPK39WLb3MkagxbU8t1)lmEm5bv zxLE7sSg-#i9y;dQHq9w?R-$odJJD3f_aJd$O6nkP5m!twL@Pe$O+{@CD7kvKcjN(& z>#3=zgZrb7sR&QJI0=q_aS~cmX%86v1=`K-_;?!Byc(mT|S`i~XIl0vaw?u^xHPQ;_ zoS^F_KI?r_Ei^1pVS$8IrK2wqG*wg>hYG9vvR!~^dFA>UB|%oBf7N3DYDU&yKi#`V zJs)U9S4I3-qaXWFO-PN@=y#*;Vt<|9TRRPM@Mun2i*!>8$PlD|b^ce7J8Dxjz9qPZ z#U5K!ov~@KMdf139X8-;+i=#tT>w-gh%a4GZ{6D`YQnfJ0V~d*cT6ZJvG@;I$c4ah z1oeI!)YC*dLar%LsH41M6s%Dnu<|Xz4aL5v=zGfb9j#Z-leBjgyim>1uk`;2tvRLt-LAEhw3dmHSVD|{Q@Wh;|D!3$-|ZQ}5`_8_>C5l&FN>sT z!t;DVj5ai{*i_+2j##0GL?Tk7puzus`8JHG`mqwhzj=~DyG!Fdbx9G z#yN)~)3=-n`EjQunzaGjmbCo#H1;U74g6!T0koHO{|$T7mUaHg+v3&d$CuaT3WgA@ zG}6?UuZMuw88gW3)KRz!VH$<2ZRh$`yDA$AOJ`2WKvca}b`z%-)Gn zlgqoxTnXdm{@512Q>HRrQ!Ix&;KM0E+zEBL6FPZ!!e}N@w7olF0``r2V8ETw!JUw+ zce`@5c5?27364D#-3hd0?gV`m9(Mu)xEq+3__$JFd;cfA2)p1uH5BmWq2h9>cKs2eI2>^>4^xC~JTl`wt z;@8vb+Qb&$frJr5+|k8)5AnCVnAze_IoCYMQdk{GhLaEA-VDf~^Kg;)954e!d*aQH z#G5%b*NQhe7cu26xr;eF7xX(t&mJ^ro;^E~r+243H9F_sh^UdHdHm;{dnq;IBH06> z;@qpVHSs^u(Vf(}w;VMp8nQ@@pj)0AajLAuxtCBQB9VE-6%x+bDR@ZOAo9~W0Mw?u({iG}I;=!JxS*)tRR zy@>6zME3AfO@Gj_M;A{7$KdL@*3&sQCzn7Z5ASwgcJPA4SUJNhMKSqAGxsaYocLcWYn1pb zm+HWny;lR0Ai#@`rBL*gZ}Z8NPYh#$@K2KyyF+9*B(~X=>H^8Oq?g%uq_BX-^BfN; zJzk^O;y=B)wo$RgXF1b6rZYIhpReCkPRxG>VPVWI$iGjwZ5tnuQUHR=P|^X_!YdXHg^@DgLhmXp^x-v0x87MW zsjZ+~!o~GIlCAgQbiEJ18tW}2BDWogXYr&%>wVI%_X)S&w#EdDXuYkXChOL_IgRTa z@s(hiWWAf%4VGT-BKVeF?*ed_Uhm(?*8A{M>#d__G95IFp~Gz6=3YwHyf6Z-d7&TE zCbN?PN$92#vU9E*A$vd$oD8t4S@e7ofoVA5Jn4oLZrKK1>2L{KK^Ph1o6mqI&! zCoVA1!~xpWk&CC*)bU(Xzg^bU{8CLliJR&&2sGC}Mm z)lHrAO?^jAeInP?(`8NVReWz1iau$alsN8?re4UQ=pU4!=)QrbB8lesmaiF-rBk zUiXB4(C%*v4~E<8fl>T3V(H!gwbnDyu5dxHl~<37O8UQt*3c zl@b$t(TiRbdKHbrL`9>}DbRZJi`kpcIU$Y0XS2d1Y2oLy!b54{r?bNOwD1?R!l%>1 zr?SF1D`dOS0KQkJF9fkI8W^y3*G(|1gRj$l(`Fm-SqnhrK=YkuWN*ad--qNlhOH*k zMCx~nYwQT_qntzvE$MZ9v+w=VhnqSMj!L9`fsjpUoqD@zYVzanM|V+zD+ZBD5!OBD z7@s9jY&PDqGcYu^ruAMXU1BZ?F{((stn>Lq6D^^+>F#M{C=~U+wo#d!=-eH)iW)A~ zoGwtNGD!6DLI4DWIonG2F z-Md~7rlM;j?lC~hV#+J)`)i}Mi~UG1O<>{G1MwwLfS)}x_`2M1?u-_hsEp?|EdJVs z&PI*tUV}MJ$n2`Bh!|^OyOE2%t}FJs;bX5!(lF~}6TL+UHhuyhd(BDdAnKX-#l>EC zq)%*8zc=&?{Z3()B=*{Oz0pNq*Q0Cc_qq$~*J8e}r{5&z+wyeHsNdU){cfgTTspqr zDfPRCnOsA^n=Y*14Vv%k=y!v+Z?D&UyXyCvV!r@G_HFe`c)4(&Uaz88tm=w2&p}yo zTRD`8EMG7CHrX+v^@)9ZMA@{V9qp(z6bI>gLQ0&z|_XHjW%is z5Nm-*6JX#ks9yje_+mGw`em{ramjSFmV}uKz9*oesbnopEcPH~)aj8o!+bQ22PT?P zEh5EB_k%T;#IIscC=>LmSW3Hl$Aw!Bsu~0S1&hGatrx5wOTYfj5b%r26Qh_!*zlwM z8o6=yKJmkmyZ*iR3$=r|wjuSG~5-{ZVAXB zrA?0vh7|Ujk}AR8Q6Vu_W7~CkhAUow?zAm4KveEEZO^5Fhg<_-F~$86KRjdaNdr8a zQExNh{k{R1gBKoX;Rjs{WXdt7QTI)db0-@E5Ai7L&ky(}P9q`KV*bV_gYIvQZnW_P zG1d->`P+S}2@MA^HVf#OZlscFs{Bx4-y~?}it3v7g8Q3Whr6TD=dgsA zf}ES#d~`q-Otqc5?1jK)CM400mdJ5rdDMUs=t+4@2E_vg<(4-;C^sZ*Aq?qD8WNdO z;?p)y{-)EX@CcGJlgHM{!5SIe?KcKa%|4NE z$|g7FXD_Bv_MFKlda-ntoXA`D_DGrzyX+}#fn)-tIO{S^@iHi_mnEU5P;Z~D)k4uw zjY$UG`2^1ved^JT(7}gI)5_oCt8#%0tuf)9GkB9j4QfSj9|xW4yKt>epLM z|5j6PHF>Kc)lw-+@vEYRXs$3q`ILC(0AZIIy(#8wzwU6q?snDh=OX=jN8sy_&zh>i z>)015oN<>sq9%o~DqVuB+^@(k$g#XBh1)9J>7Gd`>he8@rpQ())0)gE4!YlHY?P@! zD|o?F#OChe?8N8#W5O-X2=P@YBR^@-S88*l0OeS4Ur{< z(U8^~dCXF4M0m2R^y~cCD-4G6O!Fe2my!;<(`%*jn>B|4l zb%sh@Zt45nt>rC(x4lq}^=gube%lhl>7Zk;A)!eBq8cJKncp@u0yi2YE5s}J)ZT!= z?2SE>jb=TlA=((QU>FpOZ-B7~HH?z9*nVD?N{)v%FGL?|Z02PyjGPp;)h{DAj>6;t zly0`N@5Gx)zuS~qCvH8YJUon=Gy}1in!pN_r26=YY~ADE%$_vkpa0B%K3-FP@n$^! z-e`2z+V%5L+nx6!6KiywTig?O9#N7z7o?z7u}MXOhV61kG~#Gj7iidiMRtLPc||mAZ{F#ijX}IJm`zZMg2-xj-wy%P>||OR z*Sd~^M|KyINo#inqI0fv7G>26|1=F%Ts`$?dLM79C@+5#!}w(eDZafoNIzXS;}sSmj+F`R&EXl&A=ss@MU%} zZGiDS{wV&W$ak&_f`#K~bnK_B3HSJE^L9HD9LYN1+Wu;z)&#uzXDm^FNQJkD2s8!` z-wNYn-}rL{?#9n^)nhhmdyF07F)RZi|3(PmY{cLA^CO#-JJf23Er$fL^({dwI)DYV zA&~lUaaX+*dYD@Zt5vcTl>59Yc4v82RF$YCw~A4+Xtsp<_QnWb7SXuSn{2+Uoz0j; zLm`OH6H<551ec+a!bn*76ltIABEHc3z>rNQJ~;_}?PQ+n6uf+-)f z(JCwDQl+wHNH7SeVrvXqN!h_P28C9{IMe~l{D7G`Z2aKEl<`vly+hq1YH;8n6Sy-1e?o4dT-%ROWCl zLFzQ&49{J{8RU_+6ZkbL_1vBbB1(N`nx$TRv0j12Q;#@rQ5b*v%fIsFKxq6cy3w!< zk9ooH7^L7|)9{!VZU&E)53=FveLvi|5l<=Ce-AU6q8_IR&t%;Ou~`(H!x7shQyg&* z4MzqUi+_#nOsyJz!apkTbIRc-m!ZBL#;5q{xs}JygsJH#_~}$;_Q(MS`0_9<=SQaP z94<}mLBturwG^dDI?DGnUIt42>ov8Gw7+HulBL0Cpq5_;?pRosK%%4lus;eqlN^SK z+>#3CYJ*r(*~v&Fm?R97AlR%4p2-%@pRR9$l|jFD4cy=w0Ou8Nn=}A^WDW2P0??mL zYJi%MgkwJtDH1!9U&NAXvn-ec5>7XRjqX?K8@17eMUxBFLh*h?`;OETprtt=LogoQVN7*v*Q?cc ziL1qXiB7C{?^DB0injTTbgu zVZ$519vKWkf1%lCoFNX&xXU4#i0ow|Srmd|_$s_n%P`GmDT6mR`qtNo371TiRfG~W z(NUg`YiAcbAftepJMud_>4#EoJRawEc5MdsdR;9W8&;=6QZ_fD_=KdEGpfR<)!i>m z)}(XNu$!IiLC~13&n&y|bfo-XAMJt13S;Os4Dlch_(~!Thqj%nk1~Ufae_LN41{Ix zbOX}5^9>CxJl?3HY5rH05MT?5O^mx4$7(&0gl z=l=Ncluk4RYFtzRf|*5c6ZV{Ec?c8rH84iy^^ei`j}IT{Ah(Tjf^5_plGrv%>*+U| zSi=s@Dejk2MlVHAzwIqPuqJkfrtiMdB$dC`eS%Rb-xzSe2LW zpl1CNIK?aI4}+c3bxIhZibzcl8m_88G!haqm9@r~$aAgnYoN6|wqaFJYgDOfjgN$6 z&D}lF9KX`$FiFsk9k|n&)TnA!wQBC^WXd{(m>Z>jrtNCd?-V0Zi>g)LqStlW?n`lH zjLAH}P=-Fq$R)KRO5Zh9(1M4Yf7esJlvopmG-6#zcsFWPrb>Z&rrZS*{GB={WJ83u z^H2>TsnhMP7rq{%0<$P;Cvg0~DIura_xQm&pRHU<*bD?jhA<>-3Nhf_Hc@fodit%E#U>ao ziEDql*2iTbXGNla1wlfJKSyZnQ{>^a4Yp(m`oe*aF@f5X zs47Xq8&GhH52MDfMZtfsSdWqT&%O}c76dzM8p+-bJ8SE>zIcg;^1~WR3Y#w!Ve@}o z+5y!(Y)+KG=GY}3N(LJl{GZ&AqRogyo4p%mI3E%YVa-G>K^pTMt{7*W3|IDgv-`BD z*&!9Gl3|>3H6|Db!4eLs!%&d?Uv;od!FIb9!jSuZRXslTm-gkOrn^BcbVpi2S~1l| z{LEkJImJ39)3eOAWqVU2KJwSrki>U0_aV+OFaXn8LOz7TF>}CQ_yU3E<~=a-`Oy1F zJb%s_HQv4n*$fg_qoOIZD}=jwB!a%K54*h5;-HG+vWy9w`kr zXh39?w7pp(lq{zSEEz0Tc4ns?N&A*w;uS_^8-eqE)SR3*qZg-sG($ZdId;`0ZYi}G?}<0CY-ifF9F$% zG`%3)Ro@kfiO1twi9m1(y!I5z56X(@RZTtU{uCa4!~uxI4Ij-_gF&QD-~=IQ&`3eL z7)IrmrA8~^J3v1t3)NT9zm2-am}%K?2Bfutq=Nu&Gzjgcj?NrfYs8NHv>?eK++uN* z+*h%>S}Y?4Ax64bR=Jh~y;>=6ezANv8c{Mjjb4it@Xvtbz~5%0d}UVc z!6RYT5f#EZmAgzfH=ial^V?Wg>g{oJn)^GngFC<3JdKOc48?INWDov#FI z_fGU`Q_xSmwtKwezL*~DE_`wxjrW5S+5?E9`f4k#cb|m(-$zRt1>ciaKt{V?UzB2! z8sI}Gm-EK39UfVaQuYcbl>bR5SHMOYU?k%6%HS{L6YBFHaL@L}_AlRMcK&$pbcJo) zm=FvLg=I^y29>#GO9@v%QUdH7qw--4fq z@yXV#c=h5KA(NacrsUj4$=jz}sdgC4y=MFt(u%^H>L**<>t{DcAzLH&5>exGYgOs& z#@X&yM_l5cQmx~b;IB72sT}e8>_)S|g|`IX&?$5chvN45(>thH>w zr_%vD3qfE5PHX_lfKQeU_@oWEQfXmi*>F!TIb4nX{94&DKeUcLab!_?{)5wTQ<@0R z&hgBkboHH?>Vjq|ao6jQR2zWIz9gh?yGadiCU$4a@%p?xp zp}FYQfw|x-Kn0DrN;_sVIId+l#G&TBALf5fHlNtYC>K84kmMT7a6kXqhIF4G;{JfY zpW=SMzwdHC=kM8Z;=TT!txX!$E#MVf*~OFziWxFAO{XYwmrIVQ=&p_Sxkz>^HNe{cH}ys+hJ( zdX8I*SAQeN`b0xTUVS)4OR;%qyp&fjl%eIqa%lOPZ0rjwN6VC7Ovlnb23VhX!*u)~ zZ)ZpKoUgzw*bG+IZzR6*3Nk)6cjM2!8a}9zaF_TR@v8c|uXbkJ@w2%-(C`66jDTzu zvy)*E%KFy5-+dsZB(~2?Lu_hJ5HLPz%#(QBKN#)T2nuEGV9UtL??8Ff*EVpD!i+fs zsl#pwENz3(aJ?#?$Nu1bAW~h`lB670`Y>$Tmny#$ z-3oahMxkW)GUO%hMaANp4`ZXD*tn*GC-a+M2BqTW=P+P^F_odf%7g@=fQdPmWbb=f zd`TNovh%$#%$LrHFMTn`myYH5(qfJ;9m(;f!#TdR;O~d{(hJ6ys&If6{IiU*Ur4x; zR#xS*;;@>oJP|99F{SQHX#*YNC)W{}ZUTjjBS<|w+e1#FM>scWL=-pPuaEWdV{RP@ z+q#>p1~b?+1(1ChK#6N_)8pP5Z{N?(+K#Uw0jcM(m(&T|&=D)R8GXj9+Nw zYKN!vHoP($1y%dC?&fM?z>UL3k}_Ed)Jz=V=R~;2CQk`x0mJw9M-@};ri__Kp??Id z$Ma+Fo$dbp9<~`pYufaWAYHedSbc)qFkWONqB21bam7hxh}1_AsgE&kiPT4&NR5An z3ddR!sjJ|}qWyj*J0Ekwu@pX=6&^_hYCy*(!l5GxsXqu~YcBE;_q>eyF8Wiit~8@k z*nx^12YOc`p{}gsNFikSg2*z#^f(pQ>i#3*qsP1dkj^;&#u9tkbqLl?g4uy`(-6x; zS)iMVMTx9FY|9_`lD+tjM9h76D(1e+Nx7O4_3qFgJM@*vxE>HGzv?%qt!)i61;uog z@ZsP93o=`mgzp@cU@Bs*126L)(!w5*L^8+!$h?OMu!=wTX(v@|<^KQh_mY2q$=^rZ z|AN1lbn-EOFX`l8`g=(yANKd23)~6fIg~AfAj9HQVBI-_7?;4Q&u8d!C_x`1jvPMo zS!F@A6qD!6FnNACO#XD%>-=(7AQ{T|sfIZ|tMIst}Wzulvh|N8B5OL7n22UlD*`mR+uEnsOY za2!VqQZHXET1d3L1elOVrLvb&10Uj&Ayi~x%p~6Tjmh|D7i%1QxHbMa)A1TEUpdTI z!n?N`BXr@Ccs{#dNZFo0%?9Tkm(>xNY+74`dpX&v)UY7F1qSpE}{n%F~gd9G@K?*>^Hf8F5FQg&}AVy&1(OZ302&=ScwokAkY3^M6C@vP4Y zD?F3lCno)0JafI3`xpJanDig{dok&+_F52u*6=s|y=T(fmSfU$#-x{E z(NAUgHJ7kx$#5!v*ocoNOpy1aAtdhpA!F(OpIUs|72`kp%OGC&GAOZfU>O~{K9qVf z*Kr<`(q-VybgO)Ncohz46+ZSWZmZNP?DzLtg*kt(RoLtAwF>8c*}bn-IP34V3TOQN zN>}0O*~G-dDTLN-OI|;V4)|cVRzP$l1N!3sxg$c zIT^ZsM&?Qw;YrqG3qqPan{>H%o&KI*>!f{EQ!Zdh{ig|VWD1ICWn(n?w<#7d61Cw% zpu0mkqe9mb8=n}gwbz%2Rg!hHz-)7p_4t&u4m6w}eJcSeVU5 zNi1?aV>3(r>p8|P&hXznH`v1cxg5tho8uT~avbBdzZb_i>F>ocPWXGzG2SxFw~52d zfXJXWn`~`y7Nv5^Ex~OmLT%0=luggDXYab4w1R7zK(PT~WfO5t1&P4xsBU2g6jR1D zwT!58Lpq`%zE{p{kZG<%c0>1`gldC0{VK%?iX3;y#ufol>5X2~R+h%k z)zirE(g;Cj7+A2cQho?351C`v15A0V*f(=vA$<+jY6#FWKZe=_yKd`4%8TlX3kwM! z>@}TCp979!z8x{UQq-UMp7N9|ksHTJkI9PTB4~fSO4FE`0#t#3+O4jXZ!rhZ~`vexDsJ>XaaQj)5 z)suMu-z_E%~eu~o8T8A#duYjK=*)E&6Ba~TRtcG2T(QKQ6-8=o>I zNgFFoLU1JQ=wqlLFA6{Pl0TMVQOMogsZYF9KH9|mRN_GBdZ}uPl;N zvD4kphbGo$k@%V(T#?G!2Ndkzt3izzgz%Cf;j4&XPGoj2mgO9>(ogVTun{A)z)46g z5zE~nD{Ir5Hu|NOG#{B8FWJc4c*6obG+vHb`SI#d?!b8I*v8vF(5Q{P z-18_#+Uzj&rCb%Ts13={R?CGn68|o#fr9Leic&of9Z!+cy}_Mr6{BF8)tZqyG*^94 zMY47A7&OZuhd(Ssq6U|`)PCY>yFa(=*;cmm@?+3Vcea&7Ac&SSKh});ZJacn?gA7z z30|iYA^aM24^ws1FX@E8m09S%bhzCH+JLge*%;R+wmVf$}~7@ADOXw zR9?ED`~BztaOAyx5)phLs{Mrj$@{MSCumqGK1xtzn`UW(2BW$XhS6itNa}Mm_5)Ep zt7hqq(sXjw*d=VMb@C82;`&3vLnmB>fSrwMvL4m~JUyU%7z>Y6{x#K=ZU=}|Dro7R+F|^+D`k(M7Z{e@SnJ@#>+EQB_|aFDMhTkfYL>h zibEGA0gOdt{d#Q2570-16ac;6{dxJugireTBk2$xQmIc%5REBw(O6vH4e1%{=zJy$ zZVtOY_b>YE?+b#x-~aa_U4!69)Y$r8X2oOVISvn4o+>4a82jJ^x_O zV_d`C)54Dt2GB;*Myw+r9ZDuW;vAs-v!aHK6LGv>p9mCL_3PjR-xq`!NOIg;<3KZ7 zb&8O=37Oi4fx^F$>Au2P#I%qk_%+!JfzTL{x}LX;iMQ}evl4tJHPp!*1HhP;BRfEp z@D{dGy>GllC+R$Ik*tgYTE$yh7spFl#sD&w<2j3brJl2NJ!g@oL;gZI3wLmqiKRHp zT0nwNM`)=;T`Yi_0pMY@_E9@B#+`8$F7NAs4Pi6^SJ9EDjH`@9L|9u6cuWoocXwO` z7B8MM39v}}EzT}>;*+cMP|O4XIMyPF^+&{000Li^gXcKZph?oho3B3OCh+liO3E5) zTNDT#kqJym)xH)AO{J?LK`JLqCp{NHt~W3JaR**g39N!Y*iRCd0ttUmcXW3&>JP(? z>M-o+W^^D>s{60&h$sRCFY`s24U`f(gBdnat~i+A2zSL&!dRvb^ZQJn^lgxAe|^;a z%+o(StxsjKpijg=)vX|LhTPP5zh6Hedw(C=jW$H?;5u4WG}!NhnbgHh#x8`J;M6i^GN!fl%!Gl)k&Rx=q?s_2ru8Z>m_~-A;h9N8 z%tR*Gr2%VfQ1MX0hsL8qAd(F}+M5vd3$rO`xnIKX-h@z5)Ih35wovmx+1Xqc$e%!n zh<O3eNwp`|E;S~U6~bAqXL!bUrmF0TokvzCOt-$ z-~juO@?ow~$|RV)jYJzxTgR^39@E;wv^JQg4b{ud0 zLerrAE`(P>$jS7KUik+QBDixfNb=S26(+g`>Z$UssXFr=dp=y+#P9Ya9NTvdYG=_q zDKG(mU<>IcxhSw`?4h!7GHq5)?Sd+*}Sun2)` zI5{L-7*hYun;9jlX{5nQZwO4Y(_octVtr(3oEqANMi=qZV(z*PUjzu%bQj+6+<`mK z9bkF(!_BSxCmpSLQlg3v5~*hMh7&b)U}&SAA=wrlx!IXr4s#W2IOKmn3^T_zmNOh&*}HkYlz?EdYG#| z)^LognW^{!QFB*)SFHF%R;nAd_QabXi6-6&m~@1xw}rQlPtNw<#PvC@w{ktgbtBh9 zTzgy>xW1X|8LoY<`+Kv!ySN_g&h}of-&}WaJ+fxDx0CCkwX?l9aGmF>B(BGJ{#LH| zWqNPZb=_?5My@Bg;sS|Jte@?X0XBZ=^|L+Fe8i_X-@JzFX@1|M=ln(?iRbtob3MoV z_v*TNw)YmUr>>gqUCs3b*ZWk?`}eE->e=2kD(CukmGk@ot_QBM_|<7{4>FY*uBZF6 z{*w=Ina{FBd{gLV<*B^;k?1z@S~u%Aa@~i;P9Ff-%T=>nXgetU|LnaBket_b-`TI} z$MifJ#B1;%`E>&%2P7y`5lzYz6XQ$FS47LHN~-Lw+TFO~q~gVpi6v9D+Df)KSs@W@ zVr|&sijxSk#wJX{A|=BjEy5;k%|=XwwHXUG=^_-ct9j(jTkuNHTjLbAH6P7e^U=Ho56xTiO3zzx)4VlL&D-G1rzR(C3r>FC zA~4Ncpp52yrJMH=oA**Q?<P`7d&}m z4-9vLR$kac{+Xq%_8!WTiRUU!XqW_z9Vxb}bK8O{noEUjd?;9!bSJ10k%?q-Z@5Q< z9CyE6)!U7^xuAhsMVqK-tpX#K}{#E^4WUpruOt4%j-r&HnFK322RDL zwkva70m6_LH!ChR{^{dXf-!%#$nhKG&t^cT(u<-`tHF`b zcBi@`xm|<83H3mS4Qe}xg#G4cD&f`^@@&5J{8lcmVtilU+EsUDYgG5^e_U1&t?C}% z8i0MSk?XGeOkDTy^KspySG8W@5Ca+ziV=Tt;<`{<8*3D5OZIrns^dd#t5X)jl5>p7 zO)(C&1?(a{rd$(VH+#IYK>@9XnnKf{u}5JNLMX!hjt2~L(8Aqj&6VOE>uPc>Md}*F zvCz5!^6(iiElsmWytvmdMT%Q20C67m3 zYjhp0v{kGz|CUym+p=h7t$tmBxnb*yO|XH$O_(V}m4T(*w-OwdJ#WsrEu^nRHJPUm)S#t-J%ffr!jv>j>`cCbvm| zE^FtZ??$YW-3p{7Hmtwr_q2WvsKljGoCS>TQmM}z%eGRzy4j+U zjQF8Cm%y6x7vPK9NwhJ)>V=bgqAQ``Wc7vCwRCTO4n2Hfj|{XV61K&A_Zh3rKGMaXmRR!>*wvbMy^ba?=*#me?*oFxg@z&{>NfLVx?Nh=QcTsbbixa zvYtAnj~*mJYz3fcsTBsRYv%jkKv^2rLC!vk5V&HAmgA`% zO=PUU<`@**Uibm#_#&YR7T-pRzu34bZ#TS7sV;Hx{w+S5adg|?5tfN&^C4~6aS8?j z+G#yj90-9Qh#_!aYO+10N(AO7h6sa_xb4SL5|;?|P|`gbpi$C3M@jn@x(La^2j$5| zD1EZXjH#rCgA(7rdj0;^-T_Gaa6IIFsUi22x}AgM61t*3reJM!2`Na4MSZTiP`*6M zfa$d;Dc7WnNzbX+Ywf2_h` zZd1U|aTRH(QSjQgH+CuP=P|fD<=!jd+GN@4)TsprQmqwVNCS^`Yw<^7E#7PV*1$Qk zxlFqT=$ULgrs1B`CQy$wjw`yyafKg8AKjnh9`4dO_*}Q{-xr$d*WVgvW6)aI{4+E{28Fh8^ z<@2_|8`dPnQG9xU#K+3!`SiTw)AJdD4+~4|`xC)N(-Z>U+i3iK&b`N-%&^zp`ZFIZ z3Lpfu)1)^UINoBc{r&;#WLM1Eqmvs0Dt{oZJfGr(Jxypq^;Bd`NJuf7FaJc*(!n&^Pu#vD=fM1V%s!xGe^ZHc>00qahla z8i#Mwpt~@KFWRxF;PjqEVrhXL#cI_z8H8^VD`nshBlI z+N;tQ-gMs;<{sO%pZ7OTqE;7`$b*4kfUHabLO*;cBsSKyys?e|8qt$8*A)iw^4KWn zCad<@RhvQ1=?duJMj&f2$eF=#M1vf={I_n9+q4F0BFc!QiTggHQ2t~)Cew>SiY2Jr zuQFF2!&E%^Y#j@9B|KMG?3g)&q?FFK?r6&ijbX&>n>xWNEAHZiTa`w@R%^Q7!fCeV zZP$a91gZ?CT??4GMX{KBXsFDW{(J33Pp5Mco&MKCLee>Osvcy5j>yy*R;~yat9LOE z%^pfvq{^PH zFA%q~VS#<2DxAk`q|XbRfgAuNMuheNpmNfm->g76dyaXjrugB~#|a7KutVMUNfnD6 zp4!q3zr+8C`3Q?2@91WfdeG!ZLp6Mp;u=R9>X`geue^V1E48o?vH?SIGUnB_Oa(D;bL0Qjmcw8K(_BenuE-s;j$nOyMC!7Gj$X2~q0t1MU^47l?v_=19F3yi5X2g_}fkp zGCZrPJFK-nDi$cTQWvwFrp@dA;jzAhnS!OWR{D#Je4}A?U!yp;1-7gAJwJAQxJs`> zjUE>TO1D?NpzOuQUM~9j}wKguo)$*(+_(;o<||Pfjx=9bfP7Oqm_zKoOE7$bfs_I2T>i z)lU3STtcJ+Qr>HZXk^R~n|sX=-_l<8ECQ~_4l(WR5N8c`kgPtrD%BrCJkMG-GkD4r zflcQj11-(T98qP)Ov7d9H$~A8HP^~>Mn?B;GtX)I#OGmlo)8ugo~Ge%PE41~^9}Q! z#5QvC{b{SwVmq=LaV#R;-o=1CRldE8ferJdwKmXd@=}6C?xB~q0A};VPe0i}_1BU% zPRDIz_I|920d0IMY2&Q5VFHI7T1okU@d1e9kLlFmpwW22>1<)DnduYaRZc7;I0$&K zd1%Gx#`X^bb zyuOCP%u8>F73nD^7A;oHYPn{lXPJ$eYr_lD{%j*=vd;i{Zd1g(WS=!q(%|vpU_+AH zlv7XjQ{3OW>M|vXIgOyVK8rQ!7QY>q^HF2ry>D;ow&Lh+CUX_{T9anpk~Im_)og4{ z!hYm5ff1})`P*_#P^&kC@KU0<+IKPTQLITh`>O$~K95OgW#(*`*3p{Oh^u5s#-V~Kgt-&yN_t_|Ru-0w#bOzw*j)RN_r|r5_r?@?+xHR4 zyC1!(yhpr5O3MJl)v-i^EPDyE+#^BI*kD>&-FZo`I^z|0CYkU#%&Wc1v$JmFY7%Fb z!6D*iL+w|eO{C7@Na_q&$WJEKm!s-h$eCtTn5oRDuw(rMbBYaF2lWF>)=%j(GG!eo zI@`nELS)M#$Yf9HKvBjlzRs5p=`gC3A&NgC1=3J+)=wovKad`}$~{h9x!OPDO;(3t#)E#!9b%H8-;wMmU1|lnu_-^38A1P>}R&~WC!YQo8#03eGy1TGT^g zYKdZ4WdzZJc$3*Gss0d_DD=w zDa#;9=^&oSqrnD-hfDDyTZ}G96eVQJF{#8R2F1+;&DEJ0CWo6ClsHJcBTFFUOt;Qd zPzkomR4_TvTXK*X18*u=wBz8+e!}b8DA0BnxosZL%tU4ao)0z?JPiN#QFV)!lE`n~ zGUYBN3xt8uv*oc;_kv6UY=|5DJ=k%9EtIgrn*zVbJh!gKsCpIF}wq zrrhu^d&U&3im*v+t_%e4cRiP(sa9XxalM?=eCY<4^H#p?qY z984fG1tw7e^>`mwe`oFEeiHwBBaRB-NWr^wA9rRZpB2TC^>1Mxw|Oo5I8)|~nJT(} zbj5BJ`#3F{LA+QZi>37{T-YtJLTFr>;V5`YO2VJQcb&~^8O?ZUDFbEi#mnj!C$oj<{Q z4_KHm?jomJxVE$_5YKB@`fP7cswKC*UGXig&{Dtct$NY$kmZYb+Q5VDuoQmxcLzY_ zw-R}{63N2>)qg*!ek!UifMuFdVWu*M{tNM?LARBUOU&1AFFdDDHoqqvD0nm4+Tuyu zLp5z}`8r=Zp-4WrwdHqsoQ!|(*4CBNo{XF(?u8P>hKYK@J)05j zUeNKG6zwXp)Va;h_FxPkh300UV?-^VQ>wj%CBkj+7Ha$HDt=?yeaN-DiQ+d3Fm#a( zQ{}hyQFn{NemN8SA@7(Jhn0aC&QUhQ0@=0K(BY#^oR^#Cao-+f~_ z%XoH%XQ5uLYKs>heI>dw#Lg&2tNM(^$!G%w0M&<_Vx-9XP|@BeDaY%9TU7W|OjuZ> ztsk$o?i#>1UJqiv;d(IG?4_}u@>Hj=^Z%eRf8!^MzIRgKM!gdsye_>5TLNuRuWLPC z{qC}+?0yDUQqZ~YyUV9H1owS!!T;}v#XN%h!jr!|c|*Cdtf!(=n2w(E;+{W9= z%VoDlmdniz@0<Z_(GoY_2Jvb7N= z``J=F*~5{sOOuVTiv#Cpi8c)EuPMDyNAP`LiKrknOojptXYw$uJ=k}F+2iW~X5Sjz z$&kSQkqGvEtE=zUkOqIL63_2wS}ppiq@x4Y5td|yRRaGENK}{^m=z|CKVpp|E_@>y zB2xX#V2t`@IRxGpyqiI+OjdUyXKPdaqxltibv|}8oJ+eI`oCmH2d<+7IeqODkC-4h zz=@z>#$i?101c_484VBFeQZyRt))GF=?xf~^FC#qAy{lww@ss$8d-uLLvJrW_Vbq@=fMqV{<4IC}1pETuSlWjbS z-ukNPtuTeCe$te4{8;@hN&8y_t-zFHJ<6!So~V3?at6*k_O2X+DtlTPYg7K5vorF* ztdBp3j%uJo^o*I<`E$0)pR<*1K{`ARGk7J~KEUc7lFZxdtOXi$F>(jBk79ZU-LrUi z>R7rqk1jrr=YtL3pH7aGAG9Q=(49b?DNh@|kJuUFC6>5F!u2(L6MkfhyN`r(`g=da zcQa%7wp>{0^LU>^F$&)#-AEt9_nSx>8NL^(moj`Gun2PCoC<_9(MMCm4Bwwh;Pa+o z(ZeTG9vQwbxD@|p_+FCB2bp7`fT^f~$ndSYqZz*coaAqQ(OpOnBU5hklEFv2t~h8K z<84mRG~3~UhVN9+v^;r{;hS7wEdTZJ%|!1@`!-?7Kxx((mxsP9t4cRyD2m&Wj&0|0OMJ_{G_XZZdWeAn5j&ar)W zmZL-pp9vzvw>I}YSy>?FI|RjLDD&b2N}L!O61|m zNFELV;%iCu(@}M4Ihkfun5m56`?Zwe`vfzT;hQ^a%<#S9j9$A;kU2FJF;Zy z1PrmlIslQeWLat>@r)`oyd(V1&ysspxolmwtw=?2_GuT1u4J zIiY&r`d+niN*TN$_t4}ev(I|9TYx6jX}?en-&y6p4( zPNT?em@Bx-R=X_Ij-j+u%j^`I%tO z+vE6_w#Qj;(+KwYriXlAT8A;defD`mzD!PK?ei9V{yM>0S*}J@07hY6bzJTA@8#R) zXUrNA+2vq#0Ia_lw34E5xf^LxBA)|Hp^ulJTmk~rP_ z0U7FhdQTbZFKO=vDh3tG^D84eVFFdjA)E>nJALVldN+C!tyZ0CvB3#Jd&^P+YAR=E z2J1`F{An%Hm*TEafTCi9xRB_^^ttK)Uj3TC_m^Y042L(!)Vm#hgUasrqU|cJ7bxgYr_E}84)X|WYY8pq7@3bh%v9%0ZshPYmqnQG*ES@PkoON6^> zvT4`LUJPC-*Gs?=tX|j4mBAIB)$=VqS+dqL*-PVkc??qalU<4;X*JmhyWaJ3bB^o9 zsK8+|6lmC#5w|m@@(s-GE*+YQ)WSC>T|AkAf1-ru>}#eY%aY>|4_QcC|RcSeWYiW!=jpM91QkvPhQF0YSKF_D@AO zP8hg_L%T8ZD~^=jAD%BPus-@C%n2M%ZYiM&HFJ38#=>hG^29xkWG{h?xkp31lgk%O z18_^#2?i$%%xSO^6L!QlqZt^a;pP_b90M8XlKnwV>iqM|>`Xp~lyn#x9e^iZb~45Q zs13EZS|E1?>){}D9fMxBt9{_29LGHCfy=R|XO7WmEzXYE;WI?x48&QU^j!mrk07T= za5kHV;w7ct)rhq!cZ3iBW+bQ$A2EZPHI2>)r3b~sv0n?OKPGw)FBJSa{6jG6zkXiF z?|+hi58YNetYb%yeX#-=696C)f4>8zWn?-8_xi=YX&6}Dk0z}2P{c~L>Q(LqxGNX( zNNH;7%VmdaPG}1<;;lMd@u|II9Im$I5+!8zRVq}Zg=dN0;cA;>tKYi?w)z=|t64j& ze$te;>6oE3$_bSdLe%SUU9#NV{s7$(ojqJ9hbtXL4p-chPIzvY!*zR}!}ZF64%cSZ z)O*lf4i_GD&-y!Do5LKgY&1M}4mQ2{SD^lMZ#f*hVOhUf+@m^N-{MK5Cc*`CjNSH) zBlY&er=-}w$-Nf+9Ilfnr*gPbFYRz8sZQ=mBbplOa82Ow=41*!pXx1-9j-)8M<*bS1_}UfD>$19ynk}m<1>*QbqqS}Up6C)wBmlhf{5tXH_6UNx5rAg_+81roNqa zyP|8D+f|=zrB)^*8)4*j#ejv|b<&?V3Rfmw@N(+N(FvmVhaEZkS~9p3=|QVJ^1NC( z!-!m(bqxjG$m-t558RB`%v%+G7^$A*I8*CNXmo|WPA35rFX>t)umrFCxshB!@ z^wwNZT~^yj&^gxb9IF4@WtXPxu9woKITy^WbmojAGKAuayIh(oT8&GyhkjnlbBV8; z3)7t*>$uZntn@%Oh)%G5HK)hSYdQ4vSX?W8dh97Qs_tbPsVDL2vG909%g z*|CPx|Bk6bj~DZrZZGDwIS0swoT)N5;afgH_H-krhGPw{Mw{{D2!p;V&x;u@TWX@{ z5Lq-|&X6tn;|oiw(BsGqy3df^kaLEN+YG%UlW%DT@4U8`$dQ>u{x3x*BQ)QL6?;eK z-aJR9XdyIYhJp^89nN74a%A#&m?JX*|B(p%eN}JuJ*>fJ6Fv8-w4VED($OL7C^BI4D5#=$}3nLg;)RU6#W!}6XMNo*JhKZkqV#Sfo^ng1-^oZS_LbduP?GAW zqw3l_yp)u?W>lD|jJxGqX?KgFL3PSapK`ZwhzEJVn~}R^i@95-2_;2mLk5BX^6H(_Z9m={>DPXow@?)n$0oA*I;evKh@nCjK0E%hj^yr%sUZ zJ8jRmpF>ZOUFr;P@3a$S=8c0uCRz15gZNh6E%N}q+ugED*vZN8_6~KoOuDqe29GY4 z?)-Y3AX7JDT<*TPfhWlJ81Z6N2=)v;LAE2f%DY=Cw){C!7N4O=PLQ?Z6J+hQHEvXQ z%P8rqGLepMkFpLK-kiI|bh$Xgn}trtG24^D$*+>JqPyZKbox%kBqpXX7dLKt zwJ5?#8-I$}`8@h~TnMI<4968 z&h@V0To%mbIae={ed+O3I)LMkXVL*&Dk8HnI3goLOb+K!#N%a7_O2l^(pC56WM57b z*)!`$WHtszWLywGgvfeV!XKyE?Q1>k_OkeVM~Y9iU^IROy z%(wJ>=WM>0D4sbvK))0v9?U&s&&nAxKr_zq(N0W{YSx2dO=3bD92%kvmyMb9@()bbQjW!a~qYNFXFf$mz znRsT~W<@Dl_%YI*7$jJD&)tcUiL+g|6fI$)>2IKU+b_n5W8O2~OVLO+Ps@5;jFAC0 zgy%2DsJYZnV@=Z%D5hDdv@`c&+@zT1DXxYKZ{Ba$WOGgOhoWGQ!+WxkJqPzVMtsmc ziz9n7G0kN2864BRCzcKeqdQxKv`_bzV~VWzOVd)64s<+(7G>7NO?43%~qHv+Uk;AGxTIBGb1u>$|2dQCX%1sqjOyWc>&8{n422D_xyrfg+z zEppgKHcI61aYYWZ?)pRyA4XR6Mh+j`>h%lvEY>e1N{$bT9A4yw-pJvLTU=uoxAc!3 zKFE6-B%5Y;G4yDW!=Kz5OT~+Ji5lv4-`y2jO;Y{f)|3#u-f9YM&~!J!_~uG8bc;gi)mRNC#FSRg2>_T1?WlS za0Bf84PnPc4s(fjayPVH4U)PWI`3+b5fZh`jewxu#G8W<)IYR)JtBuqwTx7{^8+J? zzbg(r`mUjo!+$*pyCR481>Yk(9~Qjy-O#uA$l=-GmbBe#)VrZ~j$r4@?7acKm`?BA z(3{;ns5_HO7aTs`}!2li30U4sQlNesZQ*ON?Jvn+>?J1#mRw^-Z(j9 zT|Sqpqz%K19awn|5F$2Bc3h&!;kP!km7gj3yMl6O7WA1{p9tIan^$*WQJmmBC)T@) zjNK7_DnGZhv*V*S5t=q-k&V3=`-z;`v@FI3NbO9BhEaAO-&Ak!d2y9^(R<)}X?iz@ z=WKUm<9qPJkl|6ViNiBz4Tv*lg57joh%wyDn0-DvDX>QTeZ=)S)QjFb zs63LsOjN53%~-9-SQ}B9N897CH`L}g(+XP0JB zd7&DYIafMVV>O%$1?`S@vlH2%vrB_dzY&bR>XWi|bBOKn>UWnWxRX@2Q7;w?i$qmvRPjTbb(W=i9cG7-)<+<-J9}H;iK7BjPw^Xgr)v=3?o`)M6 zNMao^+8ZZc^_7-+nK!ykF(8b*>L*&xUT{Jcdc5j?l`T%ntA0nYGvigiHuf^}Ev;=| ztJW@&SN&_P*zj%?YtefvKck@Wsbw?kV6pS*ETDw)ouz-_rBF#^yWRt3JxP#HV2no@X4h+eFa8G~Z|+;JxbKo#RzES_lo9 zp`e3@oy)NXWC_#bAzt-o6YxJ3fxoW~puUGS`1Rzd#q-fkX;M_4NIE)V9i?t6>II4F zX9i}4N#jphwi`-P00Ow9YVNo1v(Sj zv7X*wZ$#GyMfc+{Q{A8g5qBCpI!$7Z7$P_8RKxESKN>W4Fz(hT`chDy!dhwlFRXz9 zuRNB}$5OOp22}raQvG05UC_sS$iU@kVUGs>JNWb#ZY@=U#&m(HTA{MnY$zAzwm_X< zpHl875*pc*<5la1pu$W?1~4ICd@ClOSCtmZQO+OQ31=v$;VEaYr<`r^tJorqZiFMQ zNv!nJ&1si>%b(|R*}zXJF_*Q#6?yAIH=;*G6vv4_SB-}1>1KI$e+Oe#OgBrjR>9x? zq`Lt{Zw_9LZfY^z9E#|sHk58ML;!Av&`kzEgURgolLHK=qO4@ObW`(mQ_IrLTo2u3 zh9Ed(Ix=>IGgz#t?JkGj?VTk->(FZ6frVkZaufguy z3s3s&Y|D^95VUZdG)oUf%7V6u5^-&*2B$a3klt3LoHwGY++F9T3%~Sg^rFD77vZsc z%1g6)aeJ^SdC?3Nx;#rvKraSdYiVwtpmA&Iq(;8?*3t_z!C%qH|8Pbl=j%2ulN)!Lv#Ar$(s$WKw-Os;+^5W2V{OC2JZ4 zQ41zbba09GOt4FAuXA^>YegLK)*bEl3lz-veE~o2(T@`|g5HgVug!FBTj|`ZdLP`; z{+oLA{7i6Lzz=S%m@hpwBQ)Gtcy^|91{;fhGSpu(TKr^{%J#NBWqlRm17y;ey>u$^Xm7eY`?qdcX!Q?_FKLSE=8>NxxV5e&4Ttxgzn#!q#lRQ}ipB9PyFeD6m81$adL;^9x4EVmz6(qr%JzQDJ5s zK=n>%lB(b~G+*JH-^~yq`M(w09~rO?Gwgc+FZLJX?)AHY0j*}NUjtg*%|Ze4Nyty| zkq?$mN`H|?;~uiqym(KKK{YZx1+=HVqP6G51eZy3Z*uyD7s z&S=yX)5*H-O(bB+Sd@F@_u%gSiAyuIclb+{@SD-C ziT|BbL2!jngpZ)K47@e*^T`AsNqGL=g37%$z?BOx1444EQ}w>2s!+PiA-Vfo*KUV; z1}OVs`qsp1c%rdia3kuvDS{&eHWQL-X|nX_+sWSWoZB0!{>GTlUfn2u5+qj@CQY5Y z!XBx9;&y#?lNFlB(ArO$I_H{F{lt&%uTC`IuGLSPI_H{F{Uik8RSQ7~%vo>slcrXA zbz;@oMaLSFdy{m6o6zEdy1vz?gl7JaU~7;QclZ6B+WroAu(WjL%~Yo@1{hTCW1&y0 z{hMm#uKQj;>0BizE$Md z$&v-CNQE=yw(es$^`1qUGC)N5R6r*5?`k*Zlu1KcN~g9LhG#l$HL&~{=)inS8;IpM2L6W4$LwC>EUqx|CXu1!_?GZHp_&s=YdDCTi~ z^lt1;&9D{+elEGTtBEmQtJ)1#u}iOxO3MIwdwVP+U)v6jq@+7rnOjM zX|Ek>t@VT26&`BG{0e<)bu0AP2rCqobJb9bw5U7Z0@OCHAJjIlKhzM~tA<*Vs%`DG zwq^aGHn;vzL$z2n)RIJSYlqsl^@G}u^@kd_8Lb*>Nt(H}Lv82!LG7ybhuV%cKrKmP zw|1yqy?#(@uRqkTS_9OQ6nSfhT4(*BwtM}d)?NeD9*)EB)(*96)(>jed8i%nn#c0$ zG>;=AXdb)Q0JYO`n#r|8ZGQcrcD;w%VGp%ORtL4iBS7uCH9+m?D^YOn+M#yC`aun+ zfbFObc&Hs*9n=n_pmu`uvw8c_>*a$AaZ!cTXuUFll^th@ZPs(D^W-=U;ltRvU)BQi zDsqRIITy_Xwe`00F^;6lLA|uqcEHDI_nQ;#{UU0G*Sn?fGDuv%euTg@I3Vnz7v@VB z_c*h}n|tmx8%b=IDEEa=fLY?=9y3dTy*I#NqxFSizv_+FlbAa&gg}4-#!H~W2lt(n zkw#HGHBgK(rWS635*!6sp!LzMx2jksp<{f-o}{l&@l`|yr96c(NberqO0B7oiyj;y z1^Q|6J#)d7DipwnQ5K$)q}pDpORO(SlkxUjcSa2BCTIJJP8$$(G^?^tNvke=lm zN!u4wZ7-4rCJk=PXRB{}@%k8oY=~nt9O`KsgXZenK9sc0rZR4Osi$pB%&TvEDQTOH zS=_cR)l9<#$NB2pCY^3Xnh2A)ZKd5ww@uj0>f7ezYScEX%-S|{)t$xiL%N2u&?(YK zv0Vy^`dR6e9nF;qu3cz-w%92LMO#9u+a_A65EONIq$JvD4sXR%?!Z=lx>T$@w5t%d z7CNO)aaZNTL2=i_y&u!KT0t`??k;F(-`gou!k2rX)pDm8t&OP#)<29Rp>8a!j za3}a`>ced6IqNJa?JfAl18CC;kNZ^ii;v2-_+W0*82VK9i&sd~N*!F81gcWaseJSB z%6G?=?-*YB@5Yt?&hW~AJFa|>uPjo&OA8I8wsqCfN?gTp8(`Q279-uBx{iNQw`ZcN zdv{M=o0M?VGjtX83^15tsiKtO`V+4cGb%z3XE>`-5GN~m&RP&>E$n7F!=2b{S4rH) z`5M#uP8EwK#1mZlGgVkLG+GpQ{vY`cS;Do`6ZGtqDy-+SIVV{AI=6v$MhlJHKXdM5 z7Y)ERt$~CV;s*AVcFR8kE1WNJe9OOklY4hJ@3NZh-2`H(cW;j0{b2m=huph2H(#GF zPKcqO;_y&DLw8)Y7@j3Pnw>UuOt{GL?Wh1S8s|j@@>MJvRQ>Ia;lESfAyT~$6}P;j zb!G|%iw{Ug>uxRm2veFc?*2p0NrVtIACUNm!%g^|uNGVXvFoi*#Bcp*_AN0`hE|V; zCjKq1$}vu1dxhf_9OInu9b90j=-{}jbcU_<&MWpolZ>S}t_%Z&P0UM&mKsrODK?;X#1&(Z%a z5vUpQaYhERJ^wc59uJOkj@x7hcQWZ@C8rbMLM~%Zc%V=1Ybnrpvr~-lMWIwG!&keX zt|X@5wH-AwoW=bXYt*yal}JS$z{OW3AD&CvK0ZR*PbSruhgC1f)6_B>KFuDUJXrdC zHW|p_VFLl)x<=fCaB*05T+hkzfDy)>aJvx%;XjGT@uR~bvJhAPq2ZN#z-$Ltu;QI>VI$on55!3N-i!#W@h7PRipN>3E1&H}2ldQPj1*|jaO*c+7aULL62OBd}W{#wFKUShGAFVt`2AFnPp z902rb0C<=qFBw4Q0$@=a9hnGqdiLP{RO`#EG^E5nzGUQX?viutwpbxG*9K3KxB$5xg6NC-tr| zIC4*o0dkMV0J+Cwh*lddpRPw^h?X*iFSPzEG#$na~HBW~^FJQDTfnFtgBUxz~INMyhgq zv)yN+uf}85U}rN7CD`09miM8F3y?>P?FlJ_)At6`euUE+;WQ&8OwaM3I*psbUM1Lp zM8?otMY3Nr;CLoP%V&q3K~w>zQwhk?^f#xA421DF{N#cP#-Z>(Eq=2|G+;0djD;GV zQJ4Jj*!ELKZRk}(-e6!fZ()@x zM9=|@whA>!8*E&;9+gk&ZEIwT4}p&crp(5biyAHNFBbtoq1k#r|88b1)AOZGuxdV9 z9hqwZ8K^fX1EWm_zwJ>i8@|0W)hWr|B73}`#WD*J()@MA(rMWmq#4##k$ZN4r_m2+ zC%1*R%>|4<_PpsdaSi6?XfQYHEtI@Y)kOQe#hs$f zMZNLxj;QV(Ru?_Z#i-sA#i+WvHf%Jt39-#zE^Zek)$R>yo@8qx*%~Cf1zrkn`aMQ> z_gt2X3Zm_k*(jv7m8IClpwN814p=rFa3ZAx3I?j&0|blmww7K-shJ4*>+xa$+=INh zjepK2!)FAD@QhXGZ&&s5X|y2JIBS;AxVrSI=!et99DckaRyIY9D*AC8o{5ywqsdF*$(y`h4yEu+ z=x?&3B83MrXGh!fcmYs=sfZV9!AeavStWsTuNPvf0QYaD#GItCv4&#n^F;*mj4?Vf zTXEtRvMAPyLn#4l5Tz`P1GIi-j!YvdmHDtyfe4n|sV7V$J8rXb>L{|Nm-X%Y*3EVFUay!Zq$ zH3w|qY~8h8=U|S`z7JkZE_3w#?-U zg^O-v3Zf>3h8Jl>ZqOn}H*1D$vj&zXF#(h&1p!ppm7eAnL*8APP+}KMmPy z{032VZtK^kV+*`2NT%p0f~eFCAZl8GWik`-(xe-FIX!s9ZanyMH2AU&-tH+Wh^84l z#AJgv3dszftY#qCZX99oHR&_a;5EhtVJsRv@iJ`TOEQ{6;dT3Dao$*Xg~hqjE|iRA zXg4FCQE(qX&+`nvK@nh4Bx8#jiG}URgozjR30YV2VzKp6Kq9eMN{Kxl$6~K! zwg+)q*&Y}+*1JZ#?4YJCr^Z~4pjPnK3lP`?HAG@5JYd`VG}I^-s)3sLt*=0Vl9EPz zx8%(hb^A2PJ=#d&PP^eA$TFhTDqdgIPAJ8G*q@3glBh&4n!`=I8Q2vL9Fxgqlzvi7$;B$0 zo}vVrD{bWfqEF1*>a*s%_6NVjnUOTnn&vGzqWIJDefkoT1F6rNxywwoj{C%it3LU# zK6j=1+%ph=i^4#U zuInq*Eryy(>u*@02_Dy;M0t&e8pV`8HG1R!lgiHKL^-`z+K60j&-}%mWbQ-bt@s93f=O0P{t^NhYXaNj* zaj}l>p!UN0gN)x@!^%K(fv1%RHB$nr5s)Z1Ak|_ZRRyG}{y_5h=>}4S3H4*r*?rRIYA-3!q{eQxF>)SR=MgA~r{Ew{)%$x!v4pE`)OrbY>l~8Pp4q zAZ3ngD800io0WAogmd@r53UGigAI``3x!CRH9`Tb&DOWHQ?~`xu1VH75FW;9YlE z>D&SqhDtb{sIt;VOz*0xiG-jCcXz}}Ld_h4s#xe5sl}iCy)XP;L8|5#^hFbX02)HW ztT8SAL0pxPN7ox|MYU<0nq*=VaS1~z=prtIMiXdM1dZmD*_iU7q4y0MMh^};k{+;B zVTqA6-RdD(WHRw)D&7|SEP#$?8Zg??7+~Bg?4nKK*)2Cw)&@sQ?3{Q73WA*O5b5lG z0NN_Z5;6q?3;1Jq_3ri*B?d+r_71DMiOh5&l3C`=lI%>1|FEFcm#r&t5u+*NFq#`Y zjSwsS+1dKf$m0s!)K-hEI4%dP7>Kn`xjKWx(Y$so)9tvkgnCVNGA^0oi+K`n@{^Qm_n<_*WTFhtb+vxV{6e>t(! z7KVR`wt?#Xj_ERHkmiO?c`)gjuE(1mOTC&*FUJG-b8{Us;MhHPf~M%n?Eq54>%l904h78z=*$nf^eEZ37XI zJU*-oqbvhX3Sm7!GTJJ-Avz$N(LV7_+BVxe7b+-CY(Zj+VBPG6rIfu;?kl;d%u|6Q zz&S~R=`iRQX7S7axm4QnQ1PGQ!CR?7&~o5aJO{0agI2^rg^xpM2SUgJSz8Q01;dZR zxlN!HZ!8oDneMuV`wzB-Q?2)fuN<$06+VCSbCs~xdY|YSf{OMhiHZ+PmAd`D@bL5H zu-JN^%wi$&ZcK>FUEKW%G7l|dB(m}f+1!hr>WXiIM@MC^vo^l|$4MI}OKQWCL?ft4 zc`TEiS~{tO;d)9-FO|AldXeyUYe_pZb~jqX!NmU7zimWKgm1n+)B4mTS2Ms>c#2%x zP$Xbp1XH;;503Q9wHR7GHU_&Q11b53(0uFHEDuZWd*t~jF-37d4OwD=Hu`pxL<O#6z=P_FT}a^*$=aL#Eoyfqk|nrUMQ-fN z&b(C#4`Dm5daZUs&va+ilR_)j=Ew9I-C1S0j_$1bc|CzqoGgI@p-#kM2y7j!wI`g` z)dz%81XVmuKxl|i8@bc$y<{*wO>Itggh}34rm3RzG+|o#Q+vW+$7NIdMSmUFJ8f!7 za@Ijp16ww5yCc!&Q}TFx2Vp76m^x@Gy#)BX{$@U#)yw{7zPA@ksN6%=S(4T?XPw0a z7-8ufy18~dSQvoe336V)sz{kY~s{PqOHpa1+2{@h-lESm~ zVReziOJlHVEMI=SyxwCWG3IDv`O^B2g>;jnjpa|iyzX!ziQ{Nvc^l}3)QF>v<=1~^ z-D#JEgQJb*KdwKHNaHu!SbqO>aXr>i`0!s0ZnvKjmCGseVx+6#L+or|8wb!SQO>aj zgtZ6vxBi-RJaLHUhCq4!NATL845qpDAHlIR;~v4k9Ksvd9|qqTI~E=pI~I=r++eA& z{#bZ=>{wVFI~IQC^W(2YJ>wXtL2$k?&)uYYFTSop@+v2bwgSXdl87M>kD7T);7ar49{erMeK#wW+V zZ~UXN>jy{2t}Fi^W8XLa*4VLdc{{AWW5>e39s9oVkH(ILrLkk-H^#nW`K_^I;lS9j@ZWxV z+`IRu$Bu;yW8XJ^;a`k<=la#L?;HPg?E1k|W8bkH8T-ERrLkjSY3x{ddhGkgXUC3( z17pX+XU4v7d~EDkI5T$rU}fz4#-AEH7EX>G3%@${edC{xT}yjr>{vK8_I=}@jvWij zW5>e38T-ERrLkk-&_FC$eyP0k3?qjpx){Vyjvdm^jUCb#$G$iG)@R1OH~jZw-y6O@ zb{*jO*!AHj$G$gwW$aiuGIlKd+SvDo&y5`m2gidaW8WKoXY5+qiLqnh_s70Be0}U#I68JL{JXL5SY8=B77mXc z3qLt_EPQqBSa@^n`^JCs2jkv1{=Z}2H-2mE`oS|}*Oi|e`@Zq_$Bu>Nv18%a$G&g; z>e#VxXzW;ce(d|kC&!M3i(}Uhe)Z9D#~eL6b}YO+b}ani*!PW}96J`CA3GNQ@3HS2 zzcqGU`PkU8aBA#3mfs&c79JTp7Jho{Soqr5v9S0yVBxN5UDDK>d1gxaG_$vPI#=*3 zgA?soqVTumaqequCPCgqJp-<}R5==O|A*7Lv!R>2rl<2}Kh?j!($!|5MOw`qXj%Kp z;ghL9*}pzXmb3M_E+waZhmAiNys=()Z0K5}c!Ci&7_ea@_aPSo_MOd;q+jbkn|j`C z7_iMI_aSM+b7o_>SIXZQG(M-(R27QINeM^FTBuP8yyG_}JZY26uKyboE@PC{Ri^X# z(!mNB>F{}|LRKk~Typyv8O{I7l-*sJw=V5Aor6BTy6eBz`oNUZYxf;!W#n${&Z$*& zOMd6vZnOD4e>0t4@x_tSEB2+Iye=)tY7PXVq@ylvmnH0S;D_4N;J?c<+zb2-z;71> z4TXczS=9m87Smvy_D>Y683iXas9q~ zN9!qFu#%05yaZ=|D(WiBZut+Sg#FuR|t-M+Wr{F)_o9Q>4EBgW5DTY}!1%SPq)*R%p!|SkM$~O%y}&=i3XvR51uV0w#G7 z-Wg+x#QxcFpH_8+wiL6{Obw$&9Q{^;$6FG%_8mpPH9 zz7RM1WYXxTlBDndG->sVNvlr{Y4wYh?HcD(7081@ewy~~`KV*G2Yr@zKfW&wXvt0X zOElsq`}t&CkHpPr%@3aAFKIM6`Rxb2m7^R=Y1|$&_$TNV% zQ)an8S?o-#NEXz&C(B?p0VKGw6T+`9jth<=Q=?HeoOri@!ojf1CNGD$}b#=0W=HWU?-xP8@(+O+B6fjfD zSRd9&bd`wh)sL$ay+|j|l{%%=Or8O2u9M&Tmz8j*gK%)g?S)%-{m~^O6I?Q)i%9$>BmK7+G#lSBVqfWGLRXBG246Aq9F*fZ-0=~v82Nfq z{rM59e-=v4E?dXovhIQ41+y~rhXSqJSFdm!jrw+PXCH0`sk=4X&Clj);%Jw2fNoe3S6lP2B1CjumXgdu z(n!i_RVrB*2aI=hJFs?!*hb4M@^b{WdO5)1DSph>yB69r*@YUo3JlOK|amlz|mn2wGS(?eE;6)mSUW}Hp63p0J~B`M4VA_|D1 z^(9juxCRQ_1a>zzGhVjx98ost?yJ8zQVFl*?kh;h=t=zkLBNe7rCszxon|C9c<_mU ztG*;wS01f|H@dgbRj{@o#;`3|)uxHy6>bL(n$*n~AR3jwrfPHv!b`CTao^K2q`!`4 zFuJa~uTh+<>S`raUMSkH^G8fd1k=*=A{Ouw+012`K_bYuJ`B#qK@k2~BZoplUb`(TO+d*tZwrdfIjh z6@3N$I^gLq6HWHpSGZ++-N2oNu{Tv2iC`g7Pq0>Bdkv5H=gYQ{wylhs(q(I2*>HEZ zVbQ}@H0h*>t3-3PX48|2Tl&M2R`Af zTIaFVrffZE5L$Ft#~ydj&+t5J54^w*@W#TQl{5Chv-aS147fp$J@5=qLbWE|=1gB^ z58USLUyNhz_Q3OMTQk|##~wHk5=XVAV#dGVX8dvrB3<^tpZE11bM;PAFR=%nwu%2y zImaIOqCI-a!9*;v*CKdQ!&h_NCP4;rNlbz-t9hGMADiGn=q&qL|6CuNAms)<>J7IE zcK0;ECa7Lz6ZE~V-X^#lo9})uG2gu;6NfWTpLA@;tb&iJGiMe2`5_jwpO2e;ENS+S zl4f5{HTw%mvqy(C`wPx2c+{H(Ul)7yX2CO2i*A6A4`@je{6-dTY!>{pWMJpxW^OM$ zF`x~#@Wi^91)ZG7O(AAHbtjx0{{@~YQ;%bVp-|){LxiHeg$#h1X=F1rSh=<%Q0;{? z#fXk3o?{7%^eNw;-&Z11@U6*i;r1>4X*RJJPMBp+Mrh(9yloGXO6+LtcY5q-GF-?s zA^YB-J!dV^pV)di(I!{iL_2p=9O=omcto{Tjfk7#qY-s)Bjam5(;8hoqFAHrz0Om+ zkHpVrI}6*U<61LoU#En%kDWnq7r%qM@$T6Vyn6bH6&aYW5*fpdx3)>^HQ&w=q4cgW z;Mz`M62;5yqN>$>Y5l%knyWFtQs{0Gj(_^wgyY};jGfgMS=Ow&qbu1j-P=xG^W+9g zc(RWLlh-G#x7dY=p3@{C3O<(`gGFIo=GPXxuy7mWA{5_+hnE6*6017 zJ+@8Pgt{EXx=EL1>oT@-+HYsD?3$O`Kzeg3i#lcLG)E%lN;4;oV(!e}jP|!?_P?@I zW>U8qg-(W#*IQ|w^J6v43>Z1mNwc%L#+Vse_ozHebEE3V)FyM->}2Gu=w)ioq?cx4 zcyK9_fYYoMmi80hd1O2xGKCoUsNNne&X3hm#+(JJCVmm87wsRv@n`JLX9h<%!+qtf> zonLhp$@xB}+~07Icjj4g_sZb&fs7qDQ1NwHD=sm;A?-*xP1$gLOy~StFyYSAFymiS zKlp2t9`7tl$+I-dc&=@-8~Jk+NxJsZGEq+x7wbF z&8xqfm{(_GTb_l$&;^m4bC68*Iy=FDG<8+|TmbVuB1%luE)=&vV@K0l<CVgXn-M^rKNL;la{MOTOJPQr<2NIN z} z`AnOIy3mz-=7HYryaQpQQAZwFjBKqWA&;p)?MQT77b@387G+0bmxL^QTWPWwfaE-) z7*IVEx(<#9RL>)c$ZCT8g627tkP|x{i#;tXTZsR*&=WiD95!y*$V+dcF-_fi^w~nDXSwySy=R`a(>(r6~qSvYQc6oCy2Tvo5 zS^*Tgy8wnMrKPKki3Bl8N+)`c)l0)EK*nByL zx?l7k@wf`{k@}~I;b)yC`D`kKfbGMh80xRM=cjp|jiLS#X#xK@V|oAYRs6$Q%li+~ zr5ci^oHD)p@M(sy_VDSyPt%&inxdzl!DcF0{ED0Fiz!%iS>M0x>pku2?ORA$-~X28 z`~x}G_wUt%5BIgcYwtrt-PU(Ta7n_Z@1t>>O&|MvcU))>WgPdj{pCLPcghWF)EjPp z@9t@U{awAv{_cBSz5V@oY%2fd#8m#_*ebm*F_k~9uAGVc%R>y*Uyd7nI%)I=;zsXF z8vT`|(PxG<`YX=<{*1T3|1hh<+uwgMGM!tRhp!B1N4u;W3tvg>@BcU+)ZdR9(IOwT zk+_lP>ybpkZ5M_`OM@D}t@WtcTj&8SbBrwWf{|<1gJ^FdGvQG!^Rmldj*`wEAiW$V z{Z2`9aXCu*a+LJW4MkF=U5=7QXC<|aC3Hz0L^0E`yl57?eK|_{-j7K-##`NdD|6pn zU!S~4*mW|Y+%ooLjGHRVm@p&f!KKW;!QLh1ZHO(Lt214vyf%>$Tfj4?Y}$LUCa*^I z5_&a!TbIOq?b}M5uLaB4THMz|65EWOhXjN1v~P>kAqqkokf=6?e$Yn;IXg0>HKcxq z>W0+Mvz#X}h?mNPaVdQml}qTu@NHcZBJgc_A{fA0GAv}!mL!L{46dF>00Rb-hyTbL z{Xy-hz9;QBDf>L4K6R6MO~TW^R}9M}C*%~UPR>O8l3U!aORkq556C*YR91KL;_|Tr zVK~mF@=iT=0Kt#sQX#xEN~BVECz1L6E+k@^lU8$fCKAedqB&7p|N`G_cwVCi|R*K4z(|ZPHsITSni4JpWy%SG#cu$PNRQieHLhErw1aWsl zYu@;s7IT|?P*rE;<5GlDQ0+``&aJFSm*T=+!iG%NmO@LJXyUd+Hv9#dufw?o%Q968 z|7#(ssz5-iM+gg1eO0pS!CI{=W!6^~a*~x#ILRHZRQ7iYyDA?J3cDt3KUL6vs<6Az zJW?)BJ+!M31`C~{DinQ%qAC=37fSoWM~<=yEp!@T;XX@fJjt+&;immT!NoQf!#W|K z7R{V#!m(y%qOkYGhAbCe5AC%x=_&Zg(81i-_@S7-#BZEcx+lXwWo!; z(!D{+lR-&jP{PGL)w)3`ZPBwHqJfqA{&tmj^jUG#Qx^4<{cEHlYzAdst4jRUgDR;B z$*WNg3%3_4fE?;9h*~RvnvX)Kwg7!C*B@vrZ9y%lvp4|PfzMwolB%|KbAi>v)fNBO zRHsIwI==HkqPNMwKBZ4$R!j^z?0xZ&MHu z*p^yc!#G8rWIoFK7!IL}t-oi9uFLmkX2@G*+U!80q(e6_Yd!{Wn^}WI8qifGoJbZg z2S^s8^^3TuFSM@3SrHzoFLauEyC}+G?Te2rQ8=SQ!GwnD;i=L>>qh`w(bl|PkXAku z6a|xL#V_+3$Fm)c8NB2#(QL`N3d|rx!3Wa-UzvAQkx~)?mPM2mVYK2g8XI7$Q$^88 z4k)x}Dl9YTwFubCt%W{(pmkW3&u|J&5LO6Zgo;Rx0VpBqSL%+YYmgTYI#DKOP@NDp z59doSiUFLeD~Fh+c`k&fX$S&x4ZY?Y0*rdlDO;9kAS4h(tAmI0rPFHY)wm(XUI@>^ zS&I7G`m5Xv0b=)*FVt`2AI~n@GyeJ(3*lk|<`8xKFq~4WvP=U!=u~_)3y6(6=HYy4 zu|bssjnoVd(GZ?kH-krgLl9HQgHF}2Z}ad(4H=~!QbUK+4K2}7HEQTF-;kCp4?0ah zqG|y3L=Ewf8wJ$Rk+>lP#nFa9!Qa+z7Ht{i@rT0Rf_jlBt15&z-rkR!P+ODpeyW0;Bw61})2J|e#P+O4*9b8-VsM?Z&LuOTP{lfumO>2>RHacK*uyl1dnRF-W zn=c)2+{!B00mateh`=|Bg->`B%1vzMm^r z%CvqztQz}4vr~bw(j1zIN{#7kvfow1R zr*`{AVpi5U2SU^c<8viPqO88FU5z~BWaujbkC=n+;s;aKg2C{P3inEPn} z&HuGnM%)_Ggdzz{RFO`}O`#ZWNMuSe+!@OhcmcX2%2PP+bjM=&&(mrq4Z5Dynug;h zftqBqKm*X@=Ku3Q6|WOro!Y+8nGj)3cwsOh@jkJe*+PSwhqy}DmgoQbvqIQp>l2;( z|02e$c~ZX?!xxOtilSHQ3rL>_TCA`OWIdYZF)k0~dYZ%eabsaur@F#o=+ubx(6u#4 zF{MyIJ!Je&Q}(IFUH?8aY>nLFTC6^|xZSfgac_3)_L9#G8+}(F$}V0dySNbZRCRxQ zO9{f1%91~9i>MH;>-0$Fa{XMYV zE+=Z8uG{i=fDNka30fe#o8$6^X}hhY%97@GvYsJviO@izy6_uCn@UwA^xu{$VL;+6 zsf17?oYoFrnc9F<^H`%(H?qP;Mu$flX!uIaVK1KCziuXs6t+RX+zhG zFK+NJhTlA12}?9kS10)Gs;s{IiJCIl?pI*6Ymw)6Wsj?+p%goAtKV=#DWa@57)tot zUoD1H;K(Mn1j4qv<^vSLDc5dLLu*(pCYLEeX4ZjdlD3;&O;@6pqbmqB))i>7tHBOJ z$2F;L_;H|^9M?87euh`9mla6I8lbD++TPXI3)`d4{86@^PU`7S_~AO~@NEv|mZe|U z(r*}!rgsFC?<80BwBWLu1~moVJy^7xL-_U}tt&q@%|F!D{3m?#8iMC50eYWZS}+kZ zjdjNsHV?te0ZW;=YSm#98Y8-h$ls_5#az@vm(6i@$F-nOjl4_R**9 z$NXs zJhT=Qk%s5RQyn4_p?M;z_rgRAuhk$#OETP*YSCb z=kt6%Pjh?tJkIBpe7-QdzkL;-i_QJ*tNA>?VSoF2KF{#Ejn6l>?r#Uu*2LHm+!H(q{xtQCxroqb=z(){~5G*kZ7R zZHJYr!UVcZA8X4jTWCWm(bnSMQ>G0kct`2*oT?^ZSJ4Vc;dxV}6kI^?Qw6P04A^#R z<#S#sIOm=fRKac}Dm_GUNC|76v|izAtfJT{I8L+5z5}3p1PU*lpBv(NQm60dEGSN&XcF4Q8~q zMc6;q#Jt2(&$MJl)QRv#X5L|EeuXJNPDEcJD!8fL4)jG9w)xVjZS7Whp9_kxnv+2b zQUi69DTR(q=ID8XA=q2SOy|+JWcMRDX${*)r{k~F>7ph*)~t>b@?4%LDl+;DruIji zgN4a+Or6tugwi4Lk0uh-y-m~U3&<0RZnJ=D$BU_xBId)O?6=XKOpcvd**T49&|I4C z!oC_>U{K}H-CPgi_=D~(#JYm)!(v%yX_#fpR7KnEJF=VIVVW;j7uwNPC)y_&bZ6F2 zOCqg%Y64i!@^CZNpiu;zcF;S^6ZYV%;s{uJ{XEfHh}qCOP)|LR-QXsR#*#bPh#3x? zY^<_uh$m~&9|$qGOODGt37DUmu^BMmHY3W_71=7AW2I>Kv+K)5;m=(g?vqe*?}mG2 zyW4PU6N7c2cf$?+^JI-I*H}>w%k^9cIi0&SN8&>9Ry0|fo(qZX8Oz-ev0Sa-Iev&p zVxHN{Ok>uQW~TN^%msQl%y!32=`VL0BXO9RQE!i#sc{&`($dWIFq7EoClPbQ-bp-S zZ1S_+Y|?hnhsDa&M*bvVpt+Nn9EDBBEI64&U2JlLW0P~k7~p3U7Ik<87WIzem#boc z89pOLKY)p1&1ti#;GOSm1s?pK2!ce%49sqbj#+N9>=)UvO~TQ%MUf4O75~Oo{k^zV zHpI2-o2CbM>zmV3ELWp%>V-}-t#4|2?CaL7Z*tq0EUl(*YL;iQv)x#D9SfTjVmCm) zALHo({3d;OV`!n6hGjB}5BZqZT$T2!eUW<7j7@d6snj%;ZSaj%P6I6)sW4wUvmw}q zEt-a#ZVIL~N)lZkvF?$z7Z0=slW&?d~-J{2*sYW8ATb$X% zLW@IPa?z?TYTJn(wKIU%WHhY7oGimI23OB;jKS4c#e*}9XK>pYa~jpd zqT3e7VmPKKd@M1PW2s2l6F=@i92V|wa}S5$-mSA5yT!~RPmNAP7?zx=C70c<} zkihZLvs-TM-2E{vX!G`Hxjc_QVt|pM%BI3>Nx5}ppG4ju`;SS%mNy4m?+{N5|oUnXF!)8n_H2xr3h>W$-ZvOJ?BR zu!o>4NeG+4B0sM6GdPTPc4OhuqEkRppg&*_9wsCqWvep#-Xc#zwUG<@kgjrPfaDtv z{zGb8gH2{IEgaaEqzc?+nwhc-==&_yhZB`_Q5TY0xYYo`_-Io9&?xou_C9v{sn2*a zsygy$Q2ji~JE(r1U>{UJD|-jk&J*l?>o*DX(d;5!-W#S}gj*Nm?qfog0U6EJyDqEd z<}*IyJq&nYF;SPX>le%jqT(f=3bJe^-D1q?> zWE+FJk1XSxaj`n>LT>icTGr)b{itVB;mJ(cVy^n2KMQWhL}TSX9t_5OIExKZ;OTOx zq>Vm2dr%XPu0=CO)U8A-a;wwuHweLVVx6{OHwdA&B#~gw+v@gN^lk|NiQGhNuz~Ye z$GM?xj0d&R_9M+a(=T&v4#xAbU#?vS@-BZ4K5buMaT5O(^uWyuGC4vR zQ;Q#nM~?_{0J3hNGq~Ft;W72(j)`r$U zfTelT_Qdv}ZETF)=|K-q!=7>Nc1;G&%A5KhF80{soha7J8F?%HW3{HP0j`0JJj@$0 zWFA2ZcI*rj@)Qu@2H&eU+wn~p2RK62>0Sal#0dF78Z z+VaE8E5A(W6%aN2b2v8X!0jzeN0Tk=>ed}?#zPpkdc&-SwCfN%xTx4l)v_9mewdzg z$8dPJ0)J?@mvP0^;UJJ}G}2UjWYz5x4ck>zyag0F%tH( z!9^Ze2&fA@m<|`KcQFHvT>wz$HXE_5P8|Pm$p&Hla9PuY;!uHE%_f5_$PNHh+MIjP zNG4NG9q$!?@#pO1Y#Kvc-y`|?W5p+NI(a|8Hm7@{X~-Mx zT{oIUY>MlhM7-TgqrupEyz@%-MCnP;8%rsRi;*mnvGp&Rgjpo7blw{CZC`d*vwZVR ze<`6fKL2yF#ayy2X5=No)olEzqOg^Cyk6y|)3k>#FL#*IN7YoV`!7@_mvMnz>g~NNGY-DNRTV zWTkCBXbV*kQBe>-z?|ZxvH0S(Z2}D?LXj#(3Pg!eB|wV>iWDhufTBgprFg4Utx}|D zm3j?YrFtuUfB!M(T6^t%_BqMHUZ4BEPm?E^YtQdF=9puSIp!E+CdH<)+`|KkyxjJT zKLG2!sp!8HCdSh(90bNN1rUsvuNYR& zthTY)xrg06JYc8^(tgfPYe0a9XxXu+RUUgLIO~o{1_R&UXNojC0IR|xL=^2L{Bc*ho!-6X$V+5GK zH#VO4v95H^QHXZHR`2i2G}WlC(kEslywe9 z`zEvdZaZ!VTe`+*3s_bicHr2WnLRwe>f8-wfGGLNdcW`CTo`~rM{cowy*!Qc?4nHH5IB+15O(0fnW-q;# zT)YDF=%Zk>lbKyU_9|F&*gx0C5RhIx{OF@CECJhC0@5(WvEAWo{IbFj5Q9Rb<`jsj zAV2WxOR+tad7q+`4-4!`eh?=^zy@Hc?V>UaSCrUm2e2f7W$yc36<@Andt!qZXf^n{ zH*a=r>hF*P17!>;Gdlrk*`i#)9*!+KbAzD27sKY(pJ*LWgr-Mb10ys6Vj6l0jW9E6yDr1?q-T32fekk@ zEHGQKQO(dbj|J8(us{(-GwSf(9yM48Fxs>QrD66sz%k`!1<$;b2UALEjawwxsXU7G zd<|VKGq;QQu1Z@xHV}4|N(J58Tx(GvPH*-LOs11&&<~+pj)Mn+G^_i8Fzp6m9&p7< zG{_f}$$HOe7Rh*qi`&=?6eatvV+Sf{>B5q%gHMJF0An+tOAUhYA@02A>K20xi^UTZ z@*A`m+MckQl!5u|@M244#bth3(Omjtq7g6Ijsz4fp4pq41SgJ zDE%B(2%YyOp8llMS#31^(Pb!o+62>Np6w*Vp2Dp}6fDWLjlOZrr!_6D#XAl8F_v%3 z8~VyxJp%QTeEcH7Rr5X?YBChiyeHedmUxmc=1v#N#2OaWl1F+4EHY&q(>g!!YHrY> z&_?$n8WqOT9|R7c12OCt*A|3DHWb;|D=!c}pK#tJ6I7@R4Jzg<@Q*cE^3h&P7I)IE zQRm<4abp2y&yDH)oL4~H7*Q?%{GngX3>aF5%uhk+fXVG7F&>{CBk9YSZKNiy4y9}4 z@4o%e5(r&gw8?6b$#XqFr?hwmV`T9xR}<%4QW`u{Tt5e_on`C%mL`5pm{1l}moj{% z-YJDVm}GJwp`}pwW*spzlSOXg^NmFv8-2F*TaxuY+xj9K zy~wu~*|tJ?scrL?WV6qCjJHYA%p5>sX8txt@5 z!pb9J5#}(P#;XTXsWCwWPar)U+?at=hX~B?Yuo)1tN0(V;T|QD(Ns3RsM%~r^*BLm zP{YJ73NW?OV|8h5Ly^;OV|A|TS&Oaw5TQBHU|~bZPet`(OHFs(fM03h7EuLruClYp zZWRwe(p*xmNBmb@8?!XKco|_$)8=0OKa$8R1nske|EX?*@4>`Yesis#<)6typQHRA zTQDAj^}wAZ=|lB3)Jl;I7Zf{fQC*Aq*&;@BkPs4+KMc^85FR01CMb#IvPWw0jL$~h zg)Xt>i=z>lf?cs8G3GH(-y*-3mXWVG@ym?JEg>Qt_-!An@0soUM805SKj|#ZYm0kw zZTqJtmx+3H)c9hmdL-(1LM?MI7+PMWEUEf+h{=d>+`^~kC4&8HG;y#48o-2zotE$n z3}fH(QfB7OhC`z9n|>idP6b(`s>gFjiaSF}dZDiv*b; zxu_#&38RMQ@eD9DT-T-#pFV2yop7BBnZt3nv>4R{4rYGcSizAqr5@Oshi*uCV{LMe zI|R;-BoxdW+Ah^54{8iF`DSelwlG|3fM+0XQJ8|79eM&z1XsWwCmc5*>Of|Urgzk1 z9Di6n#kv9K#l+O4^aKQfo#b>F{VGCX{UnS|GM&f2kWKU=TLBX=vfbUF zf6H}g@)C_ypKM!D*nL^sM{@dLBndrwHf{ONv2>U#`Bger&laH{%h=kE5B77#H;6CS zm8?ex)>WfeS7u-cJ@o4eCceL}mb0$VVix8}_h5+_v5~Vi$GSrQEns7+##c~PbzQ0D z{<>PMEGsDy))iM1VO^QWkP}%^ssZ_<@y3SkBbHUCK)~v<5-QR;A=+cStlDnEpCi$A zyG%Y?2Bx&3DQ##?C2pPX`O`JEJ&-#S7S*Yea{Yk8`;Bcyl_!p-{JZJQUU zge-V)&9p*aTLW8B&pp9|vA2Tt;@sNft(CAVh&$9|=~S7zr2%%fQdUAI=|HgyF4aN- zp|!;QGPT9B$}Ky!hEuBuC0D+T{SWko{TBCUQrBcm@XVJ%NaB5ik4Nfw>l9t-!tNLR{2eh)BW9 z{jF~yUhZn*K$*jgo!fQ*Yi2(?H)P+o*Xk~3dqCSj#8#)JgYG}x5dGTWr{~1FF48f+ zQSybA#bnT(a0tiyYe`IvHCIDS<@L2-2egv3Cc|!}`(#^_W9&h`uVXTYGb&}}FZ0zP zdU30)k6hTfur9Ri%IdMzoCMcWqed-onLzKWio&_8|nI6ioP-Zl5 zR5w-QRDcMK1v~_t4TvLX7v9|Dx+seStbNc{x%ET;?j9Sh6eFL!6#dZ%fYTx3c zS)m=UMAL!EgKg$g=-4R=jPgNO}{yd@NuP8Cf;{- zz>^gIN`x|XMfRdo3#F8>jGvEs@ zsvKNR`p=TZk_<(*V`PU4YpS>AI<`Xz5$up?G6;Vv(OE^+Y5}t|8LqHOQIDaTofCC- zy`mV|Wa!1YT0~5zW{yZkbdUm;Cu-OWt%G7&G@U20;3906fX1>ma%D$pDzb)kr1l&e zO-Kl#iy;%D8Obn+*pYsWt{(3&AJ#3S^=B5}7kbbxdw>8u9OeaROb$Cq00QFt=(*;p zv<*R1=fqF4&j~7#fun$2IB>J~xrStDjb7V!883X0t1b0(q689)IEWo!04%LIK|x!L z#7`Jj(NjAM8>}Y!J!PiVk)2{8e6I~z=s8yhlDO)y()IvjtW7^v?V+hc#X0nX`T{Kd z-a(P_6x*LHMCKk;bSuEhjq9L>FAebQUw9`P&PVj0ebXY8CYsV?&d;A{O5D+yU_KEi zdyhBFgnekSTP+Zc8;LY{)}vq`fF z(&9m;WU?1dbcV%#5=`eC-cP$w0U8l-P2PA|=FIRQ>oZ=W5{L6bE~KT)ANDtdLZcS~P2F#GrO)@hszUO5YAo%%f>ycTVU)0@QiN-E6ELPaI^WuxYbN%Nx% zHZHc*RUABv+{Qh--y*1O2mVG-z#55(>eSUUlZxgZ*9`!gET;BW&sX%vbHdSgIsA+k4FdL%?OPCc1hmj3W5$fTZI(ql3}%*99VD5YCA`F{hqO z$bAR_+fu?~Y<3ehNQ#cT`rm&w`Q`r(#udMW3=h*9mikFnpU&&Aa&5a#+mJk%2uU{3 z2{wtE8^;4#48DUbYBt`RKa(#mn2_kdjAc5ViwZY(O{E`=Cs+D{tQ#tLkjrQMO8Zi1 zj<81RlZCUCEsXmZzguEE{XGek+v>W9Ib!-NE?Fj*_!RtRb81iImt}G> z;)rD$<27__Q}h-t-d%Gh6BDc3OcJ_^Uj`uR;W>a^6S#1vT`Hj_Z`5C>V=9v^(%x*) z1?EA;6wNXq%YVBjBtd1K0kZzUOx`CW8;T z9^%%)Uzk;(UpG&g{+Vf9vQp0sMf8Z+B$8?@;DOYp=&Q-BQQmF|Uj&6J<21m`kYcrr z9w}WKIntFUGSWL$w+7W8>2g2PTTX1G=C@!{&j-}3}FLWoW6BBagjWAS7|?=a9EEwrXE%#`}?5fBwc zsc$6k3&0lurMF4ZN~(3bA+$*!FeCa*HsGlFj{Gj!I?VD74 zb4D|S-&&IHwMzuKW)_@-jeR5dzVrD?5ZjFzHEA>z>y;tatoB)cx1vy^8(L;76YS35~ zFSG!EVvj>%U8}G{9R%3dCuQ6tUd!I*P)VAo=ZFYsr-PbE`e5sm{==MDpBwY{ z`5XP(?=dmfyuHSY@{{JtP!B^|tc4@8Qhi;}XpZrY8dM*}F1I)%orXu{XpKJVb-7{b zlikr6^Gu=+o^1A-eqXt`w5;iY_@MTt@@XdgfArn!*DK7pomkkD>IG9?A7IKwIIM2A z3N+hvOTb{n3-Y0t6&~d9R5UK$QH@Kh3U0FQzXZOiJ z2N#A7`~sWO$$v4fm3u4ZTpaiT>tp5N<6|gC? zzw-pL5Ag%@tS*+#f>x`i4+Dgp+TDusjP=ujOE&%&bU44KUCBdVYszNb0#Q?>XR}LHRYcL8#@sUW%uiT)M!=3tj)Cry55r33w~ zy%sif>wxX@+??q+<2z8@-aEO2UeQF^0Xu9psa~$1nvxP$JJ7NYm~eVl2kK^OqJxwy z?In|Bjk}%vcDpVOKaivA=L8~9JC&=8oXVv$G@&r{0m=>f1?uGcIU^^w`y20*?nHBe z9)+`3U}2Ubb4=P>lD5v^N;ZN`cuc|+N&{p8U+3h;Jj|tt?Sl!}Z5-PJP$^&RgC2bJ z-K1I%a(C((=fM{+hgjx2a2thF03G?o+=PcGY`&{(NW)m>W?)0uZuO$U%-ibuCd!I+ z6Yst-ycAYKiw$f#%-IwVaq7k+fMo&~oI3lPICWuX;MDu<4^QNSqcx_zVT+V?1g(bFOC^fyt;1SafeLf5;yn9(j-F{t=>0iG118Kf0r08u zbGF3K@fGaeQroSsP0NS!-@dLF&8|yF{m}3$Ew`?t{R43?ujYm{ z(aP!ZWoO5_Y^J?eZ;M`SB@QBv_gz28>@gN;ruhahuU5e>pj2HH`Rvd_ML?!Piz54; z3?}7dogQBopUpotetoR>AM+bjAY{l7^TX8NRC{tZd070s+*YOm*F%&q zz8~iMVPBWBkEknT%@1*V<>%;-?qI?A0}1K`^g{h4Eapc#nwnGSWvSM105KJ}()j}> zUX1e1D0oYJtSHMZlJl0PJ)l<~pq5#iU!L&&T=_7$B`$9cpwbliv;9k0`IL>1O?+0hu@a$Qlkj@PRluR~Xh zj$85rY;DJZc-?or&<`s+UUuXW>q!0(5uxL3?6W)GC_CN=5O2_NmZWvOQR#TYI^L*u zyun+w9#Jgu0c2;#>2}}?1uJ8?+vPcX6l%5RO>NGb%3kwOY(^0vk}ae{sIURW;ZwQZ zv3FrL==_lq3Xd2R@`s2BP%A+YfJgq*;{(mJ`6sga+NROCYj}sFpm757LFsv5kMvrF z>|h5uJzE^#hxk5(REdUF%;OEYJ&FkMmNma#i2-jk8`p-quBCkOeI4J|HI3dV`v@9g z#qt{l>q-uXx(-vm_&&n-5nq?GkEpB6dX%h3t&02>)oj%H7K?xgHzC5*QyC9G1?QPE z?~Kn|yS2H6e;(Tii{X;@&NA=)ce3dUj0ZkG^l3|;{?2xPv zMCV$pI-E@PVWyuXZAh-eF!nm1ExD$(g@3-t^%UXqQ1u-t>pL=7hfn7chdS;G6j;?xy{_?K{7>Z1diMHZ47WK&chnz0V5aftrpK z-}m!VTU49YE=#aC`gc2^s?OD#=Owx0e@+v{15(DPt# zkO*o-3X;=1#^eE!?%n(k)D<|Z^E`tkUKWP?LUj%e3E*>!n~zaFe37g^_gotNh{4-8Z}OJIemqVl(%91v@qp*ajZHm50}%@hsVZfSJ{DcypSlpp{;kh038s( zx@EM$v-6I{ab4;%$L7J6yG;{_BY-~*i&G;i=e@x6@4DO#pqb~_1>C)42y6o{admAG zl0As0unD=ts=23H&3!}xGvSL;nWg6i@YigXE(G+osr0^qR$g7U^2*t*P!p$*oR=7f z`gTZ6s_)zZl!a&YZnHQCUa}5j#2k~VHe*ejQ!u{|vB%f3)73!uiRQEyL2=o&2~*+P z4B*c|8BYH6Sm;8ZC9tqtyR#Bb5b%-)njozKHvXIts^kch|JrS_dR-}Zv|sLsKgbM} zL-&GSpILO8o-xyc=z2a$1E8n(J4gJ6QJuTB-^k4)8lkG2>0FrZO6TtAmzx<;PS?Qb zvR67c<2zSVqBi~YK1PN42j^t0c50@+V5yR!cHUHL%2?jt8qcVRjT5KGh1xnS;Zsx(28 z)E&Po!4#RQ%@le5>3L(n-v>^h-@jDCe#ord zDoBP!#vx^rjEMy)4jF+Dv}?aAwrlH~h0}_hg}I6x!cRrb!a_yP!Zk$>VU(g~;f*3^ zVTZ0VrP)-$0p%N-X+_PNPel&Rnxcm0Mo~jEpr|1@L%t+}8F?A`xUqX-3IDjUyI*?f zJc)04+}QnbWB0-vgqcQSAn~}dI|@7NBa!uj*0Z;loPZvCdED6jabx!pt|$8DcZKa~ zY4ayc3i?bQljQp0abtHbw;wll$MB3z*<85rC0&8XjompTJZ|hB&P^>t=>Y7-9H+83wO+b zhm74x3Dy1o!Pxy*V(v+~vcidLEPK{C*fYnnXO1}oV$QoaeFL}HTq$G;u#Dtf)d5+q z=8);5n~7Dmtn0X0+navUd;rILW>u74E9-*Dv<=N7c4Tv%e`)zEH2PDYt4AA>n;RI1 z(-n*h8fYZe3Ux$X?xCGA;7Jofv)4RHl+$b+D0g$CCzV;b)x8CU4;u{8H0^iGF%0srQhZa4LLNnHjkoj!_J37U7J!t`l<%%IUk{Oz@LhM$a-&M@Y1~-|9zA&fCy~s@1l0;gg``#Wi*M znV3ALg6T{4+oD2D^91K=&ku%O6tA9=Teo;Nb+pV7L+Ze4Y;k3Mfoz%i7YO-Xb zR$PS(WN3g$>!awnbVi^iwJNo#P!p~Ea#b()!~|lDQbRGv?JUs)XVlBh_xDyWPGLkW zsJCmbSk%`*Y$pe4?J$rvtP=CMmmU~+Y?aLgnCDE08lzvX#%(m6-~Fwm_KW+IE1L4R zaC3b=7sXtp9Y%Qopq@E;3!30|$Fw&g zd)`^e3>vW7hlu{$i0Iz)`F$%2tmP zi9OZ|B{znU{Wr=%w;MHqgx4v&@kVy5gBUL5Uq(ym03Uo}YKS5vU(!9f7Jb|8@`6DE z`Y!m#kPC}Cv(amVF)$EI#Lz4W49yZTG)rJ;q*$Jr9~5aLtenB&8|o$}P2tR$Bt5*h z(w#K5x3|)-Z}wGu7|P%6N>*jIa#Iv#C*}7>yWC0n>9Qi~kRN@rmHGZ%xM*|KCVTs( z5|JB(`3lC&p!iaUSua-7vV9^!b?(jgyCwNzsl=?ot&+NM5)~MYqbGU7n-UW>jgvP< z>TaoeeUdwAM!jyR*YX3HwbQ?8WhY&PQPY?^X}ZUM>I5ljW(qG5h}ce&mk2Z4UW!8O zx9pYNC3|K=XlY5h?LAccd3DHJCDPq1<5MCM}yi^cgDweS<&x-b>ADaMF zhqo}%usc0g7^QnGL`~#wuh?IgUR?GBO6Xd=t_6Gz6D>477$zTt{C6Sb8d<~0wPiiW zjZ+^jae^v@dl&+)kbTv{2SUi2vEQr}aOuE-N7xIlPx6Ps369kN#trkK{d=Z*KS=NH zMMeGvgtx$x{2bxU^!mRMqJ`eW3?qM#^dBO;gYf$Z?<0I6;oXEe;bHPUl@J!IcPXvG z%=PvWev z58s~)56Sn7gnvNz-w8iX_%gyz5x$)8vxKPKXO6!0vvvFuQ?8NUe)yB`&<{TU=dXSI4Rvikjr>c$`IR@om)5!`%h>kw z$^&1l&l`UE-Qn~0*HVpM>FoAeZi4Q0@~7^Zz#BupSudkBCRwW5iqQkC?>GtxJa9Gt z_M7Qb1HY<~+Y&hd%GczUNUt36m2Qco;LBHgOT-N6E7}r8Gz~+sfs?;&!2Ev?dVhZz zTLkt?`G=p7ZZk#a4eWV;B|Fzsq(nC2h$)!7K4C{=KoyfBbFwx^_MjmI&fHOvw^5 z#5@teoHbRdoljga5#yi#J(r5nYHJytcp10*SlCD(V%Q0svKjdpo zzZQeu@wR9(3=t^4uEzOn(b6a$`V#>ucqIn~AXqOMCMy!QfGt038h3k0O@pr&lj62T z7ZO-!)Ip0muOFk*E2(+P+jd|I;3bxxDqxsYNqKNs6H(<-%MR_Cr25i0h2mo)ZZHvz1^W`CWw~ziD z(HH8l===Pfe0kZV=Bm= zHK7vh%Xoj0XGAtLdsRWJo{7g(oF2>59;b6ig9rS8B`KV2bXaM?#p9NOEx~Dlk4>J! ziGc;qGcW2N4tT|JbBquJzSjTZbpSV}dE?a=oziE-ew!y6$eNuOHTxn3B;JnRdHT)R zMf!0^%{Ih4YMp#7rvv_f&QuT2tXOmRmggP4eg^p%2N@cILpT+&g3GzuSwP( z#u@gk?Rt_JN6q>VKOy|LA-NDR5$x7Mw7=)WN@`}I;5%*-vAo)o&t6#-IdggH#2zSa8vXic_-IP8l8N9ui$R{Gsve+FRH~!l)#+##Ex*7@jQ)viQNLG zy*7iV0T?Q1&l6e3;;_c^&C_z_l8=ee+U&*=^^mKfTu-#BvT<=k+2U$O7S8x3Zt=A2 z+@Upj6XxEsW17B@>zde+alqtV6lu|2G-aC|1 zFH?>Vr8F$1z@Yb4QiVZ=R`0Jd@j|C62HD%u`5*@A4Cfp2U&0^`Xof*ek3mg$Dw83^ z7^^}J3>p&#H9ZEM$_E?9m|@VOYDN#gy5M}}})I~s{TR9Wx=i9TG78lXfU8A|C>B5uU{1dTF%O7zj8ls+Z;y`hvr zO7yWxYDtN>Gk**z(Wd#3C{UtJ3!_BJz5par_5~o3vM&IMl>M=#MBULyg#JUHFY=V= zJeeW2fBN3SO9as$WLpDUu z58?AuCwA=u6{foDIMfYD?&JY^xmZ$|y zxN(KIHl91Nngi)rDf~^hb`esH<%pBG2@c}jrVh@H?%KH|@-T@~jkBZqddVCZ#2+8} zLJXX-ZBlzII zMgx}wCKK}_1i|NdS$hV_eJ0nz$T!52${WO*uKC!VLk9O>a+4tOjl?nrppy+i9w;CC zQv9C<%7aV3CzvdsYcBt*Zdc}n$$#AUy&=lq^%3PLPARLmNhgXZ%l@wg%G>W2qS*Zr z%VZBMj6Lr01n&vJG!<-N-&xDp8??0VVpHJp6_e*{C7}#AoxUy(NewBFNw`>1RV^;l zoC#|0La}E(~1$UhM_kmh6Hcj_tY>F_Ws{F$<(d9X0a`j>(4JuESwl zm%@mjTe_iv$$&s{E1Le9luJY!wDcPYE&rauK?@r0`RTXf?xJ}nqPU(b5D2Fbk_H-) zdC!My!|Q2_Co(^fkEIXBy#uik7w3Py#{XL3f4$cKIz4YG=T-jK`To~I|LZya*Z#@O z?LQB}qWyU(Ba7Vrr%PGP9gLrDPC&0B+`#YG5<0@y5TXv|4iKgcbZhz#@#M*!3N?Is zK@Bxq7x8+i!j%zS5KeW4aRyoQ!$04_(C0qKAKehE1P!3T>SNjne;xunAxk zgXB!ItFm?M&1*JBWV~D~B)Y+(aMn7l7KKSV_NZo%ZQ)QDr|sfHYxePzf<&WV6JqX&Rm(E)*M@10RGUr z*%W<(H7=mxSe=`1T?9QLT;(D63-^1q-6j(jN{E4~q03BziU|w{&(cogE z+dTeqC}yO;9D-O<7s2A4{?1y}C7}Jhh0WlYSSe|3bkRVVI9WQyAFAiyjCSf9{j_cR ziEvY{y-sJwwH%|BK3u?gx2y@?_l>>Jt7OijRR8c6G?*&ZcM` zJ4!1&TBQ|;{(|M8|I3-5<>B!vJqc<`-sAOtG6u60RkW*J?R%^mV_FV|G)s7=uZz3`y5#D0nfBHvQ^!*A+X$ z{R^Zhx87i9|C*2yqOaA@2l;Rp0j*S3aH6~)CX-JsA*+?CCa&;!_t=h+&s}exxbzs zxPu!-J7`gbe$2V_pJErZ7}9@MPeiwHY3wsRt*rIUP@+)nL9eim65FuW0$sCuPj{K> zmAad%tJeDzYW#+2l}zVjddAMKH)l9zb@DGndLN+fwgsJn+jZ+@>cI`Y`)CK|r|K@e zo$!x((($R%e5re$vB2oHx4Dy6|fWoEFTEh;v-D4@FDe*k?zl>s{IfDmv~oleO%F3 zFFJuPKDp?kw3{@Kv>`aZWLIY4G%Kq{Y+!uYX<)g+$V}wSVfG zfuBdes)dgNAEE=XXv!mtgTaNQd*$cs?%j*Kp(ZkUiJv zn5vFf?kZ~8MOQRBWieFp@PMIllr1`gp5WL3+CKhpK%S{eD5 z8<(Enc+kC-4vwrp>zz^C-~)i+SRV{;|L73Giok^za2j-t3v5$rr2h)HG*{hZ zLyI@D3QamkkMdrO-3vxp)GE7-Mws%3ro6G9253T>*ZL22)#<$Xstg}IY$uv!r=27& zysV=04c{hxq(sV6>)eFH$PN{xS7m5}^LGM;sdhdS6s9KX`>}jcEqbbXB5z7L3ca9C z20r07m;zlQG2QbIHB;Vx^3Df_Vy1t_2-+HRZME#yG=N#Q$nrj%ekie>INcm|(lb~E zZCU&@(cv|vay&$9a1&B`)HSs9%ku5C%Wh53N&Z-e4mHtF%^BYXUr%X|1t#6;+hank zx*2=6*!R#p4)GdS$c#5TL&?#%uD2#&ei)YUPaa175 zXyYhgaSzuTX5HgKgCVGt^u&bI-6f(AUAIKcKq?z0ZJ`7x5|RmmCAcrqF^^Yw)AU1- z3{6iP9YhWmAX{%jR1ZXiv}r&DX<_5q%_F&pJ!h)dl^K;LX1yX#1LY=WU>>KYK+9sh zHYW0+4+P3}E!6o!&|V^S#kFn;9?83VrEl1a!Q-`x~X|Cxb)}Cq20zkdG1jSR_dcB7_P*L9&K~Q}ald{?x?Z%u5;~8&R?by@+G)+y{aE&343&BxK zl==wQC7mpu!Mc5XV|1FAFC;!7N3eV2D}Vx&w;vP~AiinVZ$%9Af_y*WV!|ksOQzEM zWe7K!e`+!Qo7W&B=q17!|5vIj=OA)iRIf!z%zl@;RPabd#|%oGN_88P+xz ze3Q1xNo*kg1~4T#)_TeLy!!=^)~mkLz{A+^tG5Cyo>YQUV1wH|#L)9)bN9dTHshOL~D9`?f3t?q^C zzxhwGL$EgKznchD!ffb_8bDMZM#cFTp+k(o|Ize*v;0+UNX&2 z@=75PS5`0H-(B*x8(1V6Oa*0?po&un5UTZ5e`aDoEW-3p~G zbxSR+HpOR(y;2AHCt%ZGj6bo1UFuF!FvgwY(hHP}k-9Z|rpyFgq|B|rF}&mXO3?s_ zC)b1twxZxQ`E*l>WXwc2_7nP=g6?1!o0IcApUOM zUP%zfsb+GTt%F5OaT3x$?OMe>Ec>x=%tWdo$IfYgacR+p znoV)FJ+!H<0NT!@3WV;K?IGY9Xb(l!H5x6NjmM)CfNk~&Lj729R?=qtuT&z6ertn7 zWu@kFG=KR-s37zQ0xF6lY6+DzY6;bB8MP!wMbrS%oMtf@-zuegJ1kfH*YwZIRAck* z%+8DD&Lcn&eZ07E#xN#SR6yl7Mo)r3v2uu5>ucT^O_fopkK%vHp6MoHIo?I`7W=HE zL(mfywrr#vL_)`J$y1t)?THMl{?p(5~Q+L{`$KJ)`bSg+XAY=`n*7M4hF1*zqF*}0v@ z!K7)BTQgNHr&^otB#rGPw`Quh22#C5pwcc>fM^YHDhe^nYXl;mXz`F*3VLKq1u4cq z#=y;}lrzkdDYm9DgA`B>{j?D_!WjuR!8q@gUJ$YpB8*!7-O(#J6YBQBjBHdRvwW6b z3`D@jMU+fx4Z4!j{s){9d6^xv&f+G8qcwwIk)WI|<_kOxTrywP1B3mfYhX<{FpQE! zv4}9(vco@CGn!)71jwb`Jq5q#$-% z$o9{e%ucpDMRXy<7F$jpGhVYk1_cYpRE=~PhAu^qccJ9LI|RCZ>&wg5yV9=m6A{R%C)9P6q3p((74w{lrG|BowC>V5 zvI|iW=Q3Sf8R+?A1Q%iwPk~|0FB`w#gw!>^1r%70T^^km3>PiD@I+a7V&R2t4Oq+Y zg@uT+15o!&FrrP-AJkCAnOJN*yxFGzVXaUTgbwCx7vN)?f3kHMyQhzj13VkKoQjdm9`5vAd zN_}yl6uPmL(pajc`s3OWO5Hh7ien_D1cjp1AT*vHN_}ad6hbaa34SUy8-_2T6bS~$ z|528NbpN;+7d5>=Yh+pKZMqk;;j?U5d%@tp(Kq;qVN##kCi5kiF7;;T3bt6CA{QLj zh+IJjd928VuGolNK_4047i>ec$lbz-TtPQ^QIQKSazrlXR=rETrvMnJ8EP0a7nN5 zPz9(R+r@xa!Dqn597jDuz1`|eA!4%+Hu%8#pszC_kOV7s%MQ|e7awmf7qWNp;UEGg zrjv`0@7MmdDY~}I12(P{mEdkb)2`M0pL6k{IrV={(^H?~1jVdAW{y5s9jmyPnC0Z7 zTq2T8vl^;iK6EK#O9a`zakN~6^GCOS_kqUZI>0ShI$W=2@-1ocfgUTM|u{iTVl!thxt7wcnBWuy~T10}8b;ZfE>GRTKnPPoM+Y6q zC>Q&QurwK&hm&?86O@+mLUFHcb_WGFK|^g(!8YCFEZXitYJg?!1f9|RSK%m_z}-z? z<1aH@`g>);^nZhDo1!W*U=AhqYx%ISIaaMTFNr}NKuAJF;v?|IWoY2V0b)x;+U2Us zL=1>LG&`e+ll9oDLXJhDU2LV*EfPO-M!zW1QYgn8mId&@28$-tId(39aU zmlj1!T7i}@PjBPuD@@ciUN`Kg`!n^^#Z1w4ChH5Z$xw)bO}0-MWH@F+YftJ2dEeu4 z%%geV<8jQRdEeu4%%geV<8jQRdEeu4%%geV<8jR5eFfh>-z!`{9>@G*N);UQm#e7$ z>J#IbfBbQdS#bY9!!g4X{Ga2PHW2Cxq#humzG?9gv)HPOjRrye6TDV_(!o0Ip@(twvHCB8#Uf`(qff ze-H&15-63}4XbaMqal|`dQ2`NsRR1$+WO@(P7AB=Y7X)%KXZ>Ak7*nG_p-yEkQ+HR zf+gA*ID2VV@$&T{7jh$*OI#00oO(je<3Ndu>$ov<9mfUunfOu4m-Slg$}JQdO$s#v z$_yWYiB#&?T{5_#>i#Y2#J_RR#F5zFu%T~A9zYXG+AUvsE+AjIk;4PXc3zk&?Q}L~ zN`y*Ja1Q->UX731u&K?qdh=3A!z1&|!^;iwX>?bQfQUELMlT+Xt5vh1?XxBkcL`+V zlwsc$2rZXvx^0@1m>H@EvSVUQPYM4U zoS;`Ah17`P^;UD~jtb!7xm5sx7B?^~NVs1q0d`-JEeGw9a{TH0|K$C#v;bQ=LF*Q< zC*NiWP}aJ|`JX7&G1pcEy`syIFLRW4P16J<^-m&Pr!~<8Z2GFC3dqI8C50*=)7_=M zwp%Wlu>7trx1Y)ba3}deoGj^9t8c5ZFbDtpmATnQqi0|({VLAAECM?)xpB98C*0#H>lhq)srP#>}2FtxF11yl%3$FrjUmQ0*?@#NdSbJ%Kf0 zM<_Ezl2gEPLd)zb7$%gjFrj>f3FRwHC|_Yh`3e)tS9L;7tcN?nU4}kkLWPE+LbrhT z#jU|u-rX}H`4nu$>nn~&{OQ#85>n8v==(~sy-q24El*VLmn*4RYYI3L`35;G;fHx} zGu3n&neD;Nc<=N)Spoe69~V{F{imjg=6JY#Vrr{NdJfFkk$ZS*p~KyyduJW+}>P zJG&PDZ{C}}7S%piKaHV29gt|>p9@Ctt7gRTwr|!9Mosq<`L^`0u{4sgWPlgT2K<%K zO^bz_Kh0|p7MUc0pL8?Bcv5Ngd{kFurKhgimZE<8-fo@M+sceK^S?@VO@Ob6*sWI# z{t={wLO=H`77y{i`-ud@YhFHxJaeciEjp)FvK+egQV|URJSg{DM#_qiGAQp`N=h11 z`Z7M%wuF?)kn+xfc2ZKZkaBn+WicsF3@N`ckg|xBr6J`v2T~?Td0I$$*FXwRo89h^ za%3Py6#7R)%5M#%jFWPDNO|`_$`~m>5>nnXkkTgQ)R1z+KuU|09}X$MJ&@8QWmib~ zoq-hiRQHsS^4@`zIw?Ct%F%(88Y$<8l=ls!ptJ7IB!x}7;ZEw=ZO;4491}5YcH5o8 zvQY*j`d)k;mjUw>CZ@g`*7>36RoDVjrO6eifm^^W-K~bcig9PZ5e-)?vh4RG}nA}p61+sKZ zI20BdJ0di823eQC_6so%AkduxTBgb&4Iy50!?;)W(6D0Oe>ds_y7IqJ8g)`0ZRP95 zov!tavJeENaWT&}HpUXbr2y`UE4HeRh^4;LXL`90USj*%!va7gq&DXs2O)L_1}qfi z5Wy6g5b!^Yi5s|(|3k$JFK9CeNeVN?a?-6_eqS{0$H-TBO5sFwS0pqMHO@EY@BdPg zzAn)y^E-Jj1$KvhMAL+q?32|$tXyoruKMZj>l2n8EA1yW)4uYj=C}1L|KecfKbf!n z&s9E|A1*5Q-A(f?zQ!{>7jkN!A3d?|uFv20jS?0crrj=Fqd&-Y8udr?#Qfi}1P|bH z({AVNEF1Dq++JqE*Z7&EvfTDXW$_5AY1okexsREsNg~d^g+S>uk<{lsvbLBU&$)9% zgEzleco{B-n_6tn|H8#F=!x2x1#R8(G# zy|0&G@d%zCnhzSY8ieMmZ?oc!WLvK}v7^@oyfKWDZh~(nKYF)3YBl%`Wvx1WnTLoL ztrWnd@p*DHM?<2BYEO$ggqP0?SN+xOC9B!VKNk#?ITzXeG*Al~mGP%|n<=PNin$i6a*asslIy1LA0YK@@3-~ zP!F*Q*7?o*MevF*{;dL*p(;UIfue$I&A>yMAQ#1OnMu0tCMndTcBSaXl+JL(^B?M> z{&L=HVEOK1mdXsU9wZ1F3!gQKv^bDPx^&09d`?ArE2u37^A%BT9Y32>@J~_^SHslH zW;5ZpUeO^K%X>IG%Z6+k^J!T2^q)(5Mu!p=c~p7<8H!K;2HTm#sYLsFNEkcawovq@eZ;1 z2lb<_Ag@qI@gwgH7Z+-mk5_S>Tj5Dj~=2T>XOZ~ zzp|k|*+u~_*?4=dWnkYk)_4Mf3`xdjw+osOq$QS=%c6oO-2vPLQI?HD6ckLG-UXg{-S{gArx@5-+Xkqz({Tb|@MWMFc=4K*i%?QL*v5YLR0%{B!#jJahp{xx>h z4d{Gnu*vFz%nq=LtPddr6e-nl4nsc#VQ66JD9IXLroD~dkA*FtI&f{GL2pQ|N$iCx z&XToDarxji>?Io3BTNLBUuru3V-gqfPLixtWD1Bfn5Njim3iM#M0+@*TSRyzItDAp zIWD}%sE3hg!B?ktLUj`7i8z|HE!eRN7?2LyzYfwJyoeS2;Gia%*9Fz6#vSfxbJLn; zcOSHx@Ky{=3kZE4xeBe(KPve~O#%KK$e~>0?%Y0?3C-UWeX-05%$`mnga{f*8J~X# zQ75QzP|+S8rN10B4!V+$i))%w=RoKZ^b%?igV~QA%CD?;H|iPIKsgb;1bZ{1l+3e} zjfwB#$uUV(B!||m0y?HAlur+A?S=cR)+ZVB2>k`_XJ_j#6!O_ITO?%g@>xBKn6c~V zh6Va0`D~vXz8KyNW|)_|2AE+Hf^YTt8Lw%K;GhuF^$MB*@Z2(nEL?en?0wGFm@iJ4iWVK;Kwk78hcm@Hr!fH9v!zz&{@u0QZ<~D zaxRv>$2cCpR^=PPCq@nfw=H4|WJGP`Z@RL!{f=GBG}omvfnokwIAydqM$0@eH3nv~ zYp)IZ?PG3jUm>0}ei&EAb|NJNyt}M*6vl;twk5u8Uk`=(Sr%qDvY&K--8t+=tM<56 zVG34h3RW=%%S$V7?X21!;m1sPG%ELa`cW|~FbbYC*ucn{NZ^ReZuYpIGI0r zr}{{CrCao5_~a|x)JLxS@hO=xi#Bt2J!NxsX&&w3qqb+CeqOdOTg$9p>8^O|o3bm; zjiLk3{V}I7ie7RlgTCT@OhL{WlfrH-PB55fG(6TYUj8!mdbgEd>D$|#Y?V5}giGgS zm0PRFfY;JcPt29N_Yv#a{0;S{+$zJ&<-!gvP>*A|v);dK`ZB^~&y?YiwMqdug`*DN zq7;r+rMGxZ$I+@ScvbOmwcdKDWUI`LHz<3lKc5KYwV=yiuQYPa@?{TRYpcb`!zwL% z6gTRMg2u6s?5DUfVi*JFoQ9^RVghu^^`X_#TgB1{U1;{Zuu8*YSRx?=uk4|bYPGEr zS#oP>$CifL)q+#It3taVjQZ1C1!WY22U3vC_9y+A)ozvYE|z};j(Qik)d59U3q@D2 zkLZqQ5PUF!EU~#lYEa8{0)bs*12*iDA}(d*)U#C^bH;oGE?8A7o5Kq;|%#3 z?hJ1J{7#pjBXKvmo;J;X12@y0(Q&K|M#AOhsA!Y6-7~7}4ehCn6==S6+uEP>A~X?+ z`O@X1?@PCxm%enl11x;$@>%hv%df(hE}x|@UC5#O&4mJ2jRsgzU=ijG4CWF}N*(vJ zqB$7y=zPrFez8WTk#(C|94AdJ(yTz|L5y zzSS3VFN>}rR!UZ2kF!!y1l=3Sa{Xsnsjq6s*N#31FC~sZ%oIYUDmQgE+L?2)Q$vy% z$)FL*nXQ?L6z-Hrf!e@1Jj8G=VllW~Q}SYNh<>#0p4M0K8F(!dAnfLRK*@opGKv0C zA3g9+Cef$+=z&KviT)8E{q7+ZpHqD_Z!z{2vdI0zKAQI!2cmZo{S@_u=NQX`LCqhr zOQ_QbcvAf_V8U4n0vm`rg3od^EBHEUPqS_?bs8XZTJ324>9v=a@OVle9=z~aHYTLl z={v{sjswx>`)FL^3`C#lqj}VEAo>&^J^X&)Nj`eu4MCdx2_HT1fFRM&Ao|&YNA>-{ z6NZN?;Xxe%9&QjGm==hZfgjKA!(-q{LVEEW-?@SJ2#LPLN8da&@J&9NH}3}E@k}4h zyLSW8zu=>J^ll*fCw(+8-VH>*is(Ip2M^wr2`3DX$r2va5#TX72#;6W9>)^^+P4eP z?CFDs=k&^Ug(?^Me)5jqK=f%odicq%e<(^ylY&HwPYrBl_h&y7~&7AoFA&&4XhD zklE*>d30Fjicsq4gIQK4U$ov3|*qbz^iVKE%8V z%*NSQv_?mDA+SP`ev-k6kb!y#>6BcA-F>-32fk!{cuw)3q6>u zHs%|O$3@~`0>|VxsgnN7ld#>|tSSCkI4~Y#7X#kRZ+*RKYXwHOR2nUEkIl@Togpo; zA%;W!o&ez|5s7<@L1uj`2E>;$H>Bc`(>rW3Xk zIpI!5<91%k{3Dp^k8FGorVE_NHzTDm(C9&9l~E}P5OC6BPFu$9vD+j@CdzqS;IsHb zszJS+Wwu2tXtld7TF$R{TeOZ*N{qF9Z~omI>{8bB!#T;pR&O9_TqnMobK@X+5-}sj zZd*-yb_~siwy$YfsLAc+cYALh^Y#`!^8>SB2fHTq28U|wcEfk6Z z6%vjw*gR(_#Q(l9QZNj9UX?pt`GfH*R>0~xtat2As3Q0JrvXS zoLTyQb{NYe#r53W`6cGbY8)oza1xnp0`Bx;my|x^i10q+hzdUAi1I$;5@yQ9Sz_WO zDv5fDt9gW_HvCkY4W4-xJ(Es{InXo<&^~oz^qs!^?Llv#$Xv}9$`M((5Gse}c#*|C z!OaDaDE*kg6?JZJB#??LJy{s(WH&5vbG25J$2D#kbp4dety2D5hhwf$IgK3lADA5U z>Vj9EO6-V6%x0JDc$4m7U+eE-&va<%Z;2WNtu0X`z-)`~uuKt_EV!n7C4R6H|ID;k zl07a7qzbVdPAS(%nuo9s0eZ0xHAzlBGiN2b8kbsiiOfAf8H90pelZ72)5k%fQ}a}c@MyYZ{dKp(RDlp^a4qOPX~tMzRy>)SlL zzACvpVK5uHn}*l@B}&CMuaC;ZQ>OUZK)@^7ev+(Wpz;icn1K+TjplQl*v6I>nUd6P382N z7m1)4%C3VZT$3b8{*Et^{^Hx38CYkT)OY1$2W~o6BDk*xJ3GN14b2cK{gjYi*rTtw zq;JG{`bJckC!#!k^VQr|i)##fWAx$@RL{2o5fu)*H1Ek7QM<}q=lEPKTmu!E&SYS< z0#I?@=mQF{mwrFvd`UH7Z6#sDG$c08pU_VSP5i_qBHMk4Z0;f8hU%P^oEZo)?XNet z!ii{y=5a$G>PM34^gRjP!)61xD{qhM0w|E!l3Fp6$-xTN_AA&royF-5bgo~+WLd-7 zehoO5*PMWy%wL@THUy#=0gXllq(CPi6_7$$q|sF|i%ALyJAem50vmOK1ZNE(!Ayw+ zd{M>nETT6=ii(B$40o=G;Va3o+cIclGvv82lW9D7S`!YwKY_ra#00>URS>tTE({O{ zrB3(QK=OKnAyFrnQIkbfScK%VK6Gx3Wv)$C@*H&8D2Q4T;QtV@8RY9A%ic?&< zstz!}AJF{zb)^DcfKyplwdz&7R-SdQ#TZMZ&=mP~23`~(J{(6{9zS0q{>!Z(QNj40 zQr?{qQ9oMdy12+SYsGAgwv@Rx7P$h+r7l-Q1)h;8;~CY7VR9CAE@R?0M$avQex8*k z>fADFYY`QiWgdL9KgAt_+7F-dM6WkJJTo`A6tdr#X_lhN>dw6X`q`G@^+@DH7ta!e#7x3 zRcn=MH-4|xZYZnW7^=gBmngltnuNM+!P@ysE$m)q|HfD*+gy)V?PyMr|W= z7n>}KO;(CQtAU>9j+p4Z=?9b5Y%(L+-#PiCnua{bXgVMKRIUEZ{S#LvmnT;+@?-KI zH%I2y4h+y9ee;2M3&L^N65EV?xTT?@XCI(po}VGJo46CLInM*vrq0r{Yw+$Mqki0~ zAFWdfby?KPaaoQm#5ku~4z>1EP}c<11Cw7DlVA6uko;e6iSysS5h500JF07)2fwf= z50`%CS%}2^w2;QPZpQv8+GUCc`GI&JQXl1bSjF)%fStZ8;=UQ;$TAb{Q#J}`3B`FO zot$+tvaNq7{A~N5U+1R;Ry%&L#)$I6`^8~WZL-hR(-m1Qf6YsDBvUup>Up>)%J+-a zV6?kA+SF{w4rdypL9YwnWc&QXzJ4ry9YI$kXx!Se80z2djV#u}hO*V}nL49f;Z zU(ggOV!m!}u*KhaH4UuR@+e)Yk+<#o6^511eK+bJFU}>>LhQK`<6+Mg3A*x;34f8~ z`(=lhkll`&dNSr5Wy`PEjqApQ+vB_~VV0yMlY4IxF2wm;jv`7-R}r1$<5ZxE-T_a@ z=_`LH;d;WugpTkx2)p^~?p(wi>7Ln|yig@(?$mWKbS`|!$ATsf-m;@8ebGXP_1lp< zfYFB&t!ic`UA6|Ginw&$rf$D4ATTRaKNt|Jau#>|}d%X?mdj!vU$DVHiboZqIu=neJO3eY7S0 zxY1QJj_uRwA3<`}hu+<0tuo}T)E7JL3(g*%D9idqidM@b| zTQQ^Np#!54`HL^5v+C-oc)?4|zQ!F&;FpEH%{B2Kxm)q_;7`!bIy+H~txH;gYXjG0 z^>91`Bhhu}n0U(?Bm!*H0i3tSIfc8Xy`_tRu;2of@T& z6w1*AGGn9h^^Q8oob_U=pi0mNH(A>OnNnZQ8{81cf+aqe1 zGP@$n&F$&mHhQ-Cj(E1uwhYNhSSvc)uvDp(%Tf$ zx zJ7XlK%lE%U>+-Z`K80ur+0j|aVLzwphasEvNmx*Iael#%@PFvSf#uPBwuplSgOSzu zADpXrf=oiTFu6d+QvM>EUUYJl#L0Yrlr8}+d!djDFkdc3QP!u53BQ1t{cbz%q)Y%^2$S%H71&VdFT{n zvILr&XF$*c+B(AKM@MROMA%6gset!e@?F_BUzwbxb0bqw01)3Md1m0=5XJfZpZ&@k zd9X>?LghM-`w0u9WiX~0%6w(hi&n>t;!je1Sg6gZp8o|8Ve6Lre=C&u8?Lhe#x_}M zs|hhqYN7*I(O}94(W1!(k^x6z$Bfl3$16zlW4xFXXYd3UM<3Z83_2S?PevY zUGuPC?;#@#c}xrYM!*2ek;yNLW?q=gAaqW)83n!ZWf1^{Bb|WR0I54LmHBEa@g012!qjmF>uY%F3BZ=O3*04|Z-8}*`Dy$j_Ea4ZOi5T+M61nJlfW1aNa zji4E>2@XL~P z*T;pyJO#!j1va$>t)^c}fIE;}GdwYDG7_8dPT)KgXWWlVmx-ZWDTU6DO)8Tc7y@3< z#A=UC=rQlj|KK}l)b-Ix{>MNkkM3-*mF2DrOhc!!zC5bXrN(Yd5Tt{MJ%nv_9-XxG z#PtiE*#8Fm=kQYkI%(x@NZ6wdREYKLV6}*Q(rgtot-0m?T6{!och$@C@jV%@(4{x+ zcr?DM=l3&kPc(&W7zIwW6PS5IYf38f(@^vqmNW2%B}sw;h*lgTSz7R6q$% z5S6aVbPYs@SkLZpjp}>i?F35tQ7LB~7P0T*H;y6Y%btye2@%sb_I8v5spZRcmP9e1 z)~R2b6LhcUY~5@|D_K>HO2*S`P)U6)!@xq#mc0Lb;~VmXwtVko|lhy9r2$)2twP;VwM|8n^iE~g!C&E1a6 zdpkM?au4bwzhep--qsPYE`u4}vE%($JkP>gk{^_^1CyXb4}TWFz~Wb4zGI_(y%(r% z|NY)Y$>o%ap2rkilpnZVJag@`>Ceg zcb>j>xxC1;^UBM!-Ndt!WUYY;n%F1W&-d-;w}wJ#?&`XQP>cSlZ8 zfMx`Y*f;YXu{-yQL)rEn@l|g7T!fPH;eL*@@v<^0`wwcGyvQ@y+cSZSI_HR-cFy6y#83~ciq z-!+WUOsZ*caky9U)Io}ePJk>dL&(&sslDlajqIZHe0~48|EHh`<*!G7l3x(K!!gHF zjL0Y!7#G`qA!N8Mg|2%V-T$9u?O&S~t;}M3j@LG^;Zh_=baQf2p>oIicw zY4px5KaR%PIL_Gmy|t$LWig7Q z?0n6tYk1ckH-1&)=#4RPuwr85J3J_+R*}1~!NFJ-yC_*u7b^DA8oMNirdpiD^Zg+` z60NS;wi}gMYvq?dYBV^eU8&#)Ko)fXX2Ck31#V2ywA3O1AIh(L*yUhxUDNx397?WV zP$c`a*al9Vrp08MDGu<2of?u4Ef%$5v{YV9y2twXv`osRMmvS?)%*VQK` z1v~;wVS~eXzzL3Vh=UC_hJhy7Mu0+@V5&qg!2|=I8D}DcGvf)4HJ|TV`~0}S-Vb%_ z2aepafY{s+LHqqKaBm z5qM_|SH#f51hw8Kdf-SpZqb;+jKF@!NF^{E^d~Qfa-7*{;=yK$2|Gk+>P%{+85d|O zz*~vmVvezi(dYY+4$Az)J`t%}f^G{;9<>ZM;Amc78C8lVgAVH7*p}O%E97PX1l(;F zif2h*#z#~gU?(PC^g2^*YwUgA_Ntkx5H!z{y2j~jRP!`CD^;>UXDUvdRK;m#$rNut zoZir#a778zzEC}tLK>h|5#V0qO5x+8>yN~nn$i`VH#J>X5TZ6+VW!|sq_IKzAQk1| zgi0nYQy9Wrjae;G+Ok=h#7LkdhOgd~I%8o719{Tcf;w$5yRl;3nVf_Y z_kva;lMfJB(*()ez^bSBn0Pv{IoQ>ZZqhNt?G?4cIglFm1Nff@%K*(Q-J~h)pdo=- z>L#JW(oGtv=p2q@Usd(S))zBW4I4U{3sjbW7jzRXcS$#CNV`yfHcdAvnuF7nbQ9Bz z8sy*LYpMt7S`Ql!!IEmaiGdRGc`#kLFG3Tbv=RM;_VTqgnuB1`PkOGOxT1p$_aWd^ z0W!$ZNL8fiD9utwsW%DJnm5Tm^pSu8d8kLzn3R?4C@QehQ9696E-!SH*r$530Kz!B zj`C2Yqdatgj`9#X%0oYvJj7N-X&?_t`c2VMYAHr_lm`kOVMIqk`?#1qFruTps?bsH z4?4;N-<3T8vVQeV(NQR})KOHD=_vOnrH=Bd2|CIHXd|OK%Kg$&URCNS_q&dAzw0RX zPt#F~J_<+KT-ahTVqN1}&JTEV8x74Nlz+;K<$ShTvurPgO^1#UDxJTj@TeEC5^*&J|l9 zQb$OGWNIjRMDw0PGI4Dq5(k#^xuZIl98>i&Jy5vz?YSC|?{ZTMmzbwud{tOZo`YU;?_ejZO}(?_H) zQHKfoh~@73i0iiTJ~&atsMV}yFe%gSs;>%tMAmj!dj!BSF#0&q2;7%Sd|1;*tkZ)$ zt7Ug2@<32mh%k@`f?ni-_pfWK66UUVgYl-4hwCGOih@2eMivL@BO3j%2HGW@Mva@y zj&l>!{_Fh9_?>@VS3;bUie<2hUU6jz-DY5~P;zTZh+4iNo&}0P2{F2|uZ$K2jfRvE zpYTpoc~ibCn9aLRSlzs$Dv`Y{%avM4ZLvZFO1%m-hnZySUq_{``htbDT{VAL3z?-+ zTCA|yKE#F|?#Grs;RA$D}M@6%k*bLITA^c%Q-mg_6HeuC>=O-L*7ixnj4 z3f{)a$%lM({S2W4#iq~5SU(9+gl7fRcub%7vs;bHFDJB1@y+bgM$X@!+?podh$vmA zA-D1$57Hjg&6g2;gbSZlfy5JwhJd;WO)H?9el&i>g}) zA(rnwE$X7Dz0K1WlUJ-=XV6_3Q6``q^Aq{FDExA8;CMF~4O4mWwsLi&~$C=ye_p`k_q1vMD+EXHI+t|_lD z7m^j(Syg07Z@fhvhYp)wiYU}dAE8N06KMrEOqkkS0ZnL@i94LIZv!oNSudo%V)dFs z<1;96adWCr~48OM{`!qXkXEj9_)C2*j``?phKut)zHjWA}- zk(KY3 z%o(qJvrg!*b#-Bc{9h|=q3hETN{=#hkjn3kb#R-9rV1jkDrQlZd}A|DJtrE_oGfM@ z&!8%+jQqJQhMX9qRD>?0x{_FR0@o}mB3Uc5I|C@1U9x&N84nG6vDBdW&7iQ}yp`yS zKjCeGZ6jsm)hl#hRht&a28Zp zT4Ru>up9O5m8FWRH@ z<<)ZPY8;KJG!DU3ilGqYiK(;;$~ziUF$%R=j8v%<%n=GjfxA%(9pZB0{S7FTX)?rA zq*hL5DU#c_hH=$rIM8S^h8bj1V~jkF@+#`ldV&*1!1I7Vr#~?WaaH6y7qf!dTo(;X zxSjB+q?tfR=qUwTVy7U7`>KnB%g2~>04Wknpi}L18CZ3~nk#_Jd~q~j(`~_P5$4T^ z9JLgonuceVRiETcX1F>nWi(H3m%A+Lz&9l)q#WGIgIC z8w8n({q?0||K()Y3bgbLjB*oT7{UI_$%!Ia9s8eV_*I)3{yW8SVa+=Brw++svA?G+ zvHxk+WN3X7?7y7cNgYbOF@pU+yjx*^&uudHKOLwu3&wyO!~R~<5ca=Q91k*Jd>IT-t=$udKGXC3?VXbk(Gg0~dd|8zct{hh=X z7{AcaqhSBjVJ;-g%yv^ZN_vClYS`Z?lxJf!Sz&*pZMbG20S6(PWx`Q}7vS4K%fkND zmsvjr`=^fmhvvly_OCJn_xX$?`%|Ha)5F;RfOd{!{}UtF{|@ojWk&$Tr1q&i0sB+? z3i}VW!Flr?(x$x1K)hzMTf_d#Q0ohc{Z)Pq`;QQM!2V-T4g1@4oQD0E9c1H0-Z;)3ATRPKEt}XNLV@L-}9g2(DxO4EU!4{>tUK z2mUIh1pW#QX`^NCToZwRpu-ym{>y^*L=%&In@x;U2HrHI}{@^;9qgPLjnIV z0R!+)9r)id4E#Nffd3sO@ZW=#Yzz1gPx~?8AM&q&Kk1!hCIbJ^njzq?FQx;3|03BH z@OQFG?hL?xE&%_MtiVU+#0XD;!j$g_X+5u)U*!j)6Xq8U)}-b>%%ox^6ES}v&Kt)3 zBNeJ)etT1h@%=IXUXa%{%pdA^0OohX5$5+1t}wroo_K>~jKTO}%zuZ#z_!bz3iIDV z4_o3o=68lJ!Q+_!&Vc#%2oMV*CKq%SN5lmRu$i`yS}l@=R8wYB3Qs_-smocc=$`)8 zR1l(+&fMP-Q2&MGtl<9NN=`F9(r?zUE9p13Fd7g4Ljf?`eXDl?jJW!&x5~2k(#P4;y z*!e4Y#F~V5yQ@}7N>Qg6g~X6;rNB#3(1bj#w=+`VP9+z_k9xntAGVQ>? z$%vobJhJ67s;<4Q@gQZlZ=BB}Z>sIB37TUngg$9|>xl)+2WWOmduL_f;^c|AexmOQ z_v*5v^;izPC)%M|gRm7;>w|t`L@S)3HDD2loQ`u*oPle0tR6mc+6^7+L|=rK1>~M9 z1Ie)L?SW+OQs{+&LN#)y&F|-EFUq6!Ttd(7sOM}wV5sL3_1tZGYdyD&7Nw+PC7D)$Xlln!oG^3RE=~puX6u$h8?xM`EeZG|^Oaxt!#`%EkUol=bQoYsB91$*Q z!(!izec67_IH!Qu|Fz$gB8ruum7f7tZJSKX0cNFE|rau;A>rz zUNb>@jXj03X;0gIW+qB6CaroJ=@r^Vt7=vq_A11@+3$aPuf89uP)&N-o4WL}Md?|p zHDm-Q3%B*O3+>N_qgKB>f&!}Aq1D&@_6tXuinL-#MKv4Cmi>{C-<7o2ya<`PuS`VF zrYzQ+8pgkbKJ-Bt2>+yJ6`lA22iS?w@k|ZQGIZ3H{4c(*<}9N;9U7Iy1p(e{Um2C+ z00`IM9=wNnIGH#e?#X6c>v|{oTIaig_IV-=o0c}I)%_*C)~YjXU>8rAH0Tv+EWH}9 zV@-GvHGLrVp_71W?8E$3Y)|J|R#$8(&CP`{Aqfo6OIwE5jDyK!K2B7Yi<4EXd~8Dq zaWAx*S_9p)b*d`98KNtFk<56(Mov9}Zq&KpCo@|ksD^`Xm_lUvj!;&eu5SA3T{S)3 z&|afCn~TF-Vjs4(4{gpr_q2%ye@M1vD>jM5q0tkpWnT(~dVSYNTU$cbgtwg>7~0@7 zW8AljLjksHbcy~38!1I*K-s`LO<=?$Qn(>l$GyObvM6EQ$wU!+z;&LDU zbroRkc}5krl8>-bdsI|`!Ebak;HV_9;i%0~Llsr+o-L|~HAlw<0Gi7|s3KITLKXJO z5ciiFla#o~393XD9XGoes`xUfLdP=8@-m6{Lx7h14S3*IUFD1TH4c9us+i2VYdJoj zq+!!?0;;I0b0Dg)K_5dEu?(q(Dq=Pq53vtqyB+1~`qB-cih``-eNY8~6)LQ1B}0ls zbTt`Ow9G+73SKL(2oXK=T?4@Pf#@^&mF2zw2>NH2vVq4@{QBxR8%p> zwnRa3fhvs3YE^@T3N9Wf^gvV*z8FFk<{fzBsKT>(;ZVi@P@)PCV~qQ5Ko#FG9aUH? zf&iSx%oj^tLve>h6`*l!mYfz}p$b@W$|GzQ76J~7glrYFrLAH~hLyUqVdG11fEykWc8(T%K{G+MtK>r*zlJ1KYmN?= z0vngM2^oj;AFOZWkqjBpAPvTn^9{HHR^2lJMXaXqD^qPI7_K}nRIR%Mr>^Dre3F7q z!wD#&s?Po>LIYhP2%>Pxj2ZT|z2EUDILOi;&#KCs-wj3FlUcv@mr! z8ENmIn1bT?S{_4$G-{Q=XUsS2iI$3QhN!8IAB>PzWd?zof>k1}k&@vDY$R@#=!m8) z-;3q=Q6s0Q_-ObcJ`g`NtL;uf?dix8rt+OZp*-6j#5L5`%9uLx6b5z7sdAEEf%g7% zlVih-mwrB0u*M@%%Xw@XxC;7a2GMwdjpAy-AIHnu=>okV14=hQ3$j}?agV+aMa&sT(P zMAPoO-aTrC*QcAK-+x@ATT;IU2v5h6mlj1)t6VHJ?RVT(o|JcA=Rbi zj_TRE>-|2YH0pY9q*SY-lM*EfB&sCJk?ziB7BmTd*JSSyYk9cm8oZJ*?7o9ZT~O9C zWKeX+k$7I6$T}i2JQf|K)QC)8jN=PPA-0NJ^I6JK`7CuS7ztqw6p68?Tf%!ZbB0&3 zEwV+$Jek?f)~lE&Gf9tLCnd>98%`a3T@{IOwv2hwBSh_z(f;@s9%*Ae#5`fGK`~F3 zSj7P66KWlcBV|9_>zJM1;%tOyj7th?Xi-SYSRd>`qZB@|*d;}v4|cYRhH;!d8*%i_ zL6s#Oi6Yjh8~LV|JcK!+-4^C#R$)#!$efTR3c*;kVAjK&^i-q>V4j{Kr+KYE(5V*Y z1PE_oP8Owru$cN_x_BR9P7>l~GWSPAohmiVe3>4cDO`j;#syp9y< zq&YDfW3wKOQ9s6`F>dZ3im`Z2j1!#yUeGvh_KqStP(GeGVRw8I;U}E+gLzgrb_!(r4nzP4THVapQPnIf zgDDy*6u}e=I|BqFL_K6Y5ycoFgTWKum_~~VL+pSd1+{Lxuv(bMvmv%xFo6jW%=}Yq z**vc4rhu;>Th143xx_S?<^)5BWjuu8_X#O6is31@>YBpPQMf(_$W=FV3=zT*hJWG7 zz^0%q5h$Lu@vk*7sFLWV!Czu*oC6tHY--JFitnuw|o>@0MHp^7E5W)C6pQqhJY)}oyT zAf?OH8LM)Q_dqj&q-zu{8ZhgKSxzgj4I4&ys8O1SS#)$P{|bbvsT{2kX0cPL9PIIj z1$$AZo>-*An#xf@epc9YW)Rk&@h@EE=meERVRIE}oE}2dYHOa}qj|_74yqdpvq-;z zqoqRl<9UTyG*zMHN=FrDQIkY|PEtDRYRbgw)tpzRR(%VM<5Q zhNdeW=$J*^cdHXs(_D6?gQ}R)VY0?zD@w7r4?=+Rj>T70+{GMg0e&*78!cd*6zR~E zj+Xk#vX+u)qd=rZNc!jz7CFm>ni0odN=F0eXHnogmC~Wg)s>DoNcg3rDjl(uj%O2I zvA=(8#p3m7V8xe$zen~zA`lXr@(@Y~$2?39`#u&@@y3;odf0a>7s?w|I%+ZBEuJD% z5bkt{c#5WUph^d&qw+lgC$r1>pD#~z_F-k zi)|Gn&BRcJK9i=A&Fbs@3+A)1P~*N`jbv4dNeH#5#S;nJQUt9EKl#l)&IB-9J5azLVTU$1olog3mP66BzYqo}A-409l!@WNIR*5UKufS`L6&NXH} zWVhsydoIO57R54{<+yI(sq~s@Dy+(X__x3K*Ps00yFUIWks@DM=HsiVmX#|PVT<}c z%Ef4SDnwkZ<5?ikdR=XSU>%EJeJH6lw(_85daSxy?*$1|%kfA<*%TE85Lqq|n2yPt z0-u#z*T#pkT#GK1i_sw+iWOz6qQyYY)4}=BtS0K=(5yD+r#cs5mg;M<2w5zgC}eM6 zV=by}@lVF-qHv)aS$`KI%xlivGd2uii$L*BK`&x<=Kh_mdcj6J>vHA>*My~|8HG-% z6Oe&6&hVM$(Osh>sh~&jz4CRbqp_8e#>VxBimeP0#28x{p+(mmO2_`^f)+=0g?(s| zq&O2l01B?nkJ?-VIO=!+FkGRJig3o4Oo!%@!XL^)=i9gOGtm;0Q-y~^QCV6au5*Nt- zTXfM`O4{3m^0bhzf$v)vTNix@_WR4m$f1A90<_JzM#;JyY8HC~E%^1b#a9D{sh;MR zUE1Bj0=)0<)> ziH2+mDW!&_97A<_JQ{&e-q9F$M<5g=T#8?<`g?pC9jQYM4j&sRAi$`7oY`8HGuusv zQNsqi2ud4qW*b5+2g4{9P+3l_TX-Mttr*<6S@zwb3hf7@tSaNOcV$@SRvnNv3m640 z;H1W`PVKULO^>bg@YyK%yvrJr|Iw$S;PVb0D^GBi@~qgC=k7SG<&GHp;H(L!lW^uSqiA#8aF$BJ z5ksY5RU)XnO|o_-7t3s9#eC7a#_Vo2YgjGEBj79xvc!4K>ILHAh|kWZGn&64{F2@P z3t>)H6^v4CS@q4bWssR6=b9Q>CVa&x!)<9oPbFV zs4bj;Gx~)aS~r5B6>uX%>mu?iCknFsI^58z%1YliGhguTSWL*w?4YGn!zwlc0NA1% zS_{txOb7yL>|2+i^}y=F4`V!L#SHnTmOL0*X}K9%=jGk829WRrHj6gQ*StIAWYM8- z$O&5yofQnN#Q~e3T%EyzcgNa&GPHJ57G`Hhy*uRjkz0Mlt7BTgINd@zGqi3{$qmc8 z9EAr>BATJKIO~+}t7c`CGuAL@VdH_`iY{hoUAZq9T5qWgt&4nBH?%H?*|2t0L+k8B z?+#)SS7&YN$GCULV1Mt9;x&d=c;XA{-C^aw=)60ugWxv@d3Ow^8CstM?~d7;cZZb= z<&7FzXD51h48{-FTpjZ6ST%JdnK6{_98Hs&ps6~mF|g9 zT=MyQqE#;7A?yctH+8J_oI&i*$EaF!`4?FDQ1BId%Ae22SNgx(Jhnrmnaj!C&g|tk zBPr+l31#e(-InX+C4kWm^Mu+UW< zh~kGP9qkGO#$-PdvN(9LcQ{ggWaS6MbTni^dnN%{V#J#pWKD{PfvlB$rmA?ZCHC~>L&(#7Qe16T;z~sc zJ^`kp`~@mX$NWqXmlH52)MFL70TrcctNWSMkma*fQEE9ppW~`IHAzLOs4ynx=rzmMN}rK$VFIq2L0YP#z;=oMvS5i$U$H!W1;Lp9;e=Gf<>bVeFeBLYl0? zfB=K8+sP{`l7pY|n<*+xjhH$|V>A?YfC^KM!*i#?_#7?O)8~TGOjTjV7>%OONQJ>3 z8EC1-XX-r0jBC+Bn#{05tvKCl3LOx-wWio??WfoPJD!QZC%p(A+*HM8Fs#_D;TJlr z*r>7;I;7aFjVm_u&%0uCOR3ltZKx|Y^C&j+nJHUT&9o15TSvz-50YC-#pafM6q~h4 zip_w|FvVsOC1ugFt|>Nc3O>4GgTjooOBPMBX%~vkpi*pzUpl1N%!N5}%k!q#Z0)bu z6t7=WZ1Vqp=3)TL(Y4|xO00tpq1bG_K#Gl(duYXGYh1CJA5v`mw1NE;n~nTGeJZ*$ zitdf2%v@W$H(ue2(EIw)X0+P$+-Wm}2)r?E2AK4cHdE>h4xC~Z688I_-j5k>4>Zh= zfs7ZsHd9}4`IU0P3_{(ZC=e0*$yr{FX%GHoU-$aM0G zioV{p8DYy#X*1ALt!jl9A`8{C*Jj`fFIH`4ZcLkL9Y&kcq17yjJdevX z`)e}?Ez>+_+Dz-&YBT6rL7QnELYpB_qW&c>X*2&QeNFP}`<`ij5C8pb3{ld&StfeX zEz^A6Ycu$?-~WvL?>{~BcZohBf3W?unXpW=k$-A@g$B|0^`p}ecl|lkX^7T(V>%52 z?j@b(C7tG=6`Chr+$%H^_%)pNTtLXfue>Qd;?34+uz>HQ)37)2#jMkmD>M}qeZA{6 zikA8u6XX$AXo%@l(`lfkTGa|&OwX2*+FrbeiT%I?a9m=lgo!bzlD_o#sCDxmd@o=l6Zhm5OJg?@4n09TZro?s|5^ zD>So1I*o5v+E1t1$Ui+{g$AMbH$a=gns6A8vkm!*+>k!QhMlP%XB+Hl9@S?yOh4fm z=EHcLZ75FDOZv=FoLkg^Y3xS))x6HnaA0+wQxlCi*kuZP7yVT_5!Oj;KiGy z&TP2D*@l8bPgQ3&*fTz+&P?Ai(|2bmorj0>DXzD03Z=H7F&@(hC!&!ZGw^ahS1;_C zv2PCHZpNkxTuntqoaR%I(6BDkAKhQ&6>`_b=fSPDf73V2D01_2OpQm-WpE-bbr~b1 zP_^KiSbDTR+x3|Z?G+u@W!5HnoAnj1h;1~B&)VCpkB%{Y8_iw^jd5=?khpZ2{`0quW|M<3eH%^DhNF0!ZI<3W*|=xkX3avES**OxHYl{djiwPe_U7~EZML?*w^{M}C2zAS-e%T8 zhwwIAdx5;otXwGXaNB6s#=XsEhIARuD?ZHnOb-XMx2-XW?uokG&iV$LYioOvx%I!; z_Rmq%jsbYNwD?^ zhd{H1b3w5Sx@0$-+>)<7awWS(JBsvk#(q-DfS)|=(*w6812uo9Ya5w1E+-qI9UE%L z1{;|+46tZd3zC%fWDWWbKB+UU*9h{hv(>a`JBxjTi&_&Uak>2oO0w-wNz5jwB+6oT zN7F+}CZB#Nh1B$gUL(7`pvG$~m87-u^_MmT{d3Vm|K$t?p&1CbVXXtzsi$%Nw!ZEg z07FJlOJZ+RM-`?GlvWs@5sY6QAZK$n8PU7C3`nJCgCZGY!%hGVkp)n)ol?Zd6MBnRLL&+y3z$J4cD@v-l5oeX>oC79?8qmWzF^RqUF)?YNN977)X7|v=8>1Z1rz94WHRA$}A zr-@!OGIm@OWvJ%-=%#?O+G`yyzNI;{6=-csw6?WtL4f8|C7}8_+bowr=SFN^)J$0; z(TNj`YQ&Cxs}VDMK%*^i+92W6WJZbD&BRtUhN(x47UjgUsC6gG*k>=z^m*CU9=5uS?mcTI>mg)DeOJ3ZrQ)>YXnW6Yd{;X~`%wc&38Nry zP1~l9>!-tW=$Emmsw4L)MNgQ?|A=@QF$&+ekVMeiRX_Dh$Rp-lfF^-j{AcY1`EMfc z4NZkOfA5zp=0lu+|Cdnj`)})Y@770(sH1w+KDwKa)~0>*jZ;4Q#{E8e#gva;vEN58 z*GJH-cN25U!fDCWUWHj>RS#MwI2c5UB1=p!y@PNRGEeb9A#rV%)IKA{=YyW@813Lf z*i@Lcr=R$~zy9RE_;xsLUdnUC*k;pCd95xx}r z38L)6<3KPL)2ph~c%U`W&v>9U6PJm{868+0sf>Wb1u6bvIIapv!s#nfs&H!5v!rbr9f1jZ`MUkl{*!TQXGi8ejs6<(B<5 z0o@kiBFU2(?H;h{rA_Lw!lzj&obVu^Ld~rrB!M{YmNG!Nvc1Of{u51IACKvGuJ4SQ zfdFKF!X$c?s^CyoMLMA7lMM-V7?Mv%|MxUoju(kWNt*ge9thcO-oTAU15I1t9pt4AQeMQ zKtJJHE&H^a;AT6L7SQTx6H80n98Wu#koHWG_Kc<7Ez<6eq@|+g(r=}S7tu&UwV<{v zl)jLB>)nlW@aI`Ql+Gc^PEGe37hc)8Al*Y>iZ)E-dk!71`a=FB{Z{7s34VlZm7jhN zWq9e8jZ2oHzM7n4Gnq9=uR#F!Gi(ElXk6Bq(;AWmrY^WteckXw7a=;;jEXuf*!VyK zj3F^PA|}DGZV*d15M?EeFjWfjD$Z-wB%jGdG9;9!RM0C$IuvpbAgAO`%wLl8|AHrEKSyChDq-up`62uO ztY*fsM|Co0vxYr*s)~yvjw25aqqMGdidIPH&@NhKb3ilTS!0hGscz~ylju~c9%*Gozb3$5_A-f#{ zElh|055`l7yZ^YDl1Y5Ysh4B80eI9@=u}ayz0K61)Vw4EClfNa>BWTHX@{PLFm!1a> zD;Bgi8IN6ClLx0^UKju;%Y)mdP?P96soO&t8JX&_JDPqD$adwRS=?3WYkkoyYVM!p5kh z{HQTFCQ+=98ihHjQJIrA^^p_}@y7C_c!1ATqWMC_$8AvS3sZ+wDhCXRu}bc69(1et z=CTVyF5*F4oClrI?Jy5oet~(A%CGUDabEFp=Av=t;^TZ$w~X_{ z72sKUfyY_p*T#8eXq-=maUOfhIMb5-#(Cu?jq^y+wQ;sLhZ*OUa-6+V2aWSe^2#vI zD@hi{Ipm>nj*^GZ1N6bi0_%}0YfZ;*6`e>{X&dCCsy(eY940cxEGw_SG*n3+qHkMu7=;TLuz z6xTvFe?48&qcagk8DZ=tzmO*A*W6J7njxCCAE($;Hatsg=2N=rUPclF7*1X=M&*Sgp+CLuKxInOv;QJFQH$^3Jlv zOBiTq+gK~X&6fY}aQ=H`{-N)0Z=5@it$Zw1#$9?GKBTI9RMm!PG#R~r{)!rN zUVkodiU3bA4(QkY`f~}pnB*=P9jPc|5n|uObW5I+O}5Q?kx5_{SdAv9f=%eDkEeF&dK^u-DjK zZbk!wUeD!EgH-XGV1+Y&?6q0#itIB-LGurEG{9HZ*Y z3i59W{=TyD9udDD)xfa(8j9ihx{fvEy)=m9BAV}yse&CKJeSi8AB<(`3b)E0GOj^w z%U+La**EMw6}o+&>|4r{Q6zgmHMD56bpP;1rJ3f6Plq>yZZtH1m=c(G)-E~)RKHN` zOD*tCQ!Az-U`awZ3Tx%*SrHO6IhAH_h{kA7MPa6!E&N0?o_!2kf1fp_$p*|3iQkkx zkMnvHg8^hGyS8%8TA0f7&qR-=Gte^3#RPKxi9h+!0NiJD7KSC3Vv2<^uZT%6n)?hB z8Me}3<|rqqSNXQYitEDO=EzL{F=sE$%Skg#i>9VU)7WtE@`=gws#epI;F4qI1@7{h zAQQM!76)oeHHW#0S-_c%5uY)a1mWm$yt+vF{D=Y?ONjprC2vl~{3hPnoU%UysKd~HAM&rJWb z$jwLyWv+Em{aPXu8F9Pd$B+TG%qj!k377DvA2I-LG>Z%Z%#fsI6`=rAoM2UDz&lJ~ z`g1&F0Cs>LyaoX^h&i#eP^@;CCz7EtnqWh}s|@x+2IsD%vqc8?I_!Yp@^f&m&;)3$ zs(}$BcmiL!kiiAQ;};pc#xua`mtVM&wL=DGn=NW!7QqW7xOkO8@jTSsm+oev!8-Tb zUfK9I-JNc{{_e)>A<8KKEXX6)-~NAXZiz@5m&aBDlIToC`LZs{JQRj_pTx9QiCHx{ zL}L0@iA75X=gdedF(ZG7#2{KFhVvXEF_2q{MbDucNwo0utw!sy#&`LWVr!ozMZq5X zHfvtZzfdeGHu69Hou^i{Y!FFjQ-7p$0x&YdxAOnMOC&(}0-K@WO@n{4EGahgfA!N} zoM%a~$&zBzGSZS_libTCMfed5XU2$l3T31G*l$Zkfih`v*h{gb825iWW*-c!>)}$qWVqSHN3)K zjiF^ey{s(>>L)YY=T|qG9ZQ=O86}eWn#`US54*9nXNt6EENwY&cVXL9B`Q8qMlAMu z1VD4_r!VF|!S&3tswd!1bo)S{7>C%s;Pg z_3FTmG(DTiJadx^i%gdci|7L{Fj9egjW@iq@dhMf!@d?#S!+BOcJ^v<3i<8Old(d* zW!esa=Ump(*hWq(hjf941co5iP3Fo6spdG>hOz&(JQehet!&3C8=6b_=Eb4!!Pj@g;@8(>!775?BE|?G)+%OTjD|?Mn`C)%*0@vi_ zP{&JR((%(J=BUUmB_@no77R(ua+ZQGBohjGWfF5#0;8TGuUI!KMLjz|rLOMG>XtVe`KJR~&EyUgHn z10rLx7m3(4Ov;&ODKaK|ktprB$ndnK$O!%%qzz*nP`V8va}(;8hX$8521^ps`K)

=CmY=QO7nIE0Lr-$pKFr8D4rv-A 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

Aj5NCr?1VBUdt!_ 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≺G+0Oc?N^uL%DSS)XLzHKIxW}VC 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 z Date: Sat, 15 Jun 2024 09:48:41 +0100 Subject: [PATCH 08/24] Refactor fetch_from_pdb.ts code for consistency String references were harmonized to single quotation marks (' ') for standardization purposes. This change particularly affects the import statement from 'detect-browser' and the browser name check condition for 'firefox'. --- webapp/src/utils/fetch_from_pdb.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webapp/src/utils/fetch_from_pdb.ts b/webapp/src/utils/fetch_from_pdb.ts index 37a4d3deb..ab4711e23 100644 --- a/webapp/src/utils/fetch_from_pdb.ts +++ b/webapp/src/utils/fetch_from_pdb.ts @@ -1,4 +1,4 @@ -import { detect } from "detect-browser" +import { detect } from 'detect-browser'; async function fetchPDBFile(PDBCode: string): Promise { console.warn( @@ -32,7 +32,7 @@ export async function fetchPDB(PDBCode: string): Promise { // FIXME const browser = detect(); // FireFox doesn't work with CIF files, get the PDB. - if (browser.name === "firefox") { + if (browser.name === 'firefox') { try { return await fetchPDBFile(PDBCode); } catch (e) { From fe63ffe73f51e866d73817798945db387d092e02 Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Sun, 16 Jun 2024 11:38:20 +0100 Subject: [PATCH 09/24] Update fetchPDB and fetchPDBFile return types The return types for both fetchPDB and fetchPDBFile methods have been updated. These functions now return a tuple including the file content and its filename extension instead of just the text. This change provides more detailed information about the fetched files. --- webapp/src/utils/fetch_from_pdb.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/webapp/src/utils/fetch_from_pdb.ts b/webapp/src/utils/fetch_from_pdb.ts index ab4711e23..c5ba364aa 100644 --- a/webapp/src/utils/fetch_from_pdb.ts +++ b/webapp/src/utils/fetch_from_pdb.ts @@ -1,6 +1,6 @@ import { detect } from 'detect-browser'; -async function fetchPDBFile(PDBCode: string): Promise { +async function fetchPDBFile(PDBCode: string): Promise<[string] | void> { console.warn( 'The CIF file for this PDB could not be found, trying for the PDB' ); @@ -14,7 +14,7 @@ async function fetchPDBFile(PDBCode: string): Promise { return await response.text(); }) .then(async (file) => { - return file; + return [file, '.pdb']; }) .catch(async (error) => { return await Promise.reject(error); @@ -22,7 +22,7 @@ async function fetchPDBFile(PDBCode: string): Promise { return await file; } -export async function fetchPDB(PDBCode: string): Promise { +export async function fetchPDB(PDBCode: string): Promise<[string] | void> { if (PDBCode == null) { return; } @@ -48,7 +48,7 @@ export async function fetchPDB(PDBCode: string): Promise { return await response.text(); }) .then(async (file) => { - return file; + return [file, '.cif']; }) .catch(async () => { // if we can't find the cif, try the PDB, if that fails, then report the failure. From 19ae586f6dea4d39a8174b77a675e799b368c39d Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Sun, 16 Jun 2024 11:38:39 +0100 Subject: [PATCH 10/24] Add browser detection and CIF file handling for Firefox A 'detect-browser' package has been imported to check the kind of browser the user is employing. Introduced handling for CIF files which are currently unsupported on Firefox. New logic is now in place to handle the behavior for Firefox users to guide them to use an alternate browser. --- webapp/src/routes/Home/Home.tsx | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/webapp/src/routes/Home/Home.tsx b/webapp/src/routes/Home/Home.tsx index cc2a2caed..9fe65edcd 100644 --- a/webapp/src/routes/Home/Home.tsx +++ b/webapp/src/routes/Home/Home.tsx @@ -13,6 +13,7 @@ import { type ResultsEntry, type TorsionEntry, } from '../../interfaces/types'; +import { detect } from 'detect-browser'; const Footer = lazy(async () => await import('../../layouts/Footer.tsx')); const BorderElement = lazy( @@ -50,7 +51,21 @@ export default function Home(): Element { } setFileContent(fileContent); - const results = Module.validate(fileContent, name); + const splitFileName = name.split('.'); + const fileExtension = splitFileName[splitFileName.length - 1]; + const newFileName = '/coordinates.' + fileExtension; + Module.FS.writeFile(newFileName, fileContent); + + const browser = detect(); // FireFox doesn't work with CIF files, get the PDB. + if (browser.name === 'firefox' && fileExtension === 'cif') { + setFailureText( + 'CIF files are currently unsupported on FireFox. Please consider an alternate browser.' + ); + setFallBack(true); + return; + } + + const results = Module.validate(newFileName, name); const data: ResultsEntry[] = []; const resultSize = results.size(); for (let i = 0; i < resultSize; i++) { @@ -116,13 +131,21 @@ export default function Home(): Element { } fetchPDB(PDBCode) - .then((response: ArrayBuffer) => { - setFileContent(response); + .then((response: [string] | void) => { + // @ts-expect-error + const [fileContent, fileExtension]: [string, string] = + response; + setFileContent(fileContent); setLoadingText('Validating Glycans...'); + const fileName = PDBCode + fileExtension; privateer_module().then( async (Module: any) => { - await runPrivateer(Module, response, PDBCode); + await runPrivateer( + Module, + fileContent, + fileName + ); }, () => {} ); From 7715978d08c1a97dacda71814ffcdb87bb5a9038 Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Sun, 16 Jun 2024 11:38:54 +0100 Subject: [PATCH 11/24] Refactor molecule reading function in privateer-bind.cpp The function 'read_molecule' in privateer-bind.cpp has been refactored for simplicity and efficiency. It now uses a direct file read operation instead of converting the file content to a character array first. The function also now checks if the molecule's spacegroup is null and performs initialization if required. --- src/privateer/cpp/privateer-bind.cpp | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/src/privateer/cpp/privateer-bind.cpp b/src/privateer/cpp/privateer-bind.cpp index 615f2d9dc..c0643f98e 100644 --- a/src/privateer/cpp/privateer-bind.cpp +++ b/src/privateer/cpp/privateer-bind.cpp @@ -42,34 +42,23 @@ struct ResultsEntry clipper::MiniMol read_molecule(const std::string &file, const std::string &name) { - char *c_data = (char *)file.c_str(); - size_t size = file.length(); - if (size == 0) - { - std::cout << "[Privateer] The supplied file has no content, returning with nothing." << std::endl; - return {}; - } - ::gemmi::Structure structure = ::gemmi::read_structure_from_char_array(c_data, size, name); - std::cout << "[Privateer] Successfully read structure" << std::endl; - - if (structure.spacegroup_hm == "") { - std::cout << "[Privateer] This structure has no spacegroup specified, setting to P1." << std::endl; - structure.spacegroup_hm = "P 1"; - } - - clipper::GEMMIfile gemmi_file; - clipper::GemmiStructure gemmi_structure(structure); - gemmi_file.set_gemmi_structure(gemmi_structure); clipper::MiniMol mol; + clipper::GEMMIfile gemmi_file; + gemmi_file.read_file(file); gemmi_file.import_minimol(mol); + if (mol.spacegroup().is_null()) { + std::cout << "[Privateer] This structure has no spacegroup specified, setting to P1." << std::endl; + mol.init(clipper::Spacegroup::p1(), mol.cell()); + } + clipper::Cell cell = mol.cell(); if (cell.a() == 1.0 && cell.b() == 1.0 && cell.c() == 1.0 ) { std::cout << "[Privateer] This cell is 1A, inflating the cell but this will lose crystal contact information" << std::endl; mol.init ( clipper::Spacegroup::p1(), clipper::Cell(clipper::Cell_descr ( 300, 300, 300, 90, 90, 90 )) ); } - std::cout << "[Privateer] Created gemmi molecule" << std::endl; + std::cout << "[Privateer] Created molecule" << std::endl; return mol; } From af5808c652f2c0e6a8f71e66481e396f604365f8 Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Sun, 16 Jun 2024 11:39:08 +0100 Subject: [PATCH 12/24] Added WASM and JS blobs --- webapp/src/wasm/privateer.js | 8370 +++++++++++++++++++++++++++++++- webapp/src/wasm/privateer.wasm | Bin 1948826 -> 1978727 bytes 2 files changed, 8358 insertions(+), 12 deletions(-) diff --git a/webapp/src/wasm/privateer.js b/webapp/src/wasm/privateer.js index 2b1ac16bd..301dc9e90 100644 --- a/webapp/src/wasm/privateer.js +++ b/webapp/src/wasm/privateer.js @@ -1,16 +1,8362 @@ - var privateer_module = (() => { - var _scriptDir = import.meta.url; - - return ( -async function(moduleArg = {}) { - -var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject}));["_main","getExceptionMessage","___get_exception_message","_free","___cpp_exception","___cxa_increment_exception_refcount","___cxa_decrement_exception_refcount","___thrown_object_from_unwind_exception","_fflush","__embind_initialize_bindings","___set_stack_limits","onRuntimeInitialized"].forEach((prop=>{if(!Object.getOwnPropertyDescriptor(Module["ready"],prop)){Object.defineProperty(Module["ready"],prop,{get:()=>abort("You are getting "+prop+" on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js"),set:()=>abort("You are setting "+prop+" on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")})}}));if(!Module.expectedDataFileDownloads){Module.expectedDataFileDownloads=0}Module.expectedDataFileDownloads++;(function(){if(Module["ENVIRONMENT_IS_PTHREAD"]||Module["$ww"])return;var loadPackage=function(metadata){var PACKAGE_PATH="";if(typeof window==="object"){PACKAGE_PATH=window["encodeURIComponent"](window.location.pathname.toString().substring(0,window.location.pathname.toString().lastIndexOf("/"))+"/")}else if(typeof process==="undefined"&&typeof location!=="undefined"){PACKAGE_PATH=encodeURIComponent(location.pathname.toString().substring(0,location.pathname.toString().lastIndexOf("/"))+"/")}var PACKAGE_NAME="privateer.data";var REMOTE_PACKAGE_BASE="privateer.data";if(typeof Module["locateFilePackage"]==="function"&&!Module["locateFile"]){Module["locateFile"]=Module["locateFilePackage"];err("warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)")}var REMOTE_PACKAGE_NAME=Module["locateFile"]?Module["locateFile"](REMOTE_PACKAGE_BASE,""):REMOTE_PACKAGE_BASE;var REMOTE_PACKAGE_SIZE=metadata["remote_package_size"];function fetchRemotePackage(packageName,packageSize,callback,errback){if(typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string"){require("fs").readFile(packageName,(function(err,contents){if(err){errback(err)}else{callback(contents.buffer)}}));return}var xhr=new XMLHttpRequest;xhr.open("GET",packageName,true);xhr.responseType="arraybuffer";xhr.onprogress=function(event){var url=packageName;var size=packageSize;if(event.total)size=event.total;if(event.loaded){if(!xhr.addedTotal){xhr.addedTotal=true;if(!Module.dataFileDownloads)Module.dataFileDownloads={};Module.dataFileDownloads[url]={loaded:event.loaded,total:size}}else{Module.dataFileDownloads[url].loaded=event.loaded}var total=0;var loaded=0;var num=0;for(var download in Module.dataFileDownloads){var data=Module.dataFileDownloads[download];total+=data.total;loaded+=data.loaded;num++}total=Math.ceil(total*Module.expectedDataFileDownloads/num);if(Module["setStatus"])Module["setStatus"](`Downloading data... (${loaded}/${total})`)}else if(!Module.dataFileDownloads){if(Module["setStatus"])Module["setStatus"]("Downloading data...")}};xhr.onerror=function(event){throw new Error("NetworkError for: "+packageName)};xhr.onload=function(event){if(xhr.status==200||xhr.status==304||xhr.status==206||xhr.status==0&&xhr.response){var packageData=xhr.response;callback(packageData)}else{throw new Error(xhr.statusText+" : "+xhr.responseURL)}};xhr.send(null)}function handleError(error){console.error("package error:",error)}var fetchedCallback=null;var fetched=Module["getPreloadedPackage"]?Module["getPreloadedPackage"](REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE):null;if(!fetched)fetchRemotePackage(REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE,(function(data){if(fetchedCallback){fetchedCallback(data);fetchedCallback=null}else{fetched=data}}),handleError);function runWithFS(){function assert(check,msg){if(!check)throw msg+(new Error).stack}Module["FS_createPath"]("/","unprocessed_files",true,true);function DataRequest(start,end,audio){this.start=start;this.end=end;this.audio=audio}DataRequest.prototype={requests:{},open:function(mode,name){this.name=name;this.requests[name]=this;Module["addRunDependency"](`fp ${this.name}`)},send:function(){},onload:function(){var byteArray=this.byteArray.subarray(this.start,this.end);this.finish(byteArray)},finish:function(byteArray){var that=this;Module["FS_createDataFile"](this.name,null,byteArray,true,true,true);Module["removeRunDependency"](`fp ${that.name}`);this.requests[this.name]=null}};var files=metadata["files"];for(var i=0;i{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";var ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(Module["ENVIRONMENT"]){throw new Error("Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)")}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_NODE){if(typeof process=="undefined"||!process.release||process.release.name!=="node")throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");var nodeVersion=process.versions.node;var numericVersion=nodeVersion.split(".").slice(0,3);numericVersion=numericVersion[0]*1e4+numericVersion[1]*100+numericVersion[2].split("-")[0]*1;if(numericVersion<16e4){throw new Error("This emscripten-generated code requires node v16.0.0 (detected v"+nodeVersion+")")}const{createRequire:createRequire}=await import("module");var require=createRequire(import.meta.url);var fs=require("fs");var nodePath=require("path");if(ENVIRONMENT_IS_WORKER){scriptDirectory=nodePath.dirname(scriptDirectory)+"/"}else{scriptDirectory=require("url").fileURLToPath(new URL("./",import.meta.url))}read_=(filename,binary)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);return fs.readFileSync(filename,binary?undefined:"utf8")};readBinary=filename=>{var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};readAsync=(filename,onload,onerror,binary=true)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);fs.readFile(filename,binary?undefined:"utf8",((err,data)=>{if(err)onerror(err);else onload(binary?data.buffer:data)}))};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow};Module["inspect"]=()=>"[Emscripten Module object]"}else if(ENVIRONMENT_IS_SHELL){if(typeof process=="object"&&typeof require==="function"||typeof window=="object"||typeof importScripts=="function")throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");if(typeof read!="undefined"){read_=f=>read(f)}readBinary=f=>{let data;if(typeof readbuffer=="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data=="object");return data};readAsync=(f,onload,onerror)=>{setTimeout((()=>onload(readBinary(f))))};if(typeof clearTimeout=="undefined"){globalThis.clearTimeout=id=>{}}if(typeof setTimeout=="undefined"){globalThis.setTimeout=f=>typeof f=="function"?f():abort()}if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit=="function"){quit_=(status,toThrow)=>{setTimeout((()=>{if(!(toThrow instanceof ExitStatus)){let toLog=toThrow;if(toThrow&&typeof toThrow=="object"&&toThrow.stack){toLog=[toThrow,toThrow.stack]}err(`exiting due to exception: ${toLog}`)}quit(status)}));throw toThrow}}if(typeof print!="undefined"){if(typeof console=="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}if(!(typeof window=="object"||typeof importScripts=="function"))throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=title=>document.title=title}else{throw new Error("environment detection error")}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;checkIncomingModuleAPI();if(Module["arguments"])arguments_=Module["arguments"];legacyModuleProp("arguments","arguments_");if(Module["thisProgram"])thisProgram=Module["thisProgram"];legacyModuleProp("thisProgram","thisProgram");if(Module["quit"])quit_=Module["quit"];legacyModuleProp("quit","quit_");assert(typeof Module["memoryInitializerPrefixURL"]=="undefined","Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["pthreadMainPrefixURL"]=="undefined","Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["cdInitializerPrefixURL"]=="undefined","Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["filePackagePrefixURL"]=="undefined","Module.filePackagePrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["read"]=="undefined","Module.read option was removed (modify read_ in JS)");assert(typeof Module["readAsync"]=="undefined","Module.readAsync option was removed (modify readAsync in JS)");assert(typeof Module["readBinary"]=="undefined","Module.readBinary option was removed (modify readBinary in JS)");assert(typeof Module["setWindowTitle"]=="undefined","Module.setWindowTitle option was removed (modify setWindowTitle in JS)");assert(typeof Module["TOTAL_MEMORY"]=="undefined","Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY");legacyModuleProp("read","read_");legacyModuleProp("readAsync","readAsync");legacyModuleProp("readBinary","readBinary");legacyModuleProp("setWindowTitle","setWindowTitle");assert(!ENVIRONMENT_IS_SHELL,"shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable.");var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];legacyModuleProp("wasmBinary","wasmBinary");var noExitRuntime=Module["noExitRuntime"]||false;legacyModuleProp("noExitRuntime","noExitRuntime");if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed"+(text?": "+text:""))}}var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b)}assert(!Module["STACK_SIZE"],"STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time");assert(typeof Int32Array!="undefined"&&typeof Float64Array!=="undefined"&&Int32Array.prototype.subarray!=undefined&&Int32Array.prototype.set!=undefined,"JS engine does not provide full typed array support");assert(!Module["wasmMemory"],"Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally");assert(!Module["INITIAL_MEMORY"],"Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically");var wasmTable;function writeStackCookie(){var max=_emscripten_stack_get_end();assert((max&3)==0);if(max==0){max+=4}HEAPU32[max>>2]=34821223;checkInt32(34821223);HEAPU32[max+4>>2]=2310721022;checkInt32(2310721022);HEAPU32[0>>2]=1668509029;checkInt32(1668509029)}function checkStackCookie(){if(ABORT)return;var max=_emscripten_stack_get_end();if(max==0){max+=4}var cookie1=HEAPU32[max>>2];var cookie2=HEAPU32[max+4>>2];if(cookie1!=34821223||cookie2!=2310721022){abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString(cookie2)} ${ptrToString(cookie1)}`)}if(HEAPU32[0>>2]!=1668509029){abort("Runtime error: The application has corrupted its heap memory area (address zero)!")}}(function(){var h16=new Int16Array(1);var h8=new Int8Array(h16.buffer);h16[0]=25459;if(h8[0]!==115||h8[1]!==99)throw"Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)"})();var __ATPRERUN__=[];var __ATINIT__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;var runtimeKeepaliveCounter=0;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){assert(!runtimeInitialized);runtimeInitialized=true;checkStackCookie();setStackLimits();if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();FS.ignorePermissions=false;TTY.init();callRuntimeCallbacks(__ATINIT__)}function postRun(){checkStackCookie();if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}assert(Math.imul,"This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.fround,"This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.clz32,"This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.trunc,"This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;var runDependencyTracking={};function getUniqueRunDependency(id){var orig=id;while(1){if(!runDependencyTracking[id])return id;id=orig+Math.random()}}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(!runDependencyTracking[id]);runDependencyTracking[id]=1;if(runDependencyWatcher===null&&typeof setInterval!="undefined"){runDependencyWatcher=setInterval((()=>{if(ABORT){clearInterval(runDependencyWatcher);runDependencyWatcher=null;return}var shown=false;for(var dep in runDependencyTracking){if(!shown){shown=true;err("still waiting on run dependencies:")}err("dependency: "+dep)}if(shown){err("(end of list)")}}),1e4)}}else{err("warning: run dependency added without ID")}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(runDependencyTracking[id]);delete runDependencyTracking[id]}else{err("warning: run dependency removed without ID")}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;if(runtimeInitialized){___trap()}var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}function isFileURI(filename){return filename.startsWith("file://")}function createExportWrapper(name,fixedasm){return function(){var displayName=name;var asm=fixedasm;if(!fixedasm){asm=Module["asm"]}assert(runtimeInitialized,"native function `"+displayName+"` called before runtime initialization");assert(!runtimeExited,"native function `"+displayName+"` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)");if(!asm[name]){assert(asm[name],"exported native function `"+displayName+"` not found")}return asm[name].apply(null,arguments)}}var wasmBinaryFile;if(Module["locateFile"]){wasmBinaryFile="privateer.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}}else{wasmBinaryFile=new URL("privateer.wasm",import.meta.url).href}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}function getBinaryPromise(binaryFile){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"&&!isFileURI(binaryFile)){return fetch(binaryFile,{credentials:"same-origin"}).then((response=>{if(!response["ok"]){throw"failed to load wasm binary file at '"+binaryFile+"'"}return response["arrayBuffer"]()})).catch((()=>getBinarySync(binaryFile)))}else if(readAsync){return new Promise(((resolve,reject)=>{readAsync(binaryFile,(response=>resolve(new Uint8Array(response))),reject)}))}}return Promise.resolve().then((()=>getBinarySync(binaryFile)))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then((binary=>WebAssembly.instantiate(binary,imports))).then((instance=>instance)).then(receiver,(reason=>{err("failed to asynchronously prepare wasm: "+reason);if(isFileURI(wasmBinaryFile)){err("warning: Loading from a file URI ("+wasmBinaryFile+") is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing")}abort(reason)}))}function instantiateAsync(binary,binaryFile,imports,callback){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then((response=>{var result=WebAssembly.instantiateStreaming(response,imports);return result.then(callback,(function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(binaryFile,imports,callback)}))}))}return instantiateArrayBuffer(binaryFile,imports,callback)}function createWasm(){var info={"env":wasmImports,"wasi_snapshot_preview1":wasmImports};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["memory"];assert(wasmMemory,"memory not found in wasm exports");updateMemoryViews();wasmTable=Module["asm"]["__indirect_function_table"];assert(wasmTable,"table not found in wasm exports");addOnInit(Module["asm"]["__wasm_call_ctors"]);removeRunDependency("wasm-instantiate");return exports}addRunDependency("wasm-instantiate");var trueModule=Module;function receiveInstantiationResult(result){assert(Module===trueModule,"the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?");trueModule=null;receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err("Module.instantiateWasm callback failed with error: "+e);readyPromiseReject(e)}}instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult).catch(readyPromiseReject);return{}}var tempDouble;var tempI64;function legacyModuleProp(prop,newName){if(!Object.getOwnPropertyDescriptor(Module,prop)){Object.defineProperty(Module,prop,{configurable:true,get(){abort("Module."+prop+" has been replaced with plain "+newName+" (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}}function ignoredModuleProp(prop){if(Object.getOwnPropertyDescriptor(Module,prop)){abort("`Module."+prop+"` was supplied but `"+prop+"` not included in INCOMING_MODULE_JS_API")}}function isExportedByForceFilesystem(name){return name==="FS_createPath"||name==="FS_createDataFile"||name==="FS_createPreloadedFile"||name==="FS_unlink"||name==="addRunDependency"||name==="FS_createLazyFile"||name==="FS_createDevice"||name==="removeRunDependency"}function missingGlobal(sym,msg){if(typeof globalThis!=="undefined"){Object.defineProperty(globalThis,sym,{configurable:true,get(){warnOnce("`"+sym+"` is not longer defined by emscripten. "+msg);return undefined}})}}missingGlobal("buffer","Please use HEAP8.buffer or wasmMemory.buffer");function missingLibrarySymbol(sym){if(typeof globalThis!=="undefined"&&!Object.getOwnPropertyDescriptor(globalThis,sym)){Object.defineProperty(globalThis,sym,{configurable:true,get(){var msg="`"+sym+"` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line";var librarySymbol=sym;if(!librarySymbol.startsWith("_")){librarySymbol="$"+sym}msg+=" (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='"+librarySymbol+"')";if(isExportedByForceFilesystem(sym)){msg+=". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"}warnOnce(msg);return undefined}})}unexportedRuntimeSymbol(sym)}function unexportedRuntimeSymbol(sym){if(!Object.getOwnPropertyDescriptor(Module,sym)){Object.defineProperty(Module,sym,{configurable:true,get(){var msg="'"+sym+"' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)";if(isExportedByForceFilesystem(sym)){msg+=". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"}abort(msg)}})}}var MAX_UINT8=2**8-1;var MAX_UINT16=2**16-1;var MAX_UINT32=2**32-1;var MAX_UINT53=2**53-1;var MAX_UINT64=2**64-1;var MIN_INT8=-(2**(8-1))+1;var MIN_INT16=-(2**(16-1))+1;var MIN_INT32=-(2**(32-1))+1;var MIN_INT53=-(2**(53-1))+1;var MIN_INT64=-(2**(64-1))+1;function checkInt(value,bits,min,max){assert(Number.isInteger(Number(value)),"attempt to write non-integer ("+value+") into integer heap");assert(value<=max,"value ("+value+") too large to write as "+bits+"-bit value");assert(value>=min,"value ("+value+") too small to write as "+bits+"-bit value")}var checkInt8=value=>checkInt(value,8,MIN_INT8,MAX_UINT8);var checkInt16=value=>checkInt(value,16,MIN_INT16,MAX_UINT16);var checkInt32=value=>checkInt(value,32,MIN_INT32,MAX_UINT32);var checkInt64=value=>checkInt(value,64,MIN_INT64,MAX_UINT64);function ExitStatus(status){this.name="ExitStatus";this.message=`Program terminated with exit(${status})`;this.status=status}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};function getCppExceptionTag(){return Module["asm"]["__cpp_exception"]}function getCppExceptionThrownObjectFromWebAssemblyException(ex){var unwind_header=ex.getArg(getCppExceptionTag(),0);return ___thrown_object_from_unwind_exception(unwind_header)}var withStackSave=f=>{var stack=stackSave();var ret=f();stackRestore(stack);return ret};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):undefined;var UTF8ArrayToString=(heapOrArray,idx,maxBytesToRead)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>{assert(typeof ptr=="number");return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""};var getExceptionMessageCommon=ptr=>withStackSave((()=>{var type_addr_addr=stackAlloc(4);var message_addr_addr=stackAlloc(4);___get_exception_message(ptr,type_addr_addr,message_addr_addr);var type_addr=HEAPU32[type_addr_addr>>2];var message_addr=HEAPU32[message_addr_addr>>2];var type=UTF8ToString(type_addr);_free(type_addr);var message;if(message_addr){message=UTF8ToString(message_addr);_free(message_addr)}return[type,message]}));function getExceptionMessage(ex){var ptr=getCppExceptionThrownObjectFromWebAssemblyException(ex);return getExceptionMessageCommon(ptr)}Module["getExceptionMessage"]=getExceptionMessage;var ptrToString=ptr=>{assert(typeof ptr==="number");ptr>>>=0;return"0x"+ptr.toString(16).padStart(8,"0")};var setStackLimits=()=>{var stackLow=_emscripten_stack_get_base();var stackHigh=_emscripten_stack_get_end();___set_stack_limits(stackLow,stackHigh)};var warnOnce=text=>{if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;if(ENVIRONMENT_IS_NODE)text="warning: "+text;err(text)}};var ___assert_fail=(condition,filename,line,func)=>{abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"])};var ___handle_stack_overflow=requested=>{var base=_emscripten_stack_get_base();var end=_emscripten_stack_get_end();abort(`stack overflow (Attempt to set SP to ${ptrToString(requested)}`+`, with stack limits [${ptrToString(end)} - ${ptrToString(base)}`+"]). If you require more stack space build with -sSTACK_SIZE=")};var setErrNo=value=>{HEAP32[___errno_location()>>2]=value;checkInt32(value);return value};var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter((p=>!!p)),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:path=>{if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},join:function(){var paths=Array.prototype.slice.call(arguments);return PATH.normalize(paths.join("/"))},join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>{if(typeof crypto=="object"&&typeof crypto["getRandomValues"]=="function"){return view=>crypto.getRandomValues(view)}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");var randomFillSync=crypto_module["randomFillSync"];if(randomFillSync){return view=>crypto_module["randomFillSync"](view)}var randomBytes=crypto_module["randomBytes"];return view=>(view.set(randomBytes(view.byteLength)),view)}catch(e){}}abort("no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: (array) => { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };")};var randomFill=view=>(randomFill=initRandomFill())(view);var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter((p=>!!p)),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{assert(typeof str==="string");if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;if(u>1114111)warnOnce("Invalid Unicode code point "+ptrToString(u)+" encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).");heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx};function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc(BUFSIZE);var bytesRead=0;var fd=process.stdin.fd;try{bytesRead=fs.readSync(fd,buf,0,BUFSIZE,-1)}catch(e){if(e.toString().includes("EOF"))bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init:function(){},shutdown:function(){},register:function(dev,ops){TTY.ttys[dev]={input:[],output:[],ops:ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open:function(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close:function(stream){stream.tty.ops.fsync(stream.tty)},fsync:function(stream){stream.tty.ops.fsync(stream.tty)},read:function(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}},ioctl_tcgets:function(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets:function(tty,optional_actions,data){return 0},ioctl_tiocgwinsz:function(tty){return[24,80]}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};var zeroMemory=(address,size)=>{HEAPU8.fill(0,address,address+size);return address};var alignMemory=(size,alignment)=>{assert(alignment,"alignment argument is required");return Math.ceil(size/alignment)*alignment};var mmapAlloc=size=>{size=alignMemory(size,65536);var ptr=_emscripten_builtin_memalign(65536,size);if(!ptr)return 0;return zeroMemory(ptr,size)};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){throw FS.genericErrors[44]},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp;old_node.parent=new_dir},unlink(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);assert(size>=0);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var dep=!noRunDep?getUniqueRunDependency(`al ${url}`):"";readAsync(url,(arrayBuffer=>{assert(arrayBuffer,`Loading data file "${url}" failed (no arrayBuffer).`);onload(new Uint8Array(arrayBuffer));if(dep)removeRunDependency(dep)}),(event=>{if(onerror){onerror()}else{throw`Loading data file "${url}" failed.`}}));if(dep)addRunDependency(dep)};var preloadPlugins=Module["preloadPlugins"]||[];function FS_handledByPreloadPlugin(byteArray,fullname,finish,onerror){if(typeof Browser!="undefined")Browser.init();var handled=false;preloadPlugins.forEach((function(plugin){if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,onerror);handled=true}}));return handled}function FS_createPreloadedFile(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish){var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);function processData(byteArray){function finish(byteArray){if(preFinish)preFinish();if(!dontCreateFile){FS.createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}if(onload)onload();removeRunDependency(dep)}if(FS_handledByPreloadPlugin(byteArray,fullname,finish,(()=>{if(onerror)onerror();removeRunDependency(dep)}))){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url,(byteArray=>processData(byteArray)),onerror)}else{processData(url)}}function FS_modeStringToFlags(str){var flagModes={"r":0,"r+":2,"w":512|64|1,"w+":512|64|2,"a":1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags}function FS_getMode(canRead,canWrite){var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode}var ERRNO_CODES={};var NODEFS={isWindows:false,staticInit:()=>{NODEFS.isWindows=!!process.platform.match(/^win/);var flags=process.binding("constants");if(flags["fs"]){flags=flags["fs"]}NODEFS.flagsForNodeMap={1024:flags["O_APPEND"],64:flags["O_CREAT"],128:flags["O_EXCL"],256:flags["O_NOCTTY"],0:flags["O_RDONLY"],2:flags["O_RDWR"],4096:flags["O_SYNC"],512:flags["O_TRUNC"],1:flags["O_WRONLY"],131072:flags["O_NOFOLLOW"]};assert(NODEFS.flagsForNodeMap["0"]===0)},convertNodeCode:e=>{var code=e.code;assert(code in ERRNO_CODES,`unexpected node error code: ${code} (${e})`);return ERRNO_CODES[code]},mount:mount=>{assert(ENVIRONMENT_IS_NODE);return NODEFS.createNode(null,"/",NODEFS.getMode(mount.opts.root),0)},createNode:(parent,name,mode,dev)=>{if(!FS.isDir(mode)&&!FS.isFile(mode)&&!FS.isLink(mode)){throw new FS.ErrnoError(28)}var node=FS.createNode(parent,name,mode);node.node_ops=NODEFS.node_ops;node.stream_ops=NODEFS.stream_ops;return node},getMode:path=>{var stat;try{stat=fs.lstatSync(path);if(NODEFS.isWindows){stat.mode=stat.mode|(stat.mode&292)>>2}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}return stat.mode},realPath:node=>{var parts=[];while(node.parent!==node){parts.push(node.name);node=node.parent}parts.push(node.mount.opts.root);parts.reverse();return PATH.join.apply(null,parts)},flagsForNode:flags=>{flags&=~2097152;flags&=~2048;flags&=~32768;flags&=~524288;flags&=~65536;var newFlags=0;for(var k in NODEFS.flagsForNodeMap){if(flags&k){newFlags|=NODEFS.flagsForNodeMap[k];flags^=k}}if(flags){throw new FS.ErrnoError(28)}return newFlags},node_ops:{getattr:node=>{var path=NODEFS.realPath(node);var stat;try{stat=fs.lstatSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}if(NODEFS.isWindows&&!stat.blksize){stat.blksize=4096}if(NODEFS.isWindows&&!stat.blocks){stat.blocks=(stat.size+stat.blksize-1)/stat.blksize|0}return{dev:stat.dev,ino:stat.ino,mode:stat.mode,nlink:stat.nlink,uid:stat.uid,gid:stat.gid,rdev:stat.rdev,size:stat.size,atime:stat.atime,mtime:stat.mtime,ctime:stat.ctime,blksize:stat.blksize,blocks:stat.blocks}},setattr:(node,attr)=>{var path=NODEFS.realPath(node);try{if(attr.mode!==undefined){fs.chmodSync(path,attr.mode);node.mode=attr.mode}if(attr.timestamp!==undefined){var date=new Date(attr.timestamp);fs.utimesSync(path,date,date)}if(attr.size!==undefined){fs.truncateSync(path,attr.size)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},lookup:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);var mode=NODEFS.getMode(path);return NODEFS.createNode(parent,name,mode)},mknod:(parent,name,mode,dev)=>{var node=NODEFS.createNode(parent,name,mode,dev);var path=NODEFS.realPath(node);try{if(FS.isDir(node.mode)){fs.mkdirSync(path,node.mode)}else{fs.writeFileSync(path,"",{mode:node.mode})}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}return node},rename:(oldNode,newDir,newName)=>{var oldPath=NODEFS.realPath(oldNode);var newPath=PATH.join2(NODEFS.realPath(newDir),newName);try{fs.renameSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}oldNode.name=newName},unlink:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.unlinkSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},rmdir:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.rmdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},readdir:node=>{var path=NODEFS.realPath(node);try{return fs.readdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},symlink:(parent,newName,oldPath)=>{var newPath=PATH.join2(NODEFS.realPath(parent),newName);try{fs.symlinkSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},readlink:node=>{var path=NODEFS.realPath(node);try{path=fs.readlinkSync(path);path=nodePath.relative(nodePath.resolve(node.mount.opts.root),path);return path}catch(e){if(!e.code)throw e;if(e.code==="UNKNOWN")throw new FS.ErrnoError(28);throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}}},stream_ops:{open:stream=>{var path=NODEFS.realPath(stream.node);try{if(FS.isFile(stream.node.mode)){stream.nfd=fs.openSync(path,NODEFS.flagsForNode(stream.flags))}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},close:stream=>{try{if(FS.isFile(stream.node.mode)&&stream.nfd){fs.closeSync(stream.nfd)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},read:(stream,buffer,offset,length,position)=>{if(length===0)return 0;try{return fs.readSync(stream.nfd,Buffer.from(buffer.buffer),offset,length,position)}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},write:(stream,buffer,offset,length,position)=>{try{return fs.writeSync(stream.nfd,Buffer.from(buffer.buffer),offset,length,position)}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},llseek:(stream,offset,whence)=>{var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){try{var stat=fs.fstatSync(stream.nfd);position+=stat.size}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}}}if(position<0){throw new FS.ErrnoError(28)}return position},mmap:(stream,length,position,prot,flags)=>{if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}var ptr=mmapAlloc(length);NODEFS.stream_ops.read(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}},msync:(stream,buffer,offset,length,mmapFlags)=>{NODEFS.stream_ops.write(stream,buffer,0,length,offset,false);return 0}}};var ERRNO_MESSAGES={0:"Success",1:"Arg list too long",2:"Permission denied",3:"Address already in use",4:"Address not available",5:"Address family not supported by protocol family",6:"No more processes",7:"Socket already connected",8:"Bad file number",9:"Trying to read unreadable message",10:"Mount device busy",11:"Operation canceled",12:"No children",13:"Connection aborted",14:"Connection refused",15:"Connection reset by peer",16:"File locking deadlock error",17:"Destination address required",18:"Math arg out of domain of func",19:"Quota exceeded",20:"File exists",21:"Bad address",22:"File too large",23:"Host is unreachable",24:"Identifier removed",25:"Illegal byte sequence",26:"Connection already in progress",27:"Interrupted system call",28:"Invalid argument",29:"I/O error",30:"Socket is already connected",31:"Is a directory",32:"Too many symbolic links",33:"Too many open files",34:"Too many links",35:"Message too long",36:"Multihop attempted",37:"File or path name too long",38:"Network interface is not configured",39:"Connection reset by network",40:"Network is unreachable",41:"Too many open files in system",42:"No buffer space available",43:"No such device",44:"No such file or directory",45:"Exec format error",46:"No record locks available",47:"The link has been severed",48:"Not enough core",49:"No message of desired type",50:"Protocol not available",51:"No space left on device",52:"Function not implemented",53:"Socket is not connected",54:"Not a directory",55:"Directory not empty",56:"State not recoverable",57:"Socket operation on non-socket",59:"Not a typewriter",60:"No such device or address",61:"Value too large for defined data type",62:"Previous owner died",63:"Not super-user",64:"Broken pipe",65:"Protocol error",66:"Unknown protocol",67:"Protocol wrong type for socket",68:"Math result not representable",69:"Read only file system",70:"Illegal seek",71:"No such process",72:"Stale file handle",73:"Connection timed out",74:"Text file busy",75:"Cross-device link",100:"Device not a stream",101:"Bad font file fmt",102:"Invalid slot",103:"Invalid request code",104:"No anode",105:"Block device required",106:"Channel number out of range",107:"Level 3 halted",108:"Level 3 reset",109:"Link number out of range",110:"Protocol driver not attached",111:"No CSI structure available",112:"Level 2 halted",113:"Invalid exchange",114:"Invalid request descriptor",115:"Exchange full",116:"No data (for no delay io)",117:"Timer expired",118:"Out of streams resources",119:"Machine is not on the network",120:"Package not installed",121:"The object is remote",122:"Advertise error",123:"Srmount error",124:"Communication error on send",125:"Cross mount point (not really error)",126:"Given log. name not unique",127:"f.d. invalid for this operation",128:"Remote address changed",129:"Can access a needed shared lib",130:"Accessing a corrupted shared lib",131:".lib section in a.out corrupted",132:"Attempting to link in too many libs",133:"Attempting to exec a shared library",135:"Streams pipe error",136:"Too many users",137:"Socket type not supported",138:"Not supported",139:"Protocol family not supported",140:"Can't send after socket shutdown",141:"Too many references",142:"Host is down",148:"No medium (in tape drive)",156:"Level 2 not synchronized"};function demangle(func){warnOnce("warning: build with -sDEMANGLE_SUPPORT to link in libcxxabi demangling");return func}function demangleAll(text){var regex=/\b_Z[\w\d_]+/g;return text.replace(regex,(function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"}))}var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:(path,opts={})=>{path=PATH_FS.resolve(path);if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};opts=Object.assign(defaults,opts);if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=path.split("/").filter((p=>!!p));var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:node=>{var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?`${mount}/${path}`:mount+path}path=path?`${node.name}/${path}`:node.name;node=node.parent}},hashName:(parentid,name)=>{var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:node=>{var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:node=>{var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:(parent,name)=>{var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:(parent,name,mode,rdev)=>{assert(typeof parent=="object");var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:node=>{FS.hashRemoveNode(node)},isRoot:node=>node===node.parent,isMountpoint:node=>!!node.mounted,isFile:mode=>(mode&61440)===32768,isDir:mode=>(mode&61440)===16384,isLink:mode=>(mode&61440)===40960,isChrdev:mode=>(mode&61440)===8192,isBlkdev:mode=>(mode&61440)===24576,isFIFO:mode=>(mode&61440)===4096,isSocket:mode=>(mode&49152)===49152,flagsToPermissionString:flag=>{var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:(node,perms)=>{if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup:dir=>{var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:(dir,name)=>{try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:(dir,name,isdir)=>{var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:(node,flags)=>{if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:()=>{for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked:fd=>{var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream:(stream,fd=-1)=>{if(!FS.FSStream){FS.FSStream=function(){this.shared={}};FS.FSStream.prototype={};Object.defineProperties(FS.FSStream.prototype,{object:{get(){return this.node},set(val){this.node=val}},isRead:{get(){return(this.flags&2097155)!==1}},isWrite:{get(){return(this.flags&2097155)!==0}},isAppend:{get(){return this.flags&1024}},flags:{get(){return this.shared.flags},set(val){this.shared.flags=val}},position:{get(){return this.shared.position},set(val){this.shared.position=val}}})}stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:fd=>{FS.streams[fd]=null},chrdev_stream_ops:{open:stream=>{var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:()=>{throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice:(dev,ops)=>{FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts:mount=>{var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:(populate,callback)=>{if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){assert(FS.syncFSRequests>0);FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach((mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)}))},mount:(type,opts,mountpoint)=>{if(typeof type=="string"){throw type}var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:mountpoint=>{var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach((hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}}));node.mounted=null;var idx=node.mount.mounts.indexOf(mount);assert(idx!==-1);node.mount.mounts.splice(idx,1)},lookup:(parent,name)=>parent.node_ops.lookup(parent,name),mknod:(path,mode,dev)=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:(path,mode)=>{mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:(path,mode)=>{mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:(path,mode)=>{var dirs=path.split("/");var d="";for(var i=0;i{if(typeof dev=="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink:(oldpath,newpath)=>{if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename:(old_path,new_path)=>{var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name)}catch(e){throw e}finally{FS.hashAddNode(old_node)}},rmdir:path=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node)},readdir:path=>{var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node.node_ops.readdir){throw new FS.ErrnoError(54)}return node.node_ops.readdir(node)},unlink:path=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.unlink(parent,name);FS.destroyNode(node)},readlink:path=>{var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return PATH_FS.resolve(FS.getPath(link.parent),link.node_ops.readlink(link))},stat:(path,dontFollow)=>{var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;if(!node){throw new FS.ErrnoError(44)}if(!node.node_ops.getattr){throw new FS.ErrnoError(63)}return node.node_ops.getattr(node)},lstat:path=>FS.stat(path,true),chmod:(path,mode,dontFollow)=>{var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{mode:mode&4095|node.mode&~4095,timestamp:Date.now()})},lchmod:(path,mode)=>{FS.chmod(path,mode,true)},fchmod:(fd,mode)=>{var stream=FS.getStreamChecked(fd);FS.chmod(stream.node,mode)},chown:(path,uid,gid,dontFollow)=>{var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{timestamp:Date.now()})},lchown:(path,uid,gid)=>{FS.chown(path,uid,gid,true)},fchown:(fd,uid,gid)=>{var stream=FS.getStreamChecked(fd);FS.chown(stream.node,uid,gid)},truncate:(path,len)=>{if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}node.node_ops.setattr(node,{size:len,timestamp:Date.now()})},ftruncate:(fd,len)=>{var stream=FS.getStreamChecked(fd);if((stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.truncate(stream.node,len)},utime:(path,atime,mtime)=>{var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;node.node_ops.setattr(node,{timestamp:Math.max(atime,mtime)})},open:(path,flags,mode)=>{if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags=="string"?FS_modeStringToFlags(flags):flags;mode=typeof mode=="undefined"?438:mode;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;if(typeof path=="object"){node=path}else{path=PATH.normalize(path);try{var lookup=FS.lookupPath(path,{follow:!(flags&131072)});node=lookup.node}catch(e){}}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else{node=FS.mknod(path,mode,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512&&!created){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node:node,path:FS.getPath(node),flags:flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false});if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(Module["logReadFiles"]&&!(flags&1)){if(!FS.readFiles)FS.readFiles={};if(!(path in FS.readFiles)){FS.readFiles[path]=1}}return stream},close:stream=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed:stream=>stream.fd===null,llseek:(stream,offset,whence)=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read:(stream,buffer,offset,length,position)=>{assert(offset>=0);if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write:(stream,buffer,offset,length,position,canOwn)=>{assert(offset>=0);if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},allocate:(stream,offset,length)=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(offset<0||length<=0){throw new FS.ErrnoError(28)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(!FS.isFile(stream.node.mode)&&!FS.isDir(stream.node.mode)){throw new FS.ErrnoError(43)}if(!stream.stream_ops.allocate){throw new FS.ErrnoError(138)}stream.stream_ops.allocate(stream,offset,length)},mmap:(stream,length,position,prot,flags)=>{if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync:(stream,buffer,offset,length,mmapFlags)=>{assert(offset>=0);if(!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},munmap:stream=>0,ioctl:(stream,cmd,arg)=>{if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile:(path,opts={})=>{opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error(`Invalid encoding type "${opts.encoding}"`)}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret=UTF8ArrayToString(buf,0)}else if(opts.encoding==="binary"){ret=buf}FS.close(stream);return ret},writeFile:(path,data,opts={})=>{opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){var buf=new Uint8Array(lengthBytesUTF8(data)+1);var actualNumBytes=stringToUTF8Array(data,buf,0,buf.length);FS.write(stream,buf,0,actualNumBytes,undefined,opts.canOwn)}else if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir:path=>{var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories:()=>{FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices:()=>{FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomLeft=randomFill(randomBuffer).byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories:()=>{FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount:()=>{var node=FS.createNode(proc_self,"fd",16384|511,73);node.node_ops={lookup:(parent,name)=>{var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams:()=>{if(Module["stdin"]){FS.createDevice("/dev","stdin",Module["stdin"])}else{FS.symlink("/dev/tty","/dev/stdin")}if(Module["stdout"]){FS.createDevice("/dev","stdout",null,Module["stdout"])}else{FS.symlink("/dev/tty","/dev/stdout")}if(Module["stderr"]){FS.createDevice("/dev","stderr",null,Module["stderr"])}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1);assert(stdin.fd===0,`invalid handle for stdin (${stdin.fd})`);assert(stdout.fd===1,`invalid handle for stdout (${stdout.fd})`);assert(stderr.fd===2,`invalid handle for stderr (${stderr.fd})`)},ensureErrnoError:()=>{if(FS.ErrnoError)return;FS.ErrnoError=function ErrnoError(errno,node){this.name="ErrnoError";this.node=node;this.setErrno=function(errno){this.errno=errno;for(var key in ERRNO_CODES){if(ERRNO_CODES[key]===errno){this.code=key;break}}};this.setErrno(errno);this.message=ERRNO_MESSAGES[errno];if(this.stack){Object.defineProperty(this,"stack",{value:(new Error).stack,writable:true});this.stack=demangleAll(this.stack)}};FS.ErrnoError.prototype=new Error;FS.ErrnoError.prototype.constructor=FS.ErrnoError;[44].forEach((code=>{FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack=""}))},staticInit:()=>{FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={"MEMFS":MEMFS,"NODEFS":NODEFS}},init:(input,output,error)=>{assert(!FS.init.initialized,"FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)");FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()},quit:()=>{FS.init.initialized=false;_fflush(0);for(var i=0;i{var ret=FS.analyzePath(path,dontResolveLastLink);if(!ret.exists){return null}return ret.object},analyzePath:(path,dontResolveLastLink)=>{try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath:(parent,path,canRead,canWrite)=>{parent=typeof parent=="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){}parent=current}return current},createFile:(parent,name,properties,canRead,canWrite)=>{var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile:(parent,name,data,canRead,canWrite,canOwn)=>{var path=name;if(parent){parent=typeof parent=="string"?parent:FS.getPath(parent);path=name?PATH.join2(parent,name):parent}var mode=FS_getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data=="string"){var arr=new Array(data.length);for(var i=0,len=data.length;i{var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(!!input,!!output);if(!FS.createDevice.major)FS.createDevice.major=64;var dev=FS.makedev(FS.createDevice.major++,0);FS.registerDevice(dev,{open:stream=>{stream.seekable=false},close:stream=>{if(output&&output.buffer&&output.buffer.length){output(10)}},read:(stream,buffer,offset,length,pos)=>{var bytesRead=0;for(var i=0;i{for(var i=0;i{if(obj.isDevice||obj.isFolder||obj.link||obj.contents)return true;if(typeof XMLHttpRequest!="undefined"){throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.")}else if(read_){try{obj.contents=intArrayFromString(read_(obj.url),true);obj.usedBytes=obj.contents.length}catch(e){throw new FS.ErrnoError(29)}}else{throw new Error("Cannot load without read() or XMLHttpRequest.")}},createLazyFile:(parent,name,url,canRead,canWrite)=>{function LazyUint8Array(){this.lengthKnown=false;this.chunks=[]}LazyUint8Array.prototype.get=function LazyUint8Array_get(idx){if(idx>this.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter((chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]}));if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach((key=>{var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}}));function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);assert(size>=0);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}};node.stream_ops=stream_ops;return node},absolutePath:()=>{abort("FS.absolutePath has been removed; use PATH_FS.resolve instead")},createFolder:()=>{abort("FS.createFolder has been removed; use FS.mkdir instead")},createLink:()=>{abort("FS.createLink has been removed; use FS.symlink instead")},joinPath:()=>{abort("FS.joinPath has been removed; use PATH.join instead")},mmapAlloc:()=>{abort("FS.mmapAlloc has been replaced by the top level function mmapAlloc")},standardizePath:()=>{abort("FS.standardizePath has been removed; use PATH.normalize instead")}};var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt:function(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return PATH.join2(dir,path)},doStat:function(func,path,buf){try{var stat=func(path)}catch(e){if(e&&e.node&&PATH.normalize(path)!==PATH.normalize(FS.getPath(e.node))){return-54}throw e}HEAP32[buf>>2]=stat.dev;checkInt32(stat.dev);HEAP32[buf+4>>2]=stat.mode;checkInt32(stat.mode);HEAPU32[buf+8>>2]=stat.nlink;checkInt32(stat.nlink);HEAP32[buf+12>>2]=stat.uid;checkInt32(stat.uid);HEAP32[buf+16>>2]=stat.gid;checkInt32(stat.gid);HEAP32[buf+20>>2]=stat.rdev;checkInt32(stat.rdev);tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+24>>2]=tempI64[0],HEAP32[buf+28>>2]=tempI64[1];checkInt64(stat.size);HEAP32[buf+32>>2]=4096;checkInt32(4096);HEAP32[buf+36>>2]=stat.blocks;checkInt32(stat.blocks);var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();tempI64=[Math.floor(atime/1e3)>>>0,(tempDouble=Math.floor(atime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];checkInt64(Math.floor(atime/1e3));HEAPU32[buf+48>>2]=atime%1e3*1e3;checkInt32(atime%1e3*1e3);tempI64=[Math.floor(mtime/1e3)>>>0,(tempDouble=Math.floor(mtime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+56>>2]=tempI64[0],HEAP32[buf+60>>2]=tempI64[1];checkInt64(Math.floor(mtime/1e3));HEAPU32[buf+64>>2]=mtime%1e3*1e3;checkInt32(mtime%1e3*1e3);tempI64=[Math.floor(ctime/1e3)>>>0,(tempDouble=Math.floor(ctime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+72>>2]=tempI64[0],HEAP32[buf+76>>2]=tempI64[1];checkInt64(Math.floor(ctime/1e3));HEAPU32[buf+80>>2]=ctime%1e3*1e3;checkInt32(ctime%1e3*1e3);tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+88>>2]=tempI64[0],HEAP32[buf+92>>2]=tempI64[1];checkInt64(stat.ino);return 0},doMsync:function(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},varargs:undefined,get(){assert(SYSCALLS.varargs!=undefined);SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStreamChecked(fd);return stream}};function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.createStream(stream,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 5:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;checkInt16(2);return 0}case 6:case 7:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:{if(!stream.tty)return-59;return 0}case 21505:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcgets){var termios=stream.tty.ops.ioctl_tcgets(stream);var argp=SYSCALLS.get();HEAP32[argp>>2]=termios.c_iflag||0;checkInt32(termios.c_iflag||0);HEAP32[argp+4>>2]=termios.c_oflag||0;checkInt32(termios.c_oflag||0);HEAP32[argp+8>>2]=termios.c_cflag||0;checkInt32(termios.c_cflag||0);HEAP32[argp+12>>2]=termios.c_lflag||0;checkInt32(termios.c_lflag||0);for(var i=0;i<32;i++){HEAP8[argp+i+17>>0]=termios.c_cc[i]||0;checkInt8(termios.c_cc[i]||0)}return 0}return 0}case 21510:case 21511:case 21512:{if(!stream.tty)return-59;return 0}case 21506:case 21507:case 21508:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcsets){var argp=SYSCALLS.get();var c_iflag=HEAP32[argp>>2];var c_oflag=HEAP32[argp+4>>2];var c_cflag=HEAP32[argp+8>>2];var c_lflag=HEAP32[argp+12>>2];var c_cc=[];for(var i=0;i<32;i++){c_cc.push(HEAP8[argp+i+17>>0])}return stream.tty.ops.ioctl_tcsets(stream.tty,op,{c_iflag:c_iflag,c_oflag:c_oflag,c_cflag:c_cflag,c_lflag:c_lflag,c_cc:c_cc})}return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;checkInt32(0);return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tiocgwinsz){var winsize=stream.tty.ops.ioctl_tiocgwinsz(stream.tty);var argp=SYSCALLS.get();HEAP16[argp>>1]=winsize[0];checkInt16(winsize[0]);HEAP16[argp+2>>1]=winsize[1];checkInt16(winsize[1])}return 0}case 21524:{if(!stream.tty)return-59;return 0}case 21515:{if(!stream.tty)return-59;return 0}default:return-28}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?SYSCALLS.get():0;return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___throw_exception_with_stack_trace(ex){var e=new WebAssembly.Exception(getCppExceptionTag(),[ex],{traceStack:true});e.message=getExceptionMessage(e);if(e.stack){var arr=e.stack.split("\n");arr.splice(1,1);e.stack=arr.join("\n")}throw e}var structRegistrations={};function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAP32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach((function(type){typeDependencies[type]=dependentTypes}));function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push((()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}}))}}));if(0===unregisteredTypes.length){onComplete(typeConverters)}}var __embind_finalize_value_object=function(structType){var reg=structRegistrations[structType];delete structRegistrations[structType];var rawConstructor=reg.rawConstructor;var rawDestructor=reg.rawDestructor;var fieldRecords=reg.fields;var fieldTypes=fieldRecords.map((field=>field.getterReturnType)).concat(fieldRecords.map((field=>field.setterArgumentType)));whenDependentTypesAreResolved([structType],fieldTypes,(fieldTypes=>{var fields={};fieldRecords.forEach(((field,i)=>{var fieldName=field.fieldName;var getterReturnType=fieldTypes[i];var getter=field.getter;var getterContext=field.getterContext;var setterArgumentType=fieldTypes[i+fieldRecords.length];var setter=field.setter;var setterContext=field.setterContext;fields[fieldName]={read:ptr=>getterReturnType["fromWireType"](getter(getterContext,ptr)),write:(ptr,o)=>{var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,o));runDestructors(destructors)}}}));return[{name:reg.name,"fromWireType":function(ptr){var rv={};for(var i in fields){rv[i]=fields[i].read(ptr)}rawDestructor(ptr);return rv},"toWireType":function(destructors,o){for(var fieldName in fields){if(!(fieldName in o)){throw new TypeError(`Missing field: "${fieldName}"`)}}var ptr=rawConstructor();for(fieldName in fields){fields[fieldName].write(ptr,o[fieldName])}if(destructors!==null){destructors.push(rawDestructor,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:rawDestructor}]}))};function __embind_register_bigint(primitiveType,name,size,minRange,maxRange){}function getShiftFromSize(size){switch(size){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError(`Unknown type size: ${size}`)}}function embind_init_charCodes(){var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes}var embind_charCodes=undefined;function readLatin1String(ptr){var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}function sharedRegisterType(rawType,registeredInstance,options={}){var name=registeredInstance.name;if(!rawType){throwBindingError(`type "${name}" must have a positive integer typeid pointer`)}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError(`Cannot register type '${name}' twice`)}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach((cb=>cb()))}}function registerType(rawType,registeredInstance,options={}){if(!("argPackAdvance"in registeredInstance)){throw new TypeError("registerType registeredInstance requires argPackAdvance")}return sharedRegisterType(rawType,registeredInstance,options)}function __embind_register_bool(rawType,name,size,trueValue,falseValue){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(wt){return!!wt},"toWireType":function(destructors,o){return o?trueValue:falseValue},"argPackAdvance":8,"readValueFromPointer":function(pointer){var heap;if(size===1){heap=HEAP8}else if(size===2){heap=HEAP16}else if(size===4){heap=HEAP32}else{throw new TypeError("Unknown boolean type size: "+name)}return this["fromWireType"](heap[pointer>>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationRegistry=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}var registeredPointers={};function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}var delayFunction=undefined;function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}var attachFinalizer=function(handle){if("undefined"===typeof FinalizationRegistry){attachFinalizer=handle=>handle;return handle}finalizationRegistry=new FinalizationRegistry((info=>{console.warn(info.leakWarning.stack.replace(/^Error: /,""));releaseClassHandle(info.$$)}));attachFinalizer=handle=>{var $$=handle.$$;var hasSmartPtr=!!$$.smartPtr;if(hasSmartPtr){var info={$$:$$};var cls=$$.ptrType.registeredClass;info.leakWarning=new Error(`Embind found a leaked C++ instance ${cls.name} <${ptrToString($$.ptr)}>.\n`+"We'll free it automatically in this case, but this functionality is not reliable across various environments.\n"+"Make sure to invoke .delete() manually once you're done with the instance instead.\n"+"Originally allocated");if("captureStackTrace"in Error){Error.captureStackTrace(info.leakWarning,RegisteredPointer_fromWireType)}finalizationRegistry.register(handle,info,handle)}return handle};detachFinalizer=handle=>finalizationRegistry.unregister(handle);return attachFinalizer(handle)};function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return`_${name}`}return name}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return{[name]:function(){return body.apply(this,arguments)}}[name]}function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${arguments.length}) - expects one of (${proto[methodName].overloadTable})!`)}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError(`Cannot register public name '${name}' twice`)}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`)}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError(`Expected null or instance of ${desiredClass.name}, got an instance of ${ptrClass.name}`)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,Emval.toHandle((function(){clonedHandle["delete"]()})));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}var dynCallLegacy=(sig,ptr,args)=>{assert("dynCall_"+sig in Module,`bad function pointer type - dynCall function not found for sig '${sig}'`);if(args&&args.length){assert(args.length===sig.substring(1).replace(/j/g,"--").length)}else{assert(sig.length==1)}var f=Module["dynCall_"+sig];return args&&args.length?f.apply(null,[ptr].concat(args)):f.call(null,ptr)};var wasmTableMirror=[];var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}assert(wasmTable.get(funcPtr)==func,"JavaScript-side Wasm function table mirror is out of date!");return func};var dynCall=(sig,ptr,args)=>{if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}assert(getWasmTableEntry(ptr),`missing table entry in dynCall: ${ptr}`);var rtn=getWasmTableEntry(ptr).apply(null,args);return rtn};var getDynCaller=(sig,ptr)=>{assert(sig.includes("j")||sig.includes("p"),"getDynCaller should only be called with i64 sigs");var argCache=[];return function(){argCache.length=0;Object.assign(argCache,arguments);return dynCall(sig,ptr,argCache)}};function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(){if(signature.includes("j")){return getDynCaller(signature,rawFunction)}return getWasmTableEntry(rawFunction)}var fp=makeDynCaller();if(typeof fp!="function"){throwBindingError(`unknown function pointer with signature ${signature}: ${rawFunction}`)}return fp}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,(function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}}));errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return`${this.name}: ${this.message}`}};return errorClass}var UnboundTypeError=undefined;function getTypeName(type){var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv}function throwUnboundTypeError(message,types){var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(`${message}: `+unboundTypes.map(getTypeName).join([", "]))}function __embind_register_class(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor){name=readLatin1String(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);if(upcast){upcast=embind__requireFunction(upcastSignature,upcast)}if(downcast){downcast=embind__requireFunction(downcastSignature,downcast)}rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,(function(){throwUnboundTypeError(`Cannot construct ${name} due to unbound types`,[baseClassRawType])}));whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],(function(base){base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(legalFunctionName,(function(){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError("Use 'new' to construct "+name)}if(undefined===registeredClass.constructor_body){throw new BindingError(name+" has no accessible constructor")}var body=registeredClass.constructor_body[arguments.length];if(undefined===body){throw new BindingError(`Tried to invoke ctor of ${name} with invalid number of parameters (${arguments.length}) - expected (${Object.keys(registeredClass.constructor_body).toString()}) parameters instead!`)}return body.apply(this,arguments)}));var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);if(registeredClass.baseClass){if(registeredClass.baseClass.__derivedClasses===undefined){registeredClass.baseClass.__derivedClasses=[]}registeredClass.baseClass.__derivedClasses.push(registeredClass)}var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+"*",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+" const*",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]}))}function heap32VectorToArray(count,firstElement){var array=[];for(var i=0;i>2])}return array}function newFunc(constructor,argumentList){if(!(constructor instanceof Function)){throw new TypeError(`new_ called with constructor type ${typeof constructor} which is not a function`)}var dummy=createNamedFunction(constructor.name||"unknownFunctionName",(function(){}));dummy.prototype=constructor.prototype;var obj=new dummy;var r=constructor.apply(obj,argumentList);return r instanceof Object?r:obj}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc,isAsync){var argCount=argTypes.length;if(argCount<2){throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")}assert(!isAsync,"Async bindings are only supported with JSPI.");var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i0?", ":"")+argsListWired}invokerFnBody+=(returns||isAsync?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],(function(classType){classType=classType[0];var humanName=`constructor ${classType.name}`;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError(`Cannot register multiple constructors with identical number of parameters (${argCount-1}) for class '${classType.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!`)}classType.registeredClass.constructor_body[argCount-1]=()=>{throwUnboundTypeError(`Cannot construct ${classType.name} due to unbound types`,rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,(function(argTypes){argTypes.splice(1,0,null);classType.registeredClass.constructor_body[argCount-1]=craftInvokerFunction(humanName,argTypes,null,invoker,rawConstructor);return[]}));return[]}))}function __embind_register_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual,isAsync){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],(function(classType){classType=classType[0];var humanName=`${classType.name}.${methodName}`;if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError(`Cannot call ${humanName} due to unbound types`,rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,(function(argTypes){var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context,isAsync);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]}));return[]}))}function handleAllocatorInit(){Object.assign(HandleAllocator.prototype,{get(id){assert(this.allocated[id]!==undefined,`invalid handle: ${id}`);return this.allocated[id]},has(id){return this.allocated[id]!==undefined},allocate(handle){var id=this.freelist.pop()||this.allocated.length;this.allocated[id]=handle;return id},free(id){assert(this.allocated[id]!==undefined);this.allocated[id]=undefined;this.freelist.push(id)}})}function HandleAllocator(){this.allocated=[undefined];this.freelist=[]}var emval_handles=new HandleAllocator;function __emval_decref(handle){if(handle>=emval_handles.reserved&&0===--emval_handles.get(handle).refcount){emval_handles.free(handle)}}function count_emval_handles(){var count=0;for(var i=emval_handles.reserved;i{if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handles.get(handle).value},toHandle:value=>{switch(value){case undefined:return 1;case null:return 2;case true:return 3;case false:return 4;default:{return emval_handles.allocate({refcount:1,value:value})}}}};function __embind_register_emval(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(handle){var rv=Emval.toValue(handle);__emval_decref(handle);return rv},"toWireType":function(destructors,value){return Emval.toHandle(value)},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})}function embindRepr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!="number"&&typeof value!="boolean"){throw new TypeError(`Cannot convert ${embindRepr(value)} to ${this.name}`)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn,isAsync){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,(function(){throwUnboundTypeError(`Cannot call ${name} due to unbound types`,argTypes)}),argCount-1);whenDependentTypesAreResolved([],argTypes,(function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn,isAsync),argCount-1);return[]}))}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=value=>value;if(minRange===0){var bitshift=32-8*size;fromWireType=value=>value<>>bitshift}var isUnsignedType=name.includes("unsigned");var checkAssertions=(value,toTypeName)=>{if(typeof value!="number"&&typeof value!="boolean"){throw new TypeError(`Cannot convert "${embindRepr(value)}" to ${toTypeName}`)}if(valuemaxRange){throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!`)}};var toWireType;if(isUnsignedType){toWireType=function(destructors,value){checkAssertions(value,this.name);return value>>>0}}else{toWireType=function(destructors,value){checkAssertions(value,this.name);return value}}registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":toWireType,"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(heap.buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}var stringToUTF8=(str,outPtr,maxBytesToWrite)=>{assert(typeof maxBytesToWrite=="number","stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)};function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;checkInt32(length);if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+i]=charCode}}else{for(var i=0;i{assert(ptr%2==0,"Pointer passed to UTF16ToString must be aligned to two bytes!");var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder)return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr));var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str};var stringToUTF16=(str,outPtr,maxBytesToWrite)=>{assert(outPtr%2==0,"Pointer passed to stringToUTF16 must be aligned to two bytes!");assert(typeof maxBytesToWrite=="number","stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;checkInt16(codeUnit);outPtr+=2}HEAP16[outPtr>>1]=0;checkInt16(0);return outPtr-startPtr};var lengthBytesUTF16=str=>str.length*2;var UTF32ToString=(ptr,maxBytesToRead)=>{assert(ptr%4==0,"Pointer passed to UTF32ToString must be aligned to four bytes!");var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str};var stringToUTF32=(str,outPtr,maxBytesToWrite)=>{assert(outPtr%4==0,"Pointer passed to stringToUTF32 must be aligned to four bytes!");assert(typeof maxBytesToWrite=="number","stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;checkInt32(codeUnit);outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;checkInt32(0);return outPtr-startPtr};var lengthBytesUTF32=str=>{var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len};var __embind_register_std_wstring=function(rawType,charSize,name){name=readLatin1String(name);var decodeString,encodeString,getHeap,lengthBytesUTF,shift;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;getHeap=()=>HEAPU16;shift=1}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;getHeap=()=>HEAPU32;shift=2}registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value=="string")){throwBindingError(`Cannot pass non-string to C++ string type ${name}`)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})};function __embind_register_value_object(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}}function __embind_register_value_object_field(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function __emval_incref(handle){if(handle>4){emval_handles.get(handle).refcount+=1}}function requireRegisteredType(rawType,humanName){var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl}function __emval_take_value(type,arg){type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](arg);return Emval.toHandle(v)}var _abort=()=>{abort("native code called abort()")};var _emscripten_memcpy_big=(dest,src,num)=>HEAPU8.copyWithin(dest,src,src+num);var getHeapMax=()=>2147483648;var _emscripten_get_now;_emscripten_get_now=()=>performance.now();var growMemory=size=>{var b=wasmMemory.buffer;var pages=size-b.byteLength+65535>>>16;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){err(`growMemory: Attempted to grow heap from ${b.byteLength} bytes to ${size} bytes, but got error: ${e}`)}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;assert(requestedSize>oldSize);var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){err(`Cannot enlarge memory, asked to go up to ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!`);return false}var alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var t0=_emscripten_get_now();var replacement=growMemory(newSize);var t1=_emscripten_get_now();out(`Heap resize call from ${oldSize} to ${newSize} took ${t1-t0} msecs. Success: ${!!replacement}`);if(replacement){return true}}err(`Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!`);return false};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var stringToAscii=(str,buffer)=>{for(var i=0;i>0]=str.charCodeAt(i);checkInt8(str.charCodeAt(i))}HEAP8[buffer>>0]=0;checkInt8(0)};var _environ_get=(__environ,environ_buf)=>{var bufSize=0;getEnvStrings().forEach((function(string,i){var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>2]=ptr;checkInt32(ptr);stringToAscii(string,ptr);bufSize+=string.length+1}));return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;checkInt32(strings.length);var bufSize=0;strings.forEach((function(string){bufSize+=string.length+1}));HEAPU32[penviron_buf_size>>2]=bufSize;checkInt32(bufSize);return 0};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;checkInt32(num);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}function convertI32PairToI53Checked(lo,hi){assert(lo==lo>>>0||lo==(lo|0));assert(hi===(hi|0));return hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];checkInt64(stream.position);if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(typeof offset!=="undefined"){offset+=curr}}return ret};function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=doWritev(stream,iov,iovcnt);HEAPU32[pnum>>2]=num;checkInt32(num);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var arraySum=(array,index)=>{var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum};var MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];var addDays=(date,days)=>{var newDate=new Date(date.getTime());while(days>0){var leap=isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate};var writeArrayToMemory=(array,buffer)=>{assert(array.length>=0,"writeArrayToMemory array must have a length (should be an array or typed array)");HEAP8.set(array,buffer)};var _strftime=(s,maxsize,format,tm)=>{var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value=="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}return thisDate.getFullYear()}return thisDate.getFullYear()-1}var EXPANSION_RULES_2={"%a":date=>WEEKDAYS[date.tm_wday].substring(0,3),"%A":date=>WEEKDAYS[date.tm_wday],"%b":date=>MONTHS[date.tm_mon].substring(0,3),"%B":date=>MONTHS[date.tm_mon],"%C":date=>{var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":date=>leadingNulls(date.tm_mday,2),"%e":date=>leadingSomething(date.tm_mday,2," "),"%g":date=>getWeekBasedYear(date).toString().substring(2),"%G":date=>getWeekBasedYear(date),"%H":date=>leadingNulls(date.tm_hour,2),"%I":date=>{var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":date=>leadingNulls(date.tm_mday+arraySum(isLeapYear(date.tm_year+1900)?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR,date.tm_mon-1),3),"%m":date=>leadingNulls(date.tm_mon+1,2),"%M":date=>leadingNulls(date.tm_min,2),"%n":()=>"\n","%p":date=>{if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}return"PM"},"%S":date=>leadingNulls(date.tm_sec,2),"%t":()=>"\t","%u":date=>date.tm_wday||7,"%U":date=>{var days=date.tm_yday+7-date.tm_wday;return leadingNulls(Math.floor(days/7),2)},"%V":date=>{var val=Math.floor((date.tm_yday+7-(date.tm_wday+6)%7)/7);if((date.tm_wday+371-date.tm_yday-2)%7<=2){val++}if(!val){val=52;var dec31=(date.tm_wday+7-date.tm_yday-1)%7;if(dec31==4||dec31==5&&isLeapYear(date.tm_year%400-1)){val++}}else if(val==53){var jan1=(date.tm_wday+371-date.tm_yday)%7;if(jan1!=4&&(jan1!=3||!isLeapYear(date.tm_year)))val=1}return leadingNulls(val,2)},"%w":date=>date.tm_wday,"%W":date=>{var days=date.tm_yday+7-(date.tm_wday+6)%7;return leadingNulls(Math.floor(days/7),2)},"%y":date=>(date.tm_year+1900).toString().substring(2),"%Y":date=>date.tm_year+1900,"%z":date=>{var off=date.tm_gmtoff;var ahead=off>=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":date=>date.tm_zone,"%%":()=>"%"};pattern=pattern.replace(/%%/g,"\0\0");for(var rule in EXPANSION_RULES_2){if(pattern.includes(rule)){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}pattern=pattern.replace(/\0\0/g,"%");var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1};var _strftime_l=(s,maxsize,format,tm,loc)=>_strftime(s,maxsize,format,tm);var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.createPreloadedFile=FS_createPreloadedFile;FS.staticInit();Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_unlink"]=FS.unlink;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createDevice"]=FS.createDevice;if(ENVIRONMENT_IS_NODE){NODEFS.staticInit()}ERRNO_CODES={"EPERM":63,"ENOENT":44,"ESRCH":71,"EINTR":27,"EIO":29,"ENXIO":60,"E2BIG":1,"ENOEXEC":45,"EBADF":8,"ECHILD":12,"EAGAIN":6,"EWOULDBLOCK":6,"ENOMEM":48,"EACCES":2,"EFAULT":21,"ENOTBLK":105,"EBUSY":10,"EEXIST":20,"EXDEV":75,"ENODEV":43,"ENOTDIR":54,"EISDIR":31,"EINVAL":28,"ENFILE":41,"EMFILE":33,"ENOTTY":59,"ETXTBSY":74,"EFBIG":22,"ENOSPC":51,"ESPIPE":70,"EROFS":69,"EMLINK":34,"EPIPE":64,"EDOM":18,"ERANGE":68,"ENOMSG":49,"EIDRM":24,"ECHRNG":106,"EL2NSYNC":156,"EL3HLT":107,"EL3RST":108,"ELNRNG":109,"EUNATCH":110,"ENOCSI":111,"EL2HLT":112,"EDEADLK":16,"ENOLCK":46,"EBADE":113,"EBADR":114,"EXFULL":115,"ENOANO":104,"EBADRQC":103,"EBADSLT":102,"EDEADLOCK":16,"EBFONT":101,"ENOSTR":100,"ENODATA":116,"ETIME":117,"ENOSR":118,"ENONET":119,"ENOPKG":120,"EREMOTE":121,"ENOLINK":47,"EADV":122,"ESRMNT":123,"ECOMM":124,"EPROTO":65,"EMULTIHOP":36,"EDOTDOT":125,"EBADMSG":9,"ENOTUNIQ":126,"EBADFD":127,"EREMCHG":128,"ELIBACC":129,"ELIBBAD":130,"ELIBSCN":131,"ELIBMAX":132,"ELIBEXEC":133,"ENOSYS":52,"ENOTEMPTY":55,"ENAMETOOLONG":37,"ELOOP":32,"EOPNOTSUPP":138,"EPFNOSUPPORT":139,"ECONNRESET":15,"ENOBUFS":42,"EAFNOSUPPORT":5,"EPROTOTYPE":67,"ENOTSOCK":57,"ENOPROTOOPT":50,"ESHUTDOWN":140,"ECONNREFUSED":14,"EADDRINUSE":3,"ECONNABORTED":13,"ENETUNREACH":40,"ENETDOWN":38,"ETIMEDOUT":73,"EHOSTDOWN":142,"EHOSTUNREACH":23,"EINPROGRESS":26,"EALREADY":7,"EDESTADDRREQ":17,"EMSGSIZE":35,"EPROTONOSUPPORT":66,"ESOCKTNOSUPPORT":137,"EADDRNOTAVAIL":4,"ENETRESET":39,"EISCONN":30,"ENOTCONN":53,"ETOOMANYREFS":141,"EUSERS":136,"EDQUOT":19,"ESTALE":72,"ENOTSUP":138,"ENOMEDIUM":148,"EILSEQ":25,"EOVERFLOW":61,"ECANCELED":11,"ENOTRECOVERABLE":56,"EOWNERDEAD":62,"ESTRPIPE":135};InternalError=Module["InternalError"]=class InternalError extends Error{constructor(message){super(message);this.name="InternalError"}};embind_init_charCodes();BindingError=Module["BindingError"]=class BindingError extends Error{constructor(message){super(message);this.name="BindingError"}};init_ClassHandle();init_embind();init_RegisteredPointer();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");handleAllocatorInit();init_emval();function checkIncomingModuleAPI(){ignoredModuleProp("fetchSettings")}var wasmImports={__assert_fail:___assert_fail,__handle_stack_overflow:___handle_stack_overflow,__syscall_fcntl64:___syscall_fcntl64,__syscall_ioctl:___syscall_ioctl,__syscall_openat:___syscall_openat,__throw_exception_with_stack_trace:___throw_exception_with_stack_trace,_embind_finalize_value_object:__embind_finalize_value_object,_embind_register_bigint:__embind_register_bigint,_embind_register_bool:__embind_register_bool,_embind_register_class:__embind_register_class,_embind_register_class_constructor:__embind_register_class_constructor,_embind_register_class_function:__embind_register_class_function,_embind_register_emval:__embind_register_emval,_embind_register_float:__embind_register_float,_embind_register_function:__embind_register_function,_embind_register_integer:__embind_register_integer,_embind_register_memory_view:__embind_register_memory_view,_embind_register_std_string:__embind_register_std_string,_embind_register_std_wstring:__embind_register_std_wstring,_embind_register_value_object:__embind_register_value_object,_embind_register_value_object_field:__embind_register_value_object_field,_embind_register_void:__embind_register_void,_emval_decref:__emval_decref,_emval_incref:__emval_incref,_emval_take_value:__emval_take_value,abort:_abort,emscripten_memcpy_big:_emscripten_memcpy_big,emscripten_resize_heap:_emscripten_resize_heap,environ_get:_environ_get,environ_sizes_get:_environ_sizes_get,fd_close:_fd_close,fd_read:_fd_read,fd_seek:_fd_seek,fd_write:_fd_write,strftime_l:_strftime_l};var asm=createWasm();var ___wasm_call_ctors=createExportWrapper("__wasm_call_ctors");var _malloc=createExportWrapper("malloc");var _fflush=Module["_fflush"]=createExportWrapper("fflush");var _free=Module["_free"]=createExportWrapper("free");var ___errno_location=createExportWrapper("__errno_location");var ___getTypeName=createExportWrapper("__getTypeName");var __embind_initialize_bindings=Module["__embind_initialize_bindings"]=createExportWrapper("_embind_initialize_bindings");var ___funcs_on_exit=createExportWrapper("__funcs_on_exit");var _emscripten_builtin_memalign=createExportWrapper("emscripten_builtin_memalign");var ___trap=function(){return(___trap=Module["asm"]["__trap"]).apply(null,arguments)};var setTempRet0=createExportWrapper("setTempRet0");var _emscripten_stack_init=function(){return(_emscripten_stack_init=Module["asm"]["emscripten_stack_init"]).apply(null,arguments)};var _emscripten_stack_get_free=function(){return(_emscripten_stack_get_free=Module["asm"]["emscripten_stack_get_free"]).apply(null,arguments)};var _emscripten_stack_get_base=function(){return(_emscripten_stack_get_base=Module["asm"]["emscripten_stack_get_base"]).apply(null,arguments)};var _emscripten_stack_get_end=function(){return(_emscripten_stack_get_end=Module["asm"]["emscripten_stack_get_end"]).apply(null,arguments)};var stackSave=createExportWrapper("stackSave");var stackRestore=createExportWrapper("stackRestore");var stackAlloc=createExportWrapper("stackAlloc");var _emscripten_stack_get_current=function(){return(_emscripten_stack_get_current=Module["asm"]["emscripten_stack_get_current"]).apply(null,arguments)};var ___cxa_decrement_exception_refcount=Module["___cxa_decrement_exception_refcount"]=createExportWrapper("__cxa_decrement_exception_refcount");var ___cxa_increment_exception_refcount=Module["___cxa_increment_exception_refcount"]=createExportWrapper("__cxa_increment_exception_refcount");var ___thrown_object_from_unwind_exception=Module["___thrown_object_from_unwind_exception"]=createExportWrapper("__thrown_object_from_unwind_exception");var ___get_exception_message=Module["___get_exception_message"]=createExportWrapper("__get_exception_message");var ___set_stack_limits=Module["___set_stack_limits"]=createExportWrapper("__set_stack_limits");var dynCall_jiji=Module["dynCall_jiji"]=createExportWrapper("dynCall_jiji");var dynCall_viijii=Module["dynCall_viijii"]=createExportWrapper("dynCall_viijii");var dynCall_iiiiij=Module["dynCall_iiiiij"]=createExportWrapper("dynCall_iiiiij");var dynCall_iiiiijj=Module["dynCall_iiiiijj"]=createExportWrapper("dynCall_iiiiijj");var dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=createExportWrapper("dynCall_iiiiiijj");function intArrayFromBase64(s){if(typeof ENVIRONMENT_IS_NODE!="undefined"&&ENVIRONMENT_IS_NODE){var buf=Buffer.from(s,"base64");return new Uint8Array(buf["buffer"],buf["byteOffset"],buf["byteLength"])}try{var decoded=atob(s);var bytes=new Uint8Array(decoded.length);for(var i=0;i0){return}stackCheckInit();preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();assert(!Module["_main"],'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]');postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}checkStackCookie()}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); - + var _scriptDir = import.meta.url; - return moduleArg.ready -} + return async function (moduleArg = {}) { + var Module = moduleArg; + var readyPromiseResolve, readyPromiseReject; + Module['ready'] = new Promise((resolve, reject) => { + readyPromiseResolve = resolve; + readyPromiseReject = reject; + }); + [ + '_main', + 'getExceptionMessage', + '___get_exception_message', + '_free', + '___cpp_exception', + '___cxa_increment_exception_refcount', + '___cxa_decrement_exception_refcount', + '___thrown_object_from_unwind_exception', + '_fflush', + '__embind_initialize_bindings', + '___set_stack_limits', + 'onRuntimeInitialized', + ].forEach((prop) => { + if (!Object.getOwnPropertyDescriptor(Module['ready'], prop)) { + Object.defineProperty(Module['ready'], prop, { + get: () => + abort( + 'You are getting ' + + prop + + ' on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js' + ), + set: () => + abort( + 'You are setting ' + + prop + + ' on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js' + ), + }); + } + }); + if (!Module.expectedDataFileDownloads) { + Module.expectedDataFileDownloads = 0; + } + Module.expectedDataFileDownloads++; + (function () { + if (Module['ENVIRONMENT_IS_PTHREAD'] || Module['$ww']) return; + var loadPackage = function (metadata) { + var PACKAGE_PATH = ''; + if (typeof window === 'object') { + PACKAGE_PATH = window['encodeURIComponent']( + window.location.pathname + .toString() + .substring( + 0, + window.location.pathname + .toString() + .lastIndexOf('/') + ) + '/' + ); + } else if ( + typeof process === 'undefined' && + typeof location !== 'undefined' + ) { + PACKAGE_PATH = encodeURIComponent( + location.pathname + .toString() + .substring( + 0, + location.pathname.toString().lastIndexOf('/') + ) + '/' + ); + } + var PACKAGE_NAME = 'privateer.data'; + var REMOTE_PACKAGE_BASE = 'privateer.data'; + if ( + typeof Module['locateFilePackage'] === 'function' && + !Module['locateFile'] + ) { + Module['locateFile'] = Module['locateFilePackage']; + err( + 'warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)' + ); + } + var REMOTE_PACKAGE_NAME = Module['locateFile'] + ? Module['locateFile'](REMOTE_PACKAGE_BASE, '') + : REMOTE_PACKAGE_BASE; + var REMOTE_PACKAGE_SIZE = metadata['remote_package_size']; + function fetchRemotePackage( + packageName, + packageSize, + callback, + errback + ) { + if ( + typeof process === 'object' && + typeof process.versions === 'object' && + typeof process.versions.node === 'string' + ) { + require('fs').readFile( + packageName, + function (err, contents) { + if (err) { + errback(err); + } else { + callback(contents.buffer); + } + } + ); + return; + } + var xhr = new XMLHttpRequest(); + xhr.open('GET', packageName, true); + xhr.responseType = 'arraybuffer'; + xhr.onprogress = function (event) { + var url = packageName; + var size = packageSize; + if (event.total) size = event.total; + if (event.loaded) { + if (!xhr.addedTotal) { + xhr.addedTotal = true; + if (!Module.dataFileDownloads) + Module.dataFileDownloads = {}; + Module.dataFileDownloads[url] = { + loaded: event.loaded, + total: size, + }; + } else { + Module.dataFileDownloads[url].loaded = + event.loaded; + } + var total = 0; + var loaded = 0; + var num = 0; + for (var download in Module.dataFileDownloads) { + var data = Module.dataFileDownloads[download]; + total += data.total; + loaded += data.loaded; + num++; + } + total = Math.ceil( + (total * Module.expectedDataFileDownloads) / num + ); + if (Module['setStatus']) + Module['setStatus']( + `Downloading data... (${loaded}/${total})` + ); + } else if (!Module.dataFileDownloads) { + if (Module['setStatus']) + Module['setStatus']('Downloading data...'); + } + }; + xhr.onerror = function (event) { + throw new Error('NetworkError for: ' + packageName); + }; + xhr.onload = function (event) { + if ( + xhr.status == 200 || + xhr.status == 304 || + xhr.status == 206 || + (xhr.status == 0 && xhr.response) + ) { + var packageData = xhr.response; + callback(packageData); + } else { + throw new Error( + xhr.statusText + ' : ' + xhr.responseURL + ); + } + }; + xhr.send(null); + } + function handleError(error) { + console.error('package error:', error); + } + var fetchedCallback = null; + var fetched = Module['getPreloadedPackage'] + ? Module['getPreloadedPackage']( + REMOTE_PACKAGE_NAME, + REMOTE_PACKAGE_SIZE + ) + : null; + if (!fetched) + fetchRemotePackage( + REMOTE_PACKAGE_NAME, + REMOTE_PACKAGE_SIZE, + function (data) { + if (fetchedCallback) { + fetchedCallback(data); + fetchedCallback = null; + } else { + fetched = data; + } + }, + handleError + ); + function runWithFS() { + function assert(check, msg) { + if (!check) throw msg + new Error().stack; + } + Module['FS_createPath']( + '/', + 'unprocessed_files', + true, + true + ); + function DataRequest(start, end, audio) { + this.start = start; + this.end = end; + this.audio = audio; + } + DataRequest.prototype = { + requests: {}, + open: function (mode, name) { + this.name = name; + this.requests[name] = this; + Module['addRunDependency'](`fp ${this.name}`); + }, + send: function () {}, + onload: function () { + var byteArray = this.byteArray.subarray( + this.start, + this.end + ); + this.finish(byteArray); + }, + finish: function (byteArray) { + var that = this; + Module['FS_createDataFile']( + this.name, + null, + byteArray, + true, + true, + true + ); + Module['removeRunDependency'](`fp ${that.name}`); + this.requests[this.name] = null; + }, + }; + var files = metadata['files']; + for (var i = 0; i < files.length; ++i) { + new DataRequest( + files[i]['start'], + files[i]['end'], + files[i]['audio'] || 0 + ).open('GET', files[i]['filename']); + } + function processPackageData(arrayBuffer) { + assert(arrayBuffer, 'Loading data file failed.'); + assert( + arrayBuffer.constructor.name === ArrayBuffer.name, + 'bad input to processPackageData' + ); + var byteArray = new Uint8Array(arrayBuffer); + DataRequest.prototype.byteArray = byteArray; + var files = metadata['files']; + for (var i = 0; i < files.length; ++i) { + DataRequest.prototype.requests[ + files[i].filename + ].onload(); + } + Module['removeRunDependency']( + 'datafile_privateer.data' + ); + } + Module['addRunDependency']('datafile_privateer.data'); + if (!Module.preloadResults) Module.preloadResults = {}; + Module.preloadResults[PACKAGE_NAME] = { fromCache: false }; + if (fetched) { + processPackageData(fetched); + fetched = null; + } else { + fetchedCallback = processPackageData; + } + } + if (Module['calledRun']) { + runWithFS(); + } else { + if (!Module['preRun']) Module['preRun'] = []; + Module['preRun'].push(runWithFS); + } + }; + loadPackage({ + files: [ + { + filename: '/privateer_torsion_database.json', + start: 0, + end: 2313860, + }, + { + filename: '/privateer_torsion_statistics.json', + start: 2313860, + end: 2326506, + }, + { + filename: '/privateer_torsions_z_score_database.json', + start: 2326506, + end: 10108540, + }, + { + filename: '/unprocessed_files/ASN-NAG_reduced.json', + start: 10108540, + end: 10757358, + }, + { + filename: '/unprocessed_files/ASN-NGA_reduced.json', + start: 10757358, + end: 10758631, + }, + { + filename: '/unprocessed_files/BGC-BGC_reduced.json', + start: 10758631, + end: 10760275, + }, + { + filename: '/unprocessed_files/BGC-GAL_reduced.json', + start: 10760275, + end: 10760795, + }, + { + filename: '/unprocessed_files/BGC-GLA_reduced.json', + start: 10760795, + end: 10761054, + }, + { + filename: '/unprocessed_files/BGC-XYS_reduced.json', + start: 10761054, + end: 10761397, + }, + { + filename: '/unprocessed_files/BMA-BMA_reduced.json', + start: 10761397, + end: 10762693, + }, + { + filename: '/unprocessed_files/BMA-GAL_reduced.json', + start: 10762693, + end: 10762868, + }, + { + filename: '/unprocessed_files/BMA-MAN_reduced.json', + start: 10762868, + end: 10888263, + }, + { + filename: '/unprocessed_files/BMA-NAG_reduced.json', + start: 10888263, + end: 10888862, + }, + { + filename: '/unprocessed_files/BMA-NDG_reduced.json', + start: 10888862, + end: 10888948, + }, + { + filename: '/unprocessed_files/BMA-XYP_reduced.json', + start: 10888948, + end: 10889890, + }, + { + filename: '/unprocessed_files/FRU-FRU_reduced.json', + start: 10889890, + end: 10890666, + }, + { + filename: '/unprocessed_files/FRU-GLC_reduced.json', + start: 10890666, + end: 10891785, + }, + { + filename: '/unprocessed_files/FUC-BGC_reduced.json', + start: 10891785, + end: 10892733, + }, + { + filename: '/unprocessed_files/GAL-A2G_reduced.json', + start: 10892733, + end: 10892991, + }, + { + filename: '/unprocessed_files/GAL-FUC_reduced.json', + start: 10892991, + end: 10893162, + }, + { + filename: '/unprocessed_files/GAL-GAL_reduced.json', + start: 10893162, + end: 10894023, + }, + { + filename: '/unprocessed_files/GAL-GLA_reduced.json', + start: 10894023, + end: 10894532, + }, + { + filename: '/unprocessed_files/GAL-NAG_reduced.json', + start: 10894532, + end: 10894961, + }, + { + filename: '/unprocessed_files/GAL-SIA_reduced.json', + start: 10894961, + end: 10899540, + }, + { + filename: '/unprocessed_files/GLA-A2G_reduced.json', + start: 10899540, + end: 10899714, + }, + { + filename: '/unprocessed_files/GLA-GLA_reduced.json', + start: 10899714, + end: 10900142, + }, + { + filename: '/unprocessed_files/GLC-BGC_reduced.json', + start: 10900142, + end: 10900319, + }, + { + filename: '/unprocessed_files/GLC-FRU_reduced.json', + start: 10900319, + end: 10900493, + }, + { + filename: '/unprocessed_files/GLC-GAL_reduced.json', + start: 10900493, + end: 10900581, + }, + { + filename: '/unprocessed_files/GLC-GLA_reduced.json', + start: 10900581, + end: 10900752, + }, + { + filename: '/unprocessed_files/GLC-GLC_reduced.json', + start: 10900752, + end: 10901525, + }, + { + filename: '/unprocessed_files/GLC-MAN_reduced.json', + start: 10901525, + end: 10901612, + }, + { + filename: '/unprocessed_files/GLC-XYS_reduced.json', + start: 10901612, + end: 10901699, + }, + { + filename: '/unprocessed_files/MAG-GAL_reduced.json', + start: 10901699, + end: 10901787, + }, + { + filename: '/unprocessed_files/MAN-BMA_reduced.json', + start: 10901787, + end: 10901875, + }, + { + filename: '/unprocessed_files/MAN-GLC_reduced.json', + start: 10901875, + end: 10902549, + }, + { + filename: '/unprocessed_files/MAN-MAN_reduced.json', + start: 10902549, + end: 10987921, + }, + { + filename: '/unprocessed_files/MAN-NAG_reduced.json', + start: 10987921, + end: 11008593, + }, + { + filename: '/unprocessed_files/NAG-BMA_reduced.json', + start: 11008593, + end: 11152243, + }, + { + filename: '/unprocessed_files/NAG-FCA_reduced.json', + start: 11152243, + end: 11152331, + }, + { + filename: '/unprocessed_files/NAG-FUC_reduced.json', + start: 11152331, + end: 11206617, + }, + { + filename: '/unprocessed_files/NAG-FUL_reduced.json', + start: 11206617, + end: 11208669, + }, + { + filename: '/unprocessed_files/NAG-GAL_reduced.json', + start: 11208669, + end: 11215929, + }, + { + filename: '/unprocessed_files/NAG-GLC_reduced.json', + start: 11215929, + end: 11216018, + }, + { + filename: '/unprocessed_files/NAG-MAN_reduced.json', + start: 11216018, + end: 11216364, + }, + { + filename: '/unprocessed_files/NAG-NAG_reduced.json', + start: 11216364, + end: 11545985, + }, + { + filename: '/unprocessed_files/NAG-NDG_reduced.json', + start: 11545985, + end: 11546494, + }, + { + filename: '/unprocessed_files/NAG-SIA_reduced.json', + start: 11546494, + end: 11546667, + }, + { + filename: '/unprocessed_files/NDG-BMA_reduced.json', + start: 11546667, + end: 11546928, + }, + { + filename: '/unprocessed_files/NDG-GAL_reduced.json', + start: 11546928, + end: 11547102, + }, + { + filename: '/unprocessed_files/NDG-NAG_reduced.json', + start: 11547102, + end: 11547278, + }, + { + filename: '/unprocessed_files/NGA-GAL_reduced.json', + start: 11547278, + end: 11547454, + }, + { + filename: '/unprocessed_files/NGA-NAG_reduced.json', + start: 11547454, + end: 11547542, + }, + { + filename: '/unprocessed_files/PA1-GCS_reduced.json', + start: 11547542, + end: 11547631, + }, + { + filename: '/unprocessed_files/XYP-GCV_reduced.json', + start: 11547631, + end: 11547719, + }, + { + filename: '/unprocessed_files/XYP-XYP_reduced.json', + start: 11547719, + end: 11548065, + }, + ], + remote_package_size: 11548065, + }); + })(); + if (Module['ENVIRONMENT_IS_PTHREAD'] || Module['$ww']) + Module['preRun'] = []; + var necessaryPreJSTasks = Module['preRun'].slice(); + if (!Module['preRun']) + throw 'Module.preRun should exist because file support used it; did a pre-js delete it?'; + necessaryPreJSTasks.forEach(function (task) { + if (Module['preRun'].indexOf(task) < 0) + throw 'All preRun tasks that exist before user pre-js code should remain after; did you replace Module or modify Module.preRun?'; + }); + var moduleOverrides = Object.assign({}, Module); + var arguments_ = []; + var thisProgram = './this.program'; + var quit_ = (status, toThrow) => { + throw toThrow; + }; + var ENVIRONMENT_IS_WEB = typeof window == 'object'; + var ENVIRONMENT_IS_WORKER = typeof importScripts == 'function'; + var ENVIRONMENT_IS_NODE = + typeof process == 'object' && + typeof process.versions == 'object' && + typeof process.versions.node == 'string'; + var ENVIRONMENT_IS_SHELL = + !ENVIRONMENT_IS_WEB && + !ENVIRONMENT_IS_NODE && + !ENVIRONMENT_IS_WORKER; + if (Module['ENVIRONMENT']) { + throw new Error( + 'Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)' + ); + } + var scriptDirectory = ''; + function locateFile(path) { + if (Module['locateFile']) { + return Module['locateFile'](path, scriptDirectory); + } + return scriptDirectory + path; + } + var read_, readAsync, readBinary, setWindowTitle; + if (ENVIRONMENT_IS_NODE) { + if ( + typeof process == 'undefined' || + !process.release || + process.release.name !== 'node' + ) + throw new Error( + 'not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)' + ); + var nodeVersion = process.versions.node; + var numericVersion = nodeVersion.split('.').slice(0, 3); + numericVersion = + numericVersion[0] * 1e4 + + numericVersion[1] * 100 + + numericVersion[2].split('-')[0] * 1; + if (numericVersion < 16e4) { + throw new Error( + 'This emscripten-generated code requires node v16.0.0 (detected v' + + nodeVersion + + ')' + ); + } + const { createRequire: createRequire } = await import('module'); + var require = createRequire(import.meta.url); + var fs = require('fs'); + var nodePath = require('path'); + if (ENVIRONMENT_IS_WORKER) { + scriptDirectory = nodePath.dirname(scriptDirectory) + '/'; + } else { + scriptDirectory = require('url').fileURLToPath( + new URL('./', import.meta.url) + ); + } + read_ = (filename, binary) => { + filename = isFileURI(filename) + ? new URL(filename) + : nodePath.normalize(filename); + return fs.readFileSync(filename, binary ? undefined : 'utf8'); + }; + readBinary = (filename) => { + var ret = read_(filename, true); + if (!ret.buffer) { + ret = new Uint8Array(ret); + } + assert(ret.buffer); + return ret; + }; + readAsync = (filename, onload, onerror, binary = true) => { + filename = isFileURI(filename) + ? new URL(filename) + : nodePath.normalize(filename); + fs.readFile( + filename, + binary ? undefined : 'utf8', + (err, data) => { + if (err) onerror(err); + else onload(binary ? data.buffer : data); + } + ); + }; + if (!Module['thisProgram'] && process.argv.length > 1) { + thisProgram = process.argv[1].replace(/\\/g, '/'); + } + arguments_ = process.argv.slice(2); + quit_ = (status, toThrow) => { + process.exitCode = status; + throw toThrow; + }; + Module['inspect'] = () => '[Emscripten Module object]'; + } else if (ENVIRONMENT_IS_SHELL) { + if ( + (typeof process == 'object' && typeof require === 'function') || + typeof window == 'object' || + typeof importScripts == 'function' + ) + throw new Error( + 'not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)' + ); + if (typeof read != 'undefined') { + read_ = (f) => read(f); + } + readBinary = (f) => { + let data; + if (typeof readbuffer == 'function') { + return new Uint8Array(readbuffer(f)); + } + data = read(f, 'binary'); + assert(typeof data == 'object'); + return data; + }; + readAsync = (f, onload, onerror) => { + setTimeout(() => onload(readBinary(f))); + }; + if (typeof clearTimeout == 'undefined') { + globalThis.clearTimeout = (id) => {}; + } + if (typeof setTimeout == 'undefined') { + globalThis.setTimeout = (f) => + typeof f == 'function' ? f() : abort(); + } + if (typeof scriptArgs != 'undefined') { + arguments_ = scriptArgs; + } else if (typeof arguments != 'undefined') { + arguments_ = arguments; + } + if (typeof quit == 'function') { + quit_ = (status, toThrow) => { + setTimeout(() => { + if (!(toThrow instanceof ExitStatus)) { + let toLog = toThrow; + if ( + toThrow && + typeof toThrow == 'object' && + toThrow.stack + ) { + toLog = [toThrow, toThrow.stack]; + } + err(`exiting due to exception: ${toLog}`); + } + quit(status); + }); + throw toThrow; + }; + } + if (typeof print != 'undefined') { + if (typeof console == 'undefined') console = {}; + console.log = print; + console.warn = console.error = + typeof printErr != 'undefined' ? printErr : print; + } + } else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { + if (ENVIRONMENT_IS_WORKER) { + scriptDirectory = self.location.href; + } else if ( + typeof document != 'undefined' && + document.currentScript + ) { + scriptDirectory = document.currentScript.src; + } + if (_scriptDir) { + scriptDirectory = _scriptDir; + } + if (scriptDirectory.indexOf('blob:') !== 0) { + scriptDirectory = scriptDirectory.substr( + 0, + scriptDirectory.replace(/[?#].*/, '').lastIndexOf('/') + 1 + ); + } else { + scriptDirectory = ''; + } + if ( + !( + typeof window == 'object' || + typeof importScripts == 'function' + ) + ) + throw new Error( + 'not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)' + ); + { + read_ = (url) => { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + xhr.send(null); + return xhr.responseText; + }; + if (ENVIRONMENT_IS_WORKER) { + readBinary = (url) => { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + xhr.responseType = 'arraybuffer'; + xhr.send(null); + return new Uint8Array(xhr.response); + }; + } + readAsync = (url, onload, onerror) => { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.responseType = 'arraybuffer'; + xhr.onload = () => { + if ( + xhr.status == 200 || + (xhr.status == 0 && xhr.response) + ) { + onload(xhr.response); + return; + } + onerror(); + }; + xhr.onerror = onerror; + xhr.send(null); + }; + } + setWindowTitle = (title) => (document.title = title); + } else { + throw new Error('environment detection error'); + } + var out = Module['print'] || console.log.bind(console); + var err = Module['printErr'] || console.error.bind(console); + Object.assign(Module, moduleOverrides); + moduleOverrides = null; + checkIncomingModuleAPI(); + if (Module['arguments']) arguments_ = Module['arguments']; + legacyModuleProp('arguments', 'arguments_'); + if (Module['thisProgram']) thisProgram = Module['thisProgram']; + legacyModuleProp('thisProgram', 'thisProgram'); + if (Module['quit']) quit_ = Module['quit']; + legacyModuleProp('quit', 'quit_'); + assert( + typeof Module['memoryInitializerPrefixURL'] == 'undefined', + 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead' + ); + assert( + typeof Module['pthreadMainPrefixURL'] == 'undefined', + 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead' + ); + assert( + typeof Module['cdInitializerPrefixURL'] == 'undefined', + 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead' + ); + assert( + typeof Module['filePackagePrefixURL'] == 'undefined', + 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead' + ); + assert( + typeof Module['read'] == 'undefined', + 'Module.read option was removed (modify read_ in JS)' + ); + assert( + typeof Module['readAsync'] == 'undefined', + 'Module.readAsync option was removed (modify readAsync in JS)' + ); + assert( + typeof Module['readBinary'] == 'undefined', + 'Module.readBinary option was removed (modify readBinary in JS)' + ); + assert( + typeof Module['setWindowTitle'] == 'undefined', + 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)' + ); + assert( + typeof Module['TOTAL_MEMORY'] == 'undefined', + 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY' + ); + legacyModuleProp('read', 'read_'); + legacyModuleProp('readAsync', 'readAsync'); + legacyModuleProp('readBinary', 'readBinary'); + legacyModuleProp('setWindowTitle', 'setWindowTitle'); + assert( + !ENVIRONMENT_IS_SHELL, + "shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable." + ); + var wasmBinary; + if (Module['wasmBinary']) wasmBinary = Module['wasmBinary']; + legacyModuleProp('wasmBinary', 'wasmBinary'); + var noExitRuntime = Module['noExitRuntime'] || false; + legacyModuleProp('noExitRuntime', 'noExitRuntime'); + if (typeof WebAssembly != 'object') { + abort('no native wasm support detected'); + } + var wasmMemory; + var ABORT = false; + var EXITSTATUS; + function assert(condition, text) { + if (!condition) { + abort('Assertion failed' + (text ? ': ' + text : '')); + } + } + var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64; + function updateMemoryViews() { + var b = wasmMemory.buffer; + Module['HEAP8'] = HEAP8 = new Int8Array(b); + Module['HEAP16'] = HEAP16 = new Int16Array(b); + Module['HEAP32'] = HEAP32 = new Int32Array(b); + Module['HEAPU8'] = HEAPU8 = new Uint8Array(b); + Module['HEAPU16'] = HEAPU16 = new Uint16Array(b); + Module['HEAPU32'] = HEAPU32 = new Uint32Array(b); + Module['HEAPF32'] = HEAPF32 = new Float32Array(b); + Module['HEAPF64'] = HEAPF64 = new Float64Array(b); + } + assert( + !Module['STACK_SIZE'], + 'STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time' + ); + assert( + typeof Int32Array != 'undefined' && + typeof Float64Array !== 'undefined' && + Int32Array.prototype.subarray != undefined && + Int32Array.prototype.set != undefined, + 'JS engine does not provide full typed array support' + ); + assert( + !Module['wasmMemory'], + 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally' + ); + assert( + !Module['INITIAL_MEMORY'], + 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically' + ); + var wasmTable; + function writeStackCookie() { + var max = _emscripten_stack_get_end(); + assert((max & 3) == 0); + if (max == 0) { + max += 4; + } + HEAPU32[max >> 2] = 34821223; + checkInt32(34821223); + HEAPU32[(max + 4) >> 2] = 2310721022; + checkInt32(2310721022); + HEAPU32[0 >> 2] = 1668509029; + checkInt32(1668509029); + } + function checkStackCookie() { + if (ABORT) return; + var max = _emscripten_stack_get_end(); + if (max == 0) { + max += 4; + } + var cookie1 = HEAPU32[max >> 2]; + var cookie2 = HEAPU32[(max + 4) >> 2]; + if (cookie1 != 34821223 || cookie2 != 2310721022) { + abort( + `Stack overflow! Stack cookie has been overwritten at ${ptrToString( + max + )}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString( + cookie2 + )} ${ptrToString(cookie1)}` + ); + } + if (HEAPU32[0 >> 2] != 1668509029) { + abort( + 'Runtime error: The application has corrupted its heap memory area (address zero)!' + ); + } + } + (function () { + var h16 = new Int16Array(1); + var h8 = new Int8Array(h16.buffer); + h16[0] = 25459; + if (h8[0] !== 115 || h8[1] !== 99) + throw 'Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)'; + })(); + var __ATPRERUN__ = []; + var __ATINIT__ = []; + var __ATEXIT__ = []; + var __ATPOSTRUN__ = []; + var runtimeInitialized = false; + var runtimeExited = false; + var runtimeKeepaliveCounter = 0; + function preRun() { + if (Module['preRun']) { + if (typeof Module['preRun'] == 'function') + Module['preRun'] = [Module['preRun']]; + while (Module['preRun'].length) { + addOnPreRun(Module['preRun'].shift()); + } + } + callRuntimeCallbacks(__ATPRERUN__); + } + function initRuntime() { + assert(!runtimeInitialized); + runtimeInitialized = true; + checkStackCookie(); + setStackLimits(); + if (!Module['noFSInit'] && !FS.init.initialized) FS.init(); + FS.ignorePermissions = false; + TTY.init(); + callRuntimeCallbacks(__ATINIT__); + } + function postRun() { + checkStackCookie(); + if (Module['postRun']) { + if (typeof Module['postRun'] == 'function') + Module['postRun'] = [Module['postRun']]; + while (Module['postRun'].length) { + addOnPostRun(Module['postRun'].shift()); + } + } + callRuntimeCallbacks(__ATPOSTRUN__); + } + function addOnPreRun(cb) { + __ATPRERUN__.unshift(cb); + } + function addOnInit(cb) { + __ATINIT__.unshift(cb); + } + function addOnPostRun(cb) { + __ATPOSTRUN__.unshift(cb); + } + assert( + Math.imul, + 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill' + ); + assert( + Math.fround, + 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill' + ); + assert( + Math.clz32, + 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill' + ); + assert( + Math.trunc, + 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill' + ); + var runDependencies = 0; + var runDependencyWatcher = null; + var dependenciesFulfilled = null; + var runDependencyTracking = {}; + function getUniqueRunDependency(id) { + var orig = id; + while (1) { + if (!runDependencyTracking[id]) return id; + id = orig + Math.random(); + } + } + function addRunDependency(id) { + runDependencies++; + if (Module['monitorRunDependencies']) { + Module['monitorRunDependencies'](runDependencies); + } + if (id) { + assert(!runDependencyTracking[id]); + runDependencyTracking[id] = 1; + if ( + runDependencyWatcher === null && + typeof setInterval != 'undefined' + ) { + runDependencyWatcher = setInterval(() => { + if (ABORT) { + clearInterval(runDependencyWatcher); + runDependencyWatcher = null; + return; + } + var shown = false; + for (var dep in runDependencyTracking) { + if (!shown) { + shown = true; + err('still waiting on run dependencies:'); + } + err('dependency: ' + dep); + } + if (shown) { + err('(end of list)'); + } + }, 1e4); + } + } else { + err('warning: run dependency added without ID'); + } + } + function removeRunDependency(id) { + runDependencies--; + if (Module['monitorRunDependencies']) { + Module['monitorRunDependencies'](runDependencies); + } + if (id) { + assert(runDependencyTracking[id]); + delete runDependencyTracking[id]; + } else { + err('warning: run dependency removed without ID'); + } + if (runDependencies == 0) { + if (runDependencyWatcher !== null) { + clearInterval(runDependencyWatcher); + runDependencyWatcher = null; + } + if (dependenciesFulfilled) { + var callback = dependenciesFulfilled; + dependenciesFulfilled = null; + callback(); + } + } + } + function abort(what) { + if (Module['onAbort']) { + Module['onAbort'](what); + } + what = 'Aborted(' + what + ')'; + err(what); + ABORT = true; + EXITSTATUS = 1; + if (runtimeInitialized) { + ___trap(); + } + var e = new WebAssembly.RuntimeError(what); + readyPromiseReject(e); + throw e; + } + var dataURIPrefix = 'data:application/octet-stream;base64,'; + function isDataURI(filename) { + return filename.startsWith(dataURIPrefix); + } + function isFileURI(filename) { + return filename.startsWith('file://'); + } + function createExportWrapper(name, fixedasm) { + return function () { + var displayName = name; + var asm = fixedasm; + if (!fixedasm) { + asm = Module['asm']; + } + assert( + runtimeInitialized, + 'native function `' + + displayName + + '` called before runtime initialization' + ); + assert( + !runtimeExited, + 'native function `' + + displayName + + '` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)' + ); + if (!asm[name]) { + assert( + asm[name], + 'exported native function `' + + displayName + + '` not found' + ); + } + return asm[name].apply(null, arguments); + }; + } + var wasmBinaryFile; + if (Module['locateFile']) { + wasmBinaryFile = 'privateer.wasm'; + if (!isDataURI(wasmBinaryFile)) { + wasmBinaryFile = locateFile(wasmBinaryFile); + } + } else { + wasmBinaryFile = new URL('privateer.wasm', import.meta.url).href; + } + function getBinarySync(file) { + if (file == wasmBinaryFile && wasmBinary) { + return new Uint8Array(wasmBinary); + } + if (readBinary) { + return readBinary(file); + } + throw 'both async and sync fetching of the wasm failed'; + } + function getBinaryPromise(binaryFile) { + if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) { + if (typeof fetch == 'function' && !isFileURI(binaryFile)) { + return fetch(binaryFile, { credentials: 'same-origin' }) + .then((response) => { + if (!response['ok']) { + throw ( + "failed to load wasm binary file at '" + + binaryFile + + "'" + ); + } + return response['arrayBuffer'](); + }) + .catch(() => getBinarySync(binaryFile)); + } else if (readAsync) { + return new Promise((resolve, reject) => { + readAsync( + binaryFile, + (response) => resolve(new Uint8Array(response)), + reject + ); + }); + } + } + return Promise.resolve().then(() => getBinarySync(binaryFile)); + } + function instantiateArrayBuffer(binaryFile, imports, receiver) { + return getBinaryPromise(binaryFile) + .then((binary) => WebAssembly.instantiate(binary, imports)) + .then((instance) => instance) + .then(receiver, (reason) => { + err('failed to asynchronously prepare wasm: ' + reason); + if (isFileURI(wasmBinaryFile)) { + err( + 'warning: Loading from a file URI (' + + wasmBinaryFile + + ') is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing' + ); + } + abort(reason); + }); + } + function instantiateAsync(binary, binaryFile, imports, callback) { + if ( + !binary && + typeof WebAssembly.instantiateStreaming == 'function' && + !isDataURI(binaryFile) && + !isFileURI(binaryFile) && + !ENVIRONMENT_IS_NODE && + typeof fetch == 'function' + ) { + return fetch(binaryFile, { credentials: 'same-origin' }).then( + (response) => { + var result = WebAssembly.instantiateStreaming( + response, + imports + ); + return result.then(callback, function (reason) { + err('wasm streaming compile failed: ' + reason); + err('falling back to ArrayBuffer instantiation'); + return instantiateArrayBuffer( + binaryFile, + imports, + callback + ); + }); + } + ); + } + return instantiateArrayBuffer(binaryFile, imports, callback); + } + function createWasm() { + var info = { + env: wasmImports, + wasi_snapshot_preview1: wasmImports, + }; + function receiveInstance(instance, module) { + var exports = instance.exports; + Module['asm'] = exports; + wasmMemory = Module['asm']['memory']; + assert(wasmMemory, 'memory not found in wasm exports'); + updateMemoryViews(); + wasmTable = Module['asm']['__indirect_function_table']; + assert(wasmTable, 'table not found in wasm exports'); + addOnInit(Module['asm']['__wasm_call_ctors']); + removeRunDependency('wasm-instantiate'); + return exports; + } + addRunDependency('wasm-instantiate'); + var trueModule = Module; + function receiveInstantiationResult(result) { + assert( + Module === trueModule, + 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?' + ); + trueModule = null; + receiveInstance(result['instance']); + } + if (Module['instantiateWasm']) { + try { + return Module['instantiateWasm'](info, receiveInstance); + } catch (e) { + err( + 'Module.instantiateWasm callback failed with error: ' + + e + ); + readyPromiseReject(e); + } + } + instantiateAsync( + wasmBinary, + wasmBinaryFile, + info, + receiveInstantiationResult + ).catch(readyPromiseReject); + return {}; + } + var tempDouble; + var tempI64; + function legacyModuleProp(prop, newName) { + if (!Object.getOwnPropertyDescriptor(Module, prop)) { + Object.defineProperty(Module, prop, { + configurable: true, + get() { + abort( + 'Module.' + + prop + + ' has been replaced with plain ' + + newName + + ' (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)' + ); + }, + }); + } + } + function ignoredModuleProp(prop) { + if (Object.getOwnPropertyDescriptor(Module, prop)) { + abort( + '`Module.' + + prop + + '` was supplied but `' + + prop + + '` not included in INCOMING_MODULE_JS_API' + ); + } + } + function isExportedByForceFilesystem(name) { + return ( + name === 'FS_createPath' || + name === 'FS_createDataFile' || + name === 'FS_createPreloadedFile' || + name === 'FS_unlink' || + name === 'addRunDependency' || + name === 'FS_createLazyFile' || + name === 'FS_createDevice' || + name === 'removeRunDependency' + ); + } + function missingGlobal(sym, msg) { + if (typeof globalThis !== 'undefined') { + Object.defineProperty(globalThis, sym, { + configurable: true, + get() { + warnOnce( + '`' + + sym + + '` is not longer defined by emscripten. ' + + msg + ); + return undefined; + }, + }); + } + } + missingGlobal('buffer', 'Please use HEAP8.buffer or wasmMemory.buffer'); + function missingLibrarySymbol(sym) { + if ( + typeof globalThis !== 'undefined' && + !Object.getOwnPropertyDescriptor(globalThis, sym) + ) { + Object.defineProperty(globalThis, sym, { + configurable: true, + get() { + var msg = + '`' + + sym + + '` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line'; + var librarySymbol = sym; + if (!librarySymbol.startsWith('_')) { + librarySymbol = '$' + sym; + } + msg += + " (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='" + + librarySymbol + + "')"; + if (isExportedByForceFilesystem(sym)) { + msg += + '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you'; + } + warnOnce(msg); + return undefined; + }, + }); + } + unexportedRuntimeSymbol(sym); + } + function unexportedRuntimeSymbol(sym) { + if (!Object.getOwnPropertyDescriptor(Module, sym)) { + Object.defineProperty(Module, sym, { + configurable: true, + get() { + var msg = + "'" + + sym + + "' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)"; + if (isExportedByForceFilesystem(sym)) { + msg += + '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you'; + } + abort(msg); + }, + }); + } + } + var MAX_UINT8 = 2 ** 8 - 1; + var MAX_UINT16 = 2 ** 16 - 1; + var MAX_UINT32 = 2 ** 32 - 1; + var MAX_UINT53 = 2 ** 53 - 1; + var MAX_UINT64 = 2 ** 64 - 1; + var MIN_INT8 = -(2 ** (8 - 1)) + 1; + var MIN_INT16 = -(2 ** (16 - 1)) + 1; + var MIN_INT32 = -(2 ** (32 - 1)) + 1; + var MIN_INT53 = -(2 ** (53 - 1)) + 1; + var MIN_INT64 = -(2 ** (64 - 1)) + 1; + function checkInt(value, bits, min, max) { + assert( + Number.isInteger(Number(value)), + 'attempt to write non-integer (' + value + ') into integer heap' + ); + assert( + value <= max, + 'value (' + + value + + ') too large to write as ' + + bits + + '-bit value' + ); + assert( + value >= min, + 'value (' + + value + + ') too small to write as ' + + bits + + '-bit value' + ); + } + var checkInt8 = (value) => checkInt(value, 8, MIN_INT8, MAX_UINT8); + var checkInt16 = (value) => checkInt(value, 16, MIN_INT16, MAX_UINT16); + var checkInt32 = (value) => checkInt(value, 32, MIN_INT32, MAX_UINT32); + var checkInt64 = (value) => checkInt(value, 64, MIN_INT64, MAX_UINT64); + function ExitStatus(status) { + this.name = 'ExitStatus'; + this.message = `Program terminated with exit(${status})`; + this.status = status; + } + var callRuntimeCallbacks = (callbacks) => { + while (callbacks.length > 0) { + callbacks.shift()(Module); + } + }; + function getCppExceptionTag() { + return Module['asm']['__cpp_exception']; + } + function getCppExceptionThrownObjectFromWebAssemblyException(ex) { + var unwind_header = ex.getArg(getCppExceptionTag(), 0); + return ___thrown_object_from_unwind_exception(unwind_header); + } + var withStackSave = (f) => { + var stack = stackSave(); + var ret = f(); + stackRestore(stack); + return ret; + }; + var UTF8Decoder = + typeof TextDecoder != 'undefined' + ? new TextDecoder('utf8') + : undefined; + var UTF8ArrayToString = (heapOrArray, idx, maxBytesToRead) => { + var endIdx = idx + maxBytesToRead; + var endPtr = idx; + while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr; + if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) { + return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr)); + } + var str = ''; + while (idx < endPtr) { + var u0 = heapOrArray[idx++]; + if (!(u0 & 128)) { + str += String.fromCharCode(u0); + continue; + } + var u1 = heapOrArray[idx++] & 63; + if ((u0 & 224) == 192) { + str += String.fromCharCode(((u0 & 31) << 6) | u1); + continue; + } + var u2 = heapOrArray[idx++] & 63; + if ((u0 & 240) == 224) { + u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; + } else { + if ((u0 & 248) != 240) + warnOnce( + 'Invalid UTF-8 leading byte ' + + ptrToString(u0) + + ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!' + ); + u0 = + ((u0 & 7) << 18) | + (u1 << 12) | + (u2 << 6) | + (heapOrArray[idx++] & 63); + } + if (u0 < 65536) { + str += String.fromCharCode(u0); + } else { + var ch = u0 - 65536; + str += String.fromCharCode( + 55296 | (ch >> 10), + 56320 | (ch & 1023) + ); + } + } + return str; + }; + var UTF8ToString = (ptr, maxBytesToRead) => { + assert(typeof ptr == 'number'); + return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ''; + }; + var getExceptionMessageCommon = (ptr) => + withStackSave(() => { + var type_addr_addr = stackAlloc(4); + var message_addr_addr = stackAlloc(4); + ___get_exception_message( + ptr, + type_addr_addr, + message_addr_addr + ); + var type_addr = HEAPU32[type_addr_addr >> 2]; + var message_addr = HEAPU32[message_addr_addr >> 2]; + var type = UTF8ToString(type_addr); + _free(type_addr); + var message; + if (message_addr) { + message = UTF8ToString(message_addr); + _free(message_addr); + } + return [type, message]; + }); + function getExceptionMessage(ex) { + var ptr = getCppExceptionThrownObjectFromWebAssemblyException(ex); + return getExceptionMessageCommon(ptr); + } + Module['getExceptionMessage'] = getExceptionMessage; + var ptrToString = (ptr) => { + assert(typeof ptr === 'number'); + ptr >>>= 0; + return '0x' + ptr.toString(16).padStart(8, '0'); + }; + var setStackLimits = () => { + var stackLow = _emscripten_stack_get_base(); + var stackHigh = _emscripten_stack_get_end(); + ___set_stack_limits(stackLow, stackHigh); + }; + var warnOnce = (text) => { + if (!warnOnce.shown) warnOnce.shown = {}; + if (!warnOnce.shown[text]) { + warnOnce.shown[text] = 1; + if (ENVIRONMENT_IS_NODE) text = 'warning: ' + text; + err(text); + } + }; + var ___assert_fail = (condition, filename, line, func) => { + abort( + `Assertion failed: ${UTF8ToString(condition)}, at: ` + + [ + filename ? UTF8ToString(filename) : 'unknown filename', + line, + func ? UTF8ToString(func) : 'unknown function', + ] + ); + }; + var ___handle_stack_overflow = (requested) => { + var base = _emscripten_stack_get_base(); + var end = _emscripten_stack_get_end(); + abort( + `stack overflow (Attempt to set SP to ${ptrToString( + requested + )}` + + `, with stack limits [${ptrToString(end)} - ${ptrToString( + base + )}` + + ']). If you require more stack space build with -sSTACK_SIZE=' + ); + }; + var setErrNo = (value) => { + HEAP32[___errno_location() >> 2] = value; + checkInt32(value); + return value; + }; + var PATH = { + isAbs: (path) => path.charAt(0) === '/', + splitPath: (filename) => { + var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; + return splitPathRe.exec(filename).slice(1); + }, + normalizeArray: (parts, allowAboveRoot) => { + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + if (allowAboveRoot) { + for (; up; up--) { + parts.unshift('..'); + } + } + return parts; + }, + normalize: (path) => { + var isAbsolute = PATH.isAbs(path), + trailingSlash = path.substr(-1) === '/'; + path = PATH.normalizeArray( + path.split('/').filter((p) => !!p), + !isAbsolute + ).join('/'); + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + return (isAbsolute ? '/' : '') + path; + }, + dirname: (path) => { + var result = PATH.splitPath(path), + root = result[0], + dir = result[1]; + if (!root && !dir) { + return '.'; + } + if (dir) { + dir = dir.substr(0, dir.length - 1); + } + return root + dir; + }, + basename: (path) => { + if (path === '/') return '/'; + path = PATH.normalize(path); + path = path.replace(/\/$/, ''); + var lastSlash = path.lastIndexOf('/'); + if (lastSlash === -1) return path; + return path.substr(lastSlash + 1); + }, + join: function () { + var paths = Array.prototype.slice.call(arguments); + return PATH.normalize(paths.join('/')); + }, + join2: (l, r) => PATH.normalize(l + '/' + r), + }; + var initRandomFill = () => { + if ( + typeof crypto == 'object' && + typeof crypto['getRandomValues'] == 'function' + ) { + return (view) => crypto.getRandomValues(view); + } else if (ENVIRONMENT_IS_NODE) { + try { + var crypto_module = require('crypto'); + var randomFillSync = crypto_module['randomFillSync']; + if (randomFillSync) { + return (view) => crypto_module['randomFillSync'](view); + } + var randomBytes = crypto_module['randomBytes']; + return (view) => ( + view.set(randomBytes(view.byteLength)), view + ); + } catch (e) {} + } + abort( + 'no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: (array) => { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };' + ); + }; + var randomFill = (view) => (randomFill = initRandomFill())(view); + var PATH_FS = { + resolve: function () { + var resolvedPath = '', + resolvedAbsolute = false; + for ( + var i = arguments.length - 1; + i >= -1 && !resolvedAbsolute; + i-- + ) { + var path = i >= 0 ? arguments[i] : FS.cwd(); + if (typeof path != 'string') { + throw new TypeError( + 'Arguments to path.resolve must be strings' + ); + } else if (!path) { + return ''; + } + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = PATH.isAbs(path); + } + resolvedPath = PATH.normalizeArray( + resolvedPath.split('/').filter((p) => !!p), + !resolvedAbsolute + ).join('/'); + return (resolvedAbsolute ? '/' : '') + resolvedPath || '.'; + }, + relative: (from, to) => { + from = PATH_FS.resolve(from).substr(1); + to = PATH_FS.resolve(to).substr(1); + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== '') break; + } + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + var fromParts = trim(from.split('/')); + var toParts = trim(to.split('/')); + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + outputParts = outputParts.concat( + toParts.slice(samePartsLength) + ); + return outputParts.join('/'); + }, + }; + var FS_stdin_getChar_buffer = []; + var lengthBytesUTF8 = (str) => { + var len = 0; + for (var i = 0; i < str.length; ++i) { + var c = str.charCodeAt(i); + if (c <= 127) { + len++; + } else if (c <= 2047) { + len += 2; + } else if (c >= 55296 && c <= 57343) { + len += 4; + ++i; + } else { + len += 3; + } + } + return len; + }; + var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => { + assert(typeof str === 'string'); + if (!(maxBytesToWrite > 0)) return 0; + var startIdx = outIdx; + var endIdx = outIdx + maxBytesToWrite - 1; + for (var i = 0; i < str.length; ++i) { + var u = str.charCodeAt(i); + if (u >= 55296 && u <= 57343) { + var u1 = str.charCodeAt(++i); + u = (65536 + ((u & 1023) << 10)) | (u1 & 1023); + } + if (u <= 127) { + if (outIdx >= endIdx) break; + heap[outIdx++] = u; + } else if (u <= 2047) { + if (outIdx + 1 >= endIdx) break; + heap[outIdx++] = 192 | (u >> 6); + heap[outIdx++] = 128 | (u & 63); + } else if (u <= 65535) { + if (outIdx + 2 >= endIdx) break; + heap[outIdx++] = 224 | (u >> 12); + heap[outIdx++] = 128 | ((u >> 6) & 63); + heap[outIdx++] = 128 | (u & 63); + } else { + if (outIdx + 3 >= endIdx) break; + if (u > 1114111) + warnOnce( + 'Invalid Unicode code point ' + + ptrToString(u) + + ' encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).' + ); + heap[outIdx++] = 240 | (u >> 18); + heap[outIdx++] = 128 | ((u >> 12) & 63); + heap[outIdx++] = 128 | ((u >> 6) & 63); + heap[outIdx++] = 128 | (u & 63); + } + } + heap[outIdx] = 0; + return outIdx - startIdx; + }; + function intArrayFromString(stringy, dontAddNull, length) { + var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1; + var u8array = new Array(len); + var numBytesWritten = stringToUTF8Array( + stringy, + u8array, + 0, + u8array.length + ); + if (dontAddNull) u8array.length = numBytesWritten; + return u8array; + } + var FS_stdin_getChar = () => { + if (!FS_stdin_getChar_buffer.length) { + var result = null; + if (ENVIRONMENT_IS_NODE) { + var BUFSIZE = 256; + var buf = Buffer.alloc(BUFSIZE); + var bytesRead = 0; + var fd = process.stdin.fd; + try { + bytesRead = fs.readSync(fd, buf, 0, BUFSIZE, -1); + } catch (e) { + if (e.toString().includes('EOF')) bytesRead = 0; + else throw e; + } + if (bytesRead > 0) { + result = buf.slice(0, bytesRead).toString('utf-8'); + } else { + result = null; + } + } else if ( + typeof window != 'undefined' && + typeof window.prompt == 'function' + ) { + result = window.prompt('Input: '); + if (result !== null) { + result += '\n'; + } + } else if (typeof readline == 'function') { + result = readline(); + if (result !== null) { + result += '\n'; + } + } + if (!result) { + return null; + } + FS_stdin_getChar_buffer = intArrayFromString(result, true); + } + return FS_stdin_getChar_buffer.shift(); + }; + var TTY = { + ttys: [], + init: function () {}, + shutdown: function () {}, + register: function (dev, ops) { + TTY.ttys[dev] = { input: [], output: [], ops: ops }; + FS.registerDevice(dev, TTY.stream_ops); + }, + stream_ops: { + open: function (stream) { + var tty = TTY.ttys[stream.node.rdev]; + if (!tty) { + throw new FS.ErrnoError(43); + } + stream.tty = tty; + stream.seekable = false; + }, + close: function (stream) { + stream.tty.ops.fsync(stream.tty); + }, + fsync: function (stream) { + stream.tty.ops.fsync(stream.tty); + }, + read: function (stream, buffer, offset, length, pos) { + if (!stream.tty || !stream.tty.ops.get_char) { + throw new FS.ErrnoError(60); + } + var bytesRead = 0; + for (var i = 0; i < length; i++) { + var result; + try { + result = stream.tty.ops.get_char(stream.tty); + } catch (e) { + throw new FS.ErrnoError(29); + } + if (result === undefined && bytesRead === 0) { + throw new FS.ErrnoError(6); + } + if (result === null || result === undefined) break; + bytesRead++; + buffer[offset + i] = result; + } + if (bytesRead) { + stream.node.timestamp = Date.now(); + } + return bytesRead; + }, + write: function (stream, buffer, offset, length, pos) { + if (!stream.tty || !stream.tty.ops.put_char) { + throw new FS.ErrnoError(60); + } + try { + for (var i = 0; i < length; i++) { + stream.tty.ops.put_char( + stream.tty, + buffer[offset + i] + ); + } + } catch (e) { + throw new FS.ErrnoError(29); + } + if (length) { + stream.node.timestamp = Date.now(); + } + return i; + }, + }, + default_tty_ops: { + get_char: function (tty) { + return FS_stdin_getChar(); + }, + put_char: function (tty, val) { + if (val === null || val === 10) { + out(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } else { + if (val != 0) tty.output.push(val); + } + }, + fsync: function (tty) { + if (tty.output && tty.output.length > 0) { + out(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } + }, + ioctl_tcgets: function (tty) { + return { + c_iflag: 25856, + c_oflag: 5, + c_cflag: 191, + c_lflag: 35387, + c_cc: [ + 3, 28, 127, 21, 4, 0, 1, 0, 17, 19, 26, 0, 18, 15, + 23, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, + ], + }; + }, + ioctl_tcsets: function (tty, optional_actions, data) { + return 0; + }, + ioctl_tiocgwinsz: function (tty) { + return [24, 80]; + }, + }, + default_tty1_ops: { + put_char: function (tty, val) { + if (val === null || val === 10) { + err(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } else { + if (val != 0) tty.output.push(val); + } + }, + fsync: function (tty) { + if (tty.output && tty.output.length > 0) { + err(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } + }, + }, + }; + var zeroMemory = (address, size) => { + HEAPU8.fill(0, address, address + size); + return address; + }; + var alignMemory = (size, alignment) => { + assert(alignment, 'alignment argument is required'); + return Math.ceil(size / alignment) * alignment; + }; + var mmapAlloc = (size) => { + size = alignMemory(size, 65536); + var ptr = _emscripten_builtin_memalign(65536, size); + if (!ptr) return 0; + return zeroMemory(ptr, size); + }; + var MEMFS = { + ops_table: null, + mount(mount) { + return MEMFS.createNode(null, '/', 16384 | 511, 0); + }, + createNode(parent, name, mode, dev) { + if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { + throw new FS.ErrnoError(63); + } + if (!MEMFS.ops_table) { + MEMFS.ops_table = { + dir: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + lookup: MEMFS.node_ops.lookup, + mknod: MEMFS.node_ops.mknod, + rename: MEMFS.node_ops.rename, + unlink: MEMFS.node_ops.unlink, + rmdir: MEMFS.node_ops.rmdir, + readdir: MEMFS.node_ops.readdir, + symlink: MEMFS.node_ops.symlink, + }, + stream: { llseek: MEMFS.stream_ops.llseek }, + }, + file: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + }, + stream: { + llseek: MEMFS.stream_ops.llseek, + read: MEMFS.stream_ops.read, + write: MEMFS.stream_ops.write, + allocate: MEMFS.stream_ops.allocate, + mmap: MEMFS.stream_ops.mmap, + msync: MEMFS.stream_ops.msync, + }, + }, + link: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + readlink: MEMFS.node_ops.readlink, + }, + stream: {}, + }, + chrdev: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + }, + stream: FS.chrdev_stream_ops, + }, + }; + } + var node = FS.createNode(parent, name, mode, dev); + if (FS.isDir(node.mode)) { + node.node_ops = MEMFS.ops_table.dir.node; + node.stream_ops = MEMFS.ops_table.dir.stream; + node.contents = {}; + } else if (FS.isFile(node.mode)) { + node.node_ops = MEMFS.ops_table.file.node; + node.stream_ops = MEMFS.ops_table.file.stream; + node.usedBytes = 0; + node.contents = null; + } else if (FS.isLink(node.mode)) { + node.node_ops = MEMFS.ops_table.link.node; + node.stream_ops = MEMFS.ops_table.link.stream; + } else if (FS.isChrdev(node.mode)) { + node.node_ops = MEMFS.ops_table.chrdev.node; + node.stream_ops = MEMFS.ops_table.chrdev.stream; + } + node.timestamp = Date.now(); + if (parent) { + parent.contents[name] = node; + parent.timestamp = node.timestamp; + } + return node; + }, + getFileDataAsTypedArray(node) { + if (!node.contents) return new Uint8Array(0); + if (node.contents.subarray) + return node.contents.subarray(0, node.usedBytes); + return new Uint8Array(node.contents); + }, + expandFileStorage(node, newCapacity) { + var prevCapacity = node.contents ? node.contents.length : 0; + if (prevCapacity >= newCapacity) return; + var CAPACITY_DOUBLING_MAX = 1024 * 1024; + newCapacity = Math.max( + newCapacity, + (prevCapacity * + (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125)) >>> + 0 + ); + if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); + var oldContents = node.contents; + node.contents = new Uint8Array(newCapacity); + if (node.usedBytes > 0) + node.contents.set( + oldContents.subarray(0, node.usedBytes), + 0 + ); + }, + resizeFileStorage(node, newSize) { + if (node.usedBytes == newSize) return; + if (newSize == 0) { + node.contents = null; + node.usedBytes = 0; + } else { + var oldContents = node.contents; + node.contents = new Uint8Array(newSize); + if (oldContents) { + node.contents.set( + oldContents.subarray( + 0, + Math.min(newSize, node.usedBytes) + ) + ); + } + node.usedBytes = newSize; + } + }, + node_ops: { + getattr(node) { + var attr = {}; + attr.dev = FS.isChrdev(node.mode) ? node.id : 1; + attr.ino = node.id; + attr.mode = node.mode; + attr.nlink = 1; + attr.uid = 0; + attr.gid = 0; + attr.rdev = node.rdev; + if (FS.isDir(node.mode)) { + attr.size = 4096; + } else if (FS.isFile(node.mode)) { + attr.size = node.usedBytes; + } else if (FS.isLink(node.mode)) { + attr.size = node.link.length; + } else { + attr.size = 0; + } + attr.atime = new Date(node.timestamp); + attr.mtime = new Date(node.timestamp); + attr.ctime = new Date(node.timestamp); + attr.blksize = 4096; + attr.blocks = Math.ceil(attr.size / attr.blksize); + return attr; + }, + setattr(node, attr) { + if (attr.mode !== undefined) { + node.mode = attr.mode; + } + if (attr.timestamp !== undefined) { + node.timestamp = attr.timestamp; + } + if (attr.size !== undefined) { + MEMFS.resizeFileStorage(node, attr.size); + } + }, + lookup(parent, name) { + throw FS.genericErrors[44]; + }, + mknod(parent, name, mode, dev) { + return MEMFS.createNode(parent, name, mode, dev); + }, + rename(old_node, new_dir, new_name) { + if (FS.isDir(old_node.mode)) { + var new_node; + try { + new_node = FS.lookupNode(new_dir, new_name); + } catch (e) {} + if (new_node) { + for (var i in new_node.contents) { + throw new FS.ErrnoError(55); + } + } + } + delete old_node.parent.contents[old_node.name]; + old_node.parent.timestamp = Date.now(); + old_node.name = new_name; + new_dir.contents[new_name] = old_node; + new_dir.timestamp = old_node.parent.timestamp; + old_node.parent = new_dir; + }, + unlink(parent, name) { + delete parent.contents[name]; + parent.timestamp = Date.now(); + }, + rmdir(parent, name) { + var node = FS.lookupNode(parent, name); + for (var i in node.contents) { + throw new FS.ErrnoError(55); + } + delete parent.contents[name]; + parent.timestamp = Date.now(); + }, + readdir(node) { + var entries = ['.', '..']; + for (var key in node.contents) { + if (!node.contents.hasOwnProperty(key)) { + continue; + } + entries.push(key); + } + return entries; + }, + symlink(parent, newname, oldpath) { + var node = MEMFS.createNode( + parent, + newname, + 511 | 40960, + 0 + ); + node.link = oldpath; + return node; + }, + readlink(node) { + if (!FS.isLink(node.mode)) { + throw new FS.ErrnoError(28); + } + return node.link; + }, + }, + stream_ops: { + read(stream, buffer, offset, length, position) { + var contents = stream.node.contents; + if (position >= stream.node.usedBytes) return 0; + var size = Math.min( + stream.node.usedBytes - position, + length + ); + assert(size >= 0); + if (size > 8 && contents.subarray) { + buffer.set( + contents.subarray(position, position + size), + offset + ); + } else { + for (var i = 0; i < size; i++) + buffer[offset + i] = contents[position + i]; + } + return size; + }, + write(stream, buffer, offset, length, position, canOwn) { + assert(!(buffer instanceof ArrayBuffer)); + if (buffer.buffer === HEAP8.buffer) { + canOwn = false; + } + if (!length) return 0; + var node = stream.node; + node.timestamp = Date.now(); + if ( + buffer.subarray && + (!node.contents || node.contents.subarray) + ) { + if (canOwn) { + assert( + position === 0, + 'canOwn must imply no weird position inside the file' + ); + node.contents = buffer.subarray( + offset, + offset + length + ); + node.usedBytes = length; + return length; + } else if (node.usedBytes === 0 && position === 0) { + node.contents = buffer.slice( + offset, + offset + length + ); + node.usedBytes = length; + return length; + } else if (position + length <= node.usedBytes) { + node.contents.set( + buffer.subarray(offset, offset + length), + position + ); + return length; + } + } + MEMFS.expandFileStorage(node, position + length); + if (node.contents.subarray && buffer.subarray) { + node.contents.set( + buffer.subarray(offset, offset + length), + position + ); + } else { + for (var i = 0; i < length; i++) { + node.contents[position + i] = buffer[offset + i]; + } + } + node.usedBytes = Math.max( + node.usedBytes, + position + length + ); + return length; + }, + llseek(stream, offset, whence) { + var position = offset; + if (whence === 1) { + position += stream.position; + } else if (whence === 2) { + if (FS.isFile(stream.node.mode)) { + position += stream.node.usedBytes; + } + } + if (position < 0) { + throw new FS.ErrnoError(28); + } + return position; + }, + allocate(stream, offset, length) { + MEMFS.expandFileStorage(stream.node, offset + length); + stream.node.usedBytes = Math.max( + stream.node.usedBytes, + offset + length + ); + }, + mmap(stream, length, position, prot, flags) { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + var ptr; + var allocated; + var contents = stream.node.contents; + if (!(flags & 2) && contents.buffer === HEAP8.buffer) { + allocated = false; + ptr = contents.byteOffset; + } else { + if ( + position > 0 || + position + length < contents.length + ) { + if (contents.subarray) { + contents = contents.subarray( + position, + position + length + ); + } else { + contents = Array.prototype.slice.call( + contents, + position, + position + length + ); + } + } + allocated = true; + ptr = mmapAlloc(length); + if (!ptr) { + throw new FS.ErrnoError(48); + } + HEAP8.set(contents, ptr); + } + return { ptr: ptr, allocated: allocated }; + }, + msync(stream, buffer, offset, length, mmapFlags) { + MEMFS.stream_ops.write( + stream, + buffer, + 0, + length, + offset, + false + ); + return 0; + }, + }, + }; + var asyncLoad = (url, onload, onerror, noRunDep) => { + var dep = !noRunDep ? getUniqueRunDependency(`al ${url}`) : ''; + readAsync( + url, + (arrayBuffer) => { + assert( + arrayBuffer, + `Loading data file "${url}" failed (no arrayBuffer).` + ); + onload(new Uint8Array(arrayBuffer)); + if (dep) removeRunDependency(dep); + }, + (event) => { + if (onerror) { + onerror(); + } else { + throw `Loading data file "${url}" failed.`; + } + } + ); + if (dep) addRunDependency(dep); + }; + var preloadPlugins = Module['preloadPlugins'] || []; + function FS_handledByPreloadPlugin( + byteArray, + fullname, + finish, + onerror + ) { + if (typeof Browser != 'undefined') Browser.init(); + var handled = false; + preloadPlugins.forEach(function (plugin) { + if (handled) return; + if (plugin['canHandle'](fullname)) { + plugin['handle'](byteArray, fullname, finish, onerror); + handled = true; + } + }); + return handled; + } + function FS_createPreloadedFile( + parent, + name, + url, + canRead, + canWrite, + onload, + onerror, + dontCreateFile, + canOwn, + preFinish + ) { + var fullname = name + ? PATH_FS.resolve(PATH.join2(parent, name)) + : parent; + var dep = getUniqueRunDependency(`cp ${fullname}`); + function processData(byteArray) { + function finish(byteArray) { + if (preFinish) preFinish(); + if (!dontCreateFile) { + FS.createDataFile( + parent, + name, + byteArray, + canRead, + canWrite, + canOwn + ); + } + if (onload) onload(); + removeRunDependency(dep); + } + if ( + FS_handledByPreloadPlugin( + byteArray, + fullname, + finish, + () => { + if (onerror) onerror(); + removeRunDependency(dep); + } + ) + ) { + return; + } + finish(byteArray); + } + addRunDependency(dep); + if (typeof url == 'string') { + asyncLoad(url, (byteArray) => processData(byteArray), onerror); + } else { + processData(url); + } + } + function FS_modeStringToFlags(str) { + var flagModes = { + r: 0, + 'r+': 2, + w: 512 | 64 | 1, + 'w+': 512 | 64 | 2, + a: 1024 | 64 | 1, + 'a+': 1024 | 64 | 2, + }; + var flags = flagModes[str]; + if (typeof flags == 'undefined') { + throw new Error(`Unknown file open mode: ${str}`); + } + return flags; + } + function FS_getMode(canRead, canWrite) { + var mode = 0; + if (canRead) mode |= 292 | 73; + if (canWrite) mode |= 146; + return mode; + } + var ERRNO_CODES = {}; + var NODEFS = { + isWindows: false, + staticInit: () => { + NODEFS.isWindows = !!process.platform.match(/^win/); + var flags = process.binding('constants'); + if (flags['fs']) { + flags = flags['fs']; + } + NODEFS.flagsForNodeMap = { + 1024: flags['O_APPEND'], + 64: flags['O_CREAT'], + 128: flags['O_EXCL'], + 256: flags['O_NOCTTY'], + 0: flags['O_RDONLY'], + 2: flags['O_RDWR'], + 4096: flags['O_SYNC'], + 512: flags['O_TRUNC'], + 1: flags['O_WRONLY'], + 131072: flags['O_NOFOLLOW'], + }; + assert(NODEFS.flagsForNodeMap['0'] === 0); + }, + convertNodeCode: (e) => { + var code = e.code; + assert( + code in ERRNO_CODES, + `unexpected node error code: ${code} (${e})` + ); + return ERRNO_CODES[code]; + }, + mount: (mount) => { + assert(ENVIRONMENT_IS_NODE); + return NODEFS.createNode( + null, + '/', + NODEFS.getMode(mount.opts.root), + 0 + ); + }, + createNode: (parent, name, mode, dev) => { + if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) { + throw new FS.ErrnoError(28); + } + var node = FS.createNode(parent, name, mode); + node.node_ops = NODEFS.node_ops; + node.stream_ops = NODEFS.stream_ops; + return node; + }, + getMode: (path) => { + var stat; + try { + stat = fs.lstatSync(path); + if (NODEFS.isWindows) { + stat.mode = stat.mode | ((stat.mode & 292) >> 2); + } + } catch (e) { + if (!e.code) throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + return stat.mode; + }, + realPath: (node) => { + var parts = []; + while (node.parent !== node) { + parts.push(node.name); + node = node.parent; + } + parts.push(node.mount.opts.root); + parts.reverse(); + return PATH.join.apply(null, parts); + }, + flagsForNode: (flags) => { + flags &= ~2097152; + flags &= ~2048; + flags &= ~32768; + flags &= ~524288; + flags &= ~65536; + var newFlags = 0; + for (var k in NODEFS.flagsForNodeMap) { + if (flags & k) { + newFlags |= NODEFS.flagsForNodeMap[k]; + flags ^= k; + } + } + if (flags) { + throw new FS.ErrnoError(28); + } + return newFlags; + }, + node_ops: { + getattr: (node) => { + var path = NODEFS.realPath(node); + var stat; + try { + stat = fs.lstatSync(path); + } catch (e) { + if (!e.code) throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + if (NODEFS.isWindows && !stat.blksize) { + stat.blksize = 4096; + } + if (NODEFS.isWindows && !stat.blocks) { + stat.blocks = + ((stat.size + stat.blksize - 1) / stat.blksize) | 0; + } + return { + dev: stat.dev, + ino: stat.ino, + mode: stat.mode, + nlink: stat.nlink, + uid: stat.uid, + gid: stat.gid, + rdev: stat.rdev, + size: stat.size, + atime: stat.atime, + mtime: stat.mtime, + ctime: stat.ctime, + blksize: stat.blksize, + blocks: stat.blocks, + }; + }, + setattr: (node, attr) => { + var path = NODEFS.realPath(node); + try { + if (attr.mode !== undefined) { + fs.chmodSync(path, attr.mode); + node.mode = attr.mode; + } + if (attr.timestamp !== undefined) { + var date = new Date(attr.timestamp); + fs.utimesSync(path, date, date); + } + if (attr.size !== undefined) { + fs.truncateSync(path, attr.size); + } + } catch (e) { + if (!e.code) throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + lookup: (parent, name) => { + var path = PATH.join2(NODEFS.realPath(parent), name); + var mode = NODEFS.getMode(path); + return NODEFS.createNode(parent, name, mode); + }, + mknod: (parent, name, mode, dev) => { + var node = NODEFS.createNode(parent, name, mode, dev); + var path = NODEFS.realPath(node); + try { + if (FS.isDir(node.mode)) { + fs.mkdirSync(path, node.mode); + } else { + fs.writeFileSync(path, '', { mode: node.mode }); + } + } catch (e) { + if (!e.code) throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + return node; + }, + rename: (oldNode, newDir, newName) => { + var oldPath = NODEFS.realPath(oldNode); + var newPath = PATH.join2(NODEFS.realPath(newDir), newName); + try { + fs.renameSync(oldPath, newPath); + } catch (e) { + if (!e.code) throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + oldNode.name = newName; + }, + unlink: (parent, name) => { + var path = PATH.join2(NODEFS.realPath(parent), name); + try { + fs.unlinkSync(path); + } catch (e) { + if (!e.code) throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + rmdir: (parent, name) => { + var path = PATH.join2(NODEFS.realPath(parent), name); + try { + fs.rmdirSync(path); + } catch (e) { + if (!e.code) throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + readdir: (node) => { + var path = NODEFS.realPath(node); + try { + return fs.readdirSync(path); + } catch (e) { + if (!e.code) throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + symlink: (parent, newName, oldPath) => { + var newPath = PATH.join2(NODEFS.realPath(parent), newName); + try { + fs.symlinkSync(oldPath, newPath); + } catch (e) { + if (!e.code) throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + readlink: (node) => { + var path = NODEFS.realPath(node); + try { + path = fs.readlinkSync(path); + path = nodePath.relative( + nodePath.resolve(node.mount.opts.root), + path + ); + return path; + } catch (e) { + if (!e.code) throw e; + if (e.code === 'UNKNOWN') throw new FS.ErrnoError(28); + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + }, + stream_ops: { + open: (stream) => { + var path = NODEFS.realPath(stream.node); + try { + if (FS.isFile(stream.node.mode)) { + stream.nfd = fs.openSync( + path, + NODEFS.flagsForNode(stream.flags) + ); + } + } catch (e) { + if (!e.code) throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + close: (stream) => { + try { + if (FS.isFile(stream.node.mode) && stream.nfd) { + fs.closeSync(stream.nfd); + } + } catch (e) { + if (!e.code) throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + read: (stream, buffer, offset, length, position) => { + if (length === 0) return 0; + try { + return fs.readSync( + stream.nfd, + Buffer.from(buffer.buffer), + offset, + length, + position + ); + } catch (e) { + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + write: (stream, buffer, offset, length, position) => { + try { + return fs.writeSync( + stream.nfd, + Buffer.from(buffer.buffer), + offset, + length, + position + ); + } catch (e) { + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + llseek: (stream, offset, whence) => { + var position = offset; + if (whence === 1) { + position += stream.position; + } else if (whence === 2) { + if (FS.isFile(stream.node.mode)) { + try { + var stat = fs.fstatSync(stream.nfd); + position += stat.size; + } catch (e) { + throw new FS.ErrnoError( + NODEFS.convertNodeCode(e) + ); + } + } + } + if (position < 0) { + throw new FS.ErrnoError(28); + } + return position; + }, + mmap: (stream, length, position, prot, flags) => { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + var ptr = mmapAlloc(length); + NODEFS.stream_ops.read( + stream, + HEAP8, + ptr, + length, + position + ); + return { ptr: ptr, allocated: true }; + }, + msync: (stream, buffer, offset, length, mmapFlags) => { + NODEFS.stream_ops.write( + stream, + buffer, + 0, + length, + offset, + false + ); + return 0; + }, + }, + }; + var ERRNO_MESSAGES = { + 0: 'Success', + 1: 'Arg list too long', + 2: 'Permission denied', + 3: 'Address already in use', + 4: 'Address not available', + 5: 'Address family not supported by protocol family', + 6: 'No more processes', + 7: 'Socket already connected', + 8: 'Bad file number', + 9: 'Trying to read unreadable message', + 10: 'Mount device busy', + 11: 'Operation canceled', + 12: 'No children', + 13: 'Connection aborted', + 14: 'Connection refused', + 15: 'Connection reset by peer', + 16: 'File locking deadlock error', + 17: 'Destination address required', + 18: 'Math arg out of domain of func', + 19: 'Quota exceeded', + 20: 'File exists', + 21: 'Bad address', + 22: 'File too large', + 23: 'Host is unreachable', + 24: 'Identifier removed', + 25: 'Illegal byte sequence', + 26: 'Connection already in progress', + 27: 'Interrupted system call', + 28: 'Invalid argument', + 29: 'I/O error', + 30: 'Socket is already connected', + 31: 'Is a directory', + 32: 'Too many symbolic links', + 33: 'Too many open files', + 34: 'Too many links', + 35: 'Message too long', + 36: 'Multihop attempted', + 37: 'File or path name too long', + 38: 'Network interface is not configured', + 39: 'Connection reset by network', + 40: 'Network is unreachable', + 41: 'Too many open files in system', + 42: 'No buffer space available', + 43: 'No such device', + 44: 'No such file or directory', + 45: 'Exec format error', + 46: 'No record locks available', + 47: 'The link has been severed', + 48: 'Not enough core', + 49: 'No message of desired type', + 50: 'Protocol not available', + 51: 'No space left on device', + 52: 'Function not implemented', + 53: 'Socket is not connected', + 54: 'Not a directory', + 55: 'Directory not empty', + 56: 'State not recoverable', + 57: 'Socket operation on non-socket', + 59: 'Not a typewriter', + 60: 'No such device or address', + 61: 'Value too large for defined data type', + 62: 'Previous owner died', + 63: 'Not super-user', + 64: 'Broken pipe', + 65: 'Protocol error', + 66: 'Unknown protocol', + 67: 'Protocol wrong type for socket', + 68: 'Math result not representable', + 69: 'Read only file system', + 70: 'Illegal seek', + 71: 'No such process', + 72: 'Stale file handle', + 73: 'Connection timed out', + 74: 'Text file busy', + 75: 'Cross-device link', + 100: 'Device not a stream', + 101: 'Bad font file fmt', + 102: 'Invalid slot', + 103: 'Invalid request code', + 104: 'No anode', + 105: 'Block device required', + 106: 'Channel number out of range', + 107: 'Level 3 halted', + 108: 'Level 3 reset', + 109: 'Link number out of range', + 110: 'Protocol driver not attached', + 111: 'No CSI structure available', + 112: 'Level 2 halted', + 113: 'Invalid exchange', + 114: 'Invalid request descriptor', + 115: 'Exchange full', + 116: 'No data (for no delay io)', + 117: 'Timer expired', + 118: 'Out of streams resources', + 119: 'Machine is not on the network', + 120: 'Package not installed', + 121: 'The object is remote', + 122: 'Advertise error', + 123: 'Srmount error', + 124: 'Communication error on send', + 125: 'Cross mount point (not really error)', + 126: 'Given log. name not unique', + 127: 'f.d. invalid for this operation', + 128: 'Remote address changed', + 129: 'Can access a needed shared lib', + 130: 'Accessing a corrupted shared lib', + 131: '.lib section in a.out corrupted', + 132: 'Attempting to link in too many libs', + 133: 'Attempting to exec a shared library', + 135: 'Streams pipe error', + 136: 'Too many users', + 137: 'Socket type not supported', + 138: 'Not supported', + 139: 'Protocol family not supported', + 140: "Can't send after socket shutdown", + 141: 'Too many references', + 142: 'Host is down', + 148: 'No medium (in tape drive)', + 156: 'Level 2 not synchronized', + }; + function demangle(func) { + warnOnce( + 'warning: build with -sDEMANGLE_SUPPORT to link in libcxxabi demangling' + ); + return func; + } + function demangleAll(text) { + var regex = /\b_Z[\w\d_]+/g; + return text.replace(regex, function (x) { + var y = demangle(x); + return x === y ? x : y + ' [' + x + ']'; + }); + } + var FS = { + root: null, + mounts: [], + devices: {}, + streams: [], + nextInode: 1, + nameTable: null, + currentPath: '/', + initialized: false, + ignorePermissions: true, + ErrnoError: null, + genericErrors: {}, + filesystems: null, + syncFSRequests: 0, + lookupPath: (path, opts = {}) => { + path = PATH_FS.resolve(path); + if (!path) return { path: '', node: null }; + var defaults = { follow_mount: true, recurse_count: 0 }; + opts = Object.assign(defaults, opts); + if (opts.recurse_count > 8) { + throw new FS.ErrnoError(32); + } + var parts = path.split('/').filter((p) => !!p); + var current = FS.root; + var current_path = '/'; + for (var i = 0; i < parts.length; i++) { + var islast = i === parts.length - 1; + if (islast && opts.parent) { + break; + } + current = FS.lookupNode(current, parts[i]); + current_path = PATH.join2(current_path, parts[i]); + if (FS.isMountpoint(current)) { + if (!islast || (islast && opts.follow_mount)) { + current = current.mounted.root; + } + } + if (!islast || opts.follow) { + var count = 0; + while (FS.isLink(current.mode)) { + var link = FS.readlink(current_path); + current_path = PATH_FS.resolve( + PATH.dirname(current_path), + link + ); + var lookup = FS.lookupPath(current_path, { + recurse_count: opts.recurse_count + 1, + }); + current = lookup.node; + if (count++ > 40) { + throw new FS.ErrnoError(32); + } + } + } + } + return { path: current_path, node: current }; + }, + getPath: (node) => { + var path; + while (true) { + if (FS.isRoot(node)) { + var mount = node.mount.mountpoint; + if (!path) return mount; + return mount[mount.length - 1] !== '/' + ? `${mount}/${path}` + : mount + path; + } + path = path ? `${node.name}/${path}` : node.name; + node = node.parent; + } + }, + hashName: (parentid, name) => { + var hash = 0; + for (var i = 0; i < name.length; i++) { + hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0; + } + return ((parentid + hash) >>> 0) % FS.nameTable.length; + }, + hashAddNode: (node) => { + var hash = FS.hashName(node.parent.id, node.name); + node.name_next = FS.nameTable[hash]; + FS.nameTable[hash] = node; + }, + hashRemoveNode: (node) => { + var hash = FS.hashName(node.parent.id, node.name); + if (FS.nameTable[hash] === node) { + FS.nameTable[hash] = node.name_next; + } else { + var current = FS.nameTable[hash]; + while (current) { + if (current.name_next === node) { + current.name_next = node.name_next; + break; + } + current = current.name_next; + } + } + }, + lookupNode: (parent, name) => { + var errCode = FS.mayLookup(parent); + if (errCode) { + throw new FS.ErrnoError(errCode, parent); + } + var hash = FS.hashName(parent.id, name); + for ( + var node = FS.nameTable[hash]; + node; + node = node.name_next + ) { + var nodeName = node.name; + if (node.parent.id === parent.id && nodeName === name) { + return node; + } + } + return FS.lookup(parent, name); + }, + createNode: (parent, name, mode, rdev) => { + assert(typeof parent == 'object'); + var node = new FS.FSNode(parent, name, mode, rdev); + FS.hashAddNode(node); + return node; + }, + destroyNode: (node) => { + FS.hashRemoveNode(node); + }, + isRoot: (node) => node === node.parent, + isMountpoint: (node) => !!node.mounted, + isFile: (mode) => (mode & 61440) === 32768, + isDir: (mode) => (mode & 61440) === 16384, + isLink: (mode) => (mode & 61440) === 40960, + isChrdev: (mode) => (mode & 61440) === 8192, + isBlkdev: (mode) => (mode & 61440) === 24576, + isFIFO: (mode) => (mode & 61440) === 4096, + isSocket: (mode) => (mode & 49152) === 49152, + flagsToPermissionString: (flag) => { + var perms = ['r', 'w', 'rw'][flag & 3]; + if (flag & 512) { + perms += 'w'; + } + return perms; + }, + nodePermissions: (node, perms) => { + if (FS.ignorePermissions) { + return 0; + } + if (perms.includes('r') && !(node.mode & 292)) { + return 2; + } else if (perms.includes('w') && !(node.mode & 146)) { + return 2; + } else if (perms.includes('x') && !(node.mode & 73)) { + return 2; + } + return 0; + }, + mayLookup: (dir) => { + var errCode = FS.nodePermissions(dir, 'x'); + if (errCode) return errCode; + if (!dir.node_ops.lookup) return 2; + return 0; + }, + mayCreate: (dir, name) => { + try { + var node = FS.lookupNode(dir, name); + return 20; + } catch (e) {} + return FS.nodePermissions(dir, 'wx'); + }, + mayDelete: (dir, name, isdir) => { + var node; + try { + node = FS.lookupNode(dir, name); + } catch (e) { + return e.errno; + } + var errCode = FS.nodePermissions(dir, 'wx'); + if (errCode) { + return errCode; + } + if (isdir) { + if (!FS.isDir(node.mode)) { + return 54; + } + if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) { + return 10; + } + } else { + if (FS.isDir(node.mode)) { + return 31; + } + } + return 0; + }, + mayOpen: (node, flags) => { + if (!node) { + return 44; + } + if (FS.isLink(node.mode)) { + return 32; + } else if (FS.isDir(node.mode)) { + if ( + FS.flagsToPermissionString(flags) !== 'r' || + flags & 512 + ) { + return 31; + } + } + return FS.nodePermissions( + node, + FS.flagsToPermissionString(flags) + ); + }, + MAX_OPEN_FDS: 4096, + nextfd: () => { + for (var fd = 0; fd <= FS.MAX_OPEN_FDS; fd++) { + if (!FS.streams[fd]) { + return fd; + } + } + throw new FS.ErrnoError(33); + }, + getStreamChecked: (fd) => { + var stream = FS.getStream(fd); + if (!stream) { + throw new FS.ErrnoError(8); + } + return stream; + }, + getStream: (fd) => FS.streams[fd], + createStream: (stream, fd = -1) => { + if (!FS.FSStream) { + FS.FSStream = function () { + this.shared = {}; + }; + FS.FSStream.prototype = {}; + Object.defineProperties(FS.FSStream.prototype, { + object: { + get() { + return this.node; + }, + set(val) { + this.node = val; + }, + }, + isRead: { + get() { + return (this.flags & 2097155) !== 1; + }, + }, + isWrite: { + get() { + return (this.flags & 2097155) !== 0; + }, + }, + isAppend: { + get() { + return this.flags & 1024; + }, + }, + flags: { + get() { + return this.shared.flags; + }, + set(val) { + this.shared.flags = val; + }, + }, + position: { + get() { + return this.shared.position; + }, + set(val) { + this.shared.position = val; + }, + }, + }); + } + stream = Object.assign(new FS.FSStream(), stream); + if (fd == -1) { + fd = FS.nextfd(); + } + stream.fd = fd; + FS.streams[fd] = stream; + return stream; + }, + closeStream: (fd) => { + FS.streams[fd] = null; + }, + chrdev_stream_ops: { + open: (stream) => { + var device = FS.getDevice(stream.node.rdev); + stream.stream_ops = device.stream_ops; + if (stream.stream_ops.open) { + stream.stream_ops.open(stream); + } + }, + llseek: () => { + throw new FS.ErrnoError(70); + }, + }, + major: (dev) => dev >> 8, + minor: (dev) => dev & 255, + makedev: (ma, mi) => (ma << 8) | mi, + registerDevice: (dev, ops) => { + FS.devices[dev] = { stream_ops: ops }; + }, + getDevice: (dev) => FS.devices[dev], + getMounts: (mount) => { + var mounts = []; + var check = [mount]; + while (check.length) { + var m = check.pop(); + mounts.push(m); + check.push.apply(check, m.mounts); + } + return mounts; + }, + syncfs: (populate, callback) => { + if (typeof populate == 'function') { + callback = populate; + populate = false; + } + FS.syncFSRequests++; + if (FS.syncFSRequests > 1) { + err( + `warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work` + ); + } + var mounts = FS.getMounts(FS.root.mount); + var completed = 0; + function doCallback(errCode) { + assert(FS.syncFSRequests > 0); + FS.syncFSRequests--; + return callback(errCode); + } + function done(errCode) { + if (errCode) { + if (!done.errored) { + done.errored = true; + return doCallback(errCode); + } + return; + } + if (++completed >= mounts.length) { + doCallback(null); + } + } + mounts.forEach((mount) => { + if (!mount.type.syncfs) { + return done(null); + } + mount.type.syncfs(mount, populate, done); + }); + }, + mount: (type, opts, mountpoint) => { + if (typeof type == 'string') { + throw type; + } + var root = mountpoint === '/'; + var pseudo = !mountpoint; + var node; + if (root && FS.root) { + throw new FS.ErrnoError(10); + } else if (!root && !pseudo) { + var lookup = FS.lookupPath(mountpoint, { + follow_mount: false, + }); + mountpoint = lookup.path; + node = lookup.node; + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + if (!FS.isDir(node.mode)) { + throw new FS.ErrnoError(54); + } + } + var mount = { + type: type, + opts: opts, + mountpoint: mountpoint, + mounts: [], + }; + var mountRoot = type.mount(mount); + mountRoot.mount = mount; + mount.root = mountRoot; + if (root) { + FS.root = mountRoot; + } else if (node) { + node.mounted = mount; + if (node.mount) { + node.mount.mounts.push(mount); + } + } + return mountRoot; + }, + unmount: (mountpoint) => { + var lookup = FS.lookupPath(mountpoint, { follow_mount: false }); + if (!FS.isMountpoint(lookup.node)) { + throw new FS.ErrnoError(28); + } + var node = lookup.node; + var mount = node.mounted; + var mounts = FS.getMounts(mount); + Object.keys(FS.nameTable).forEach((hash) => { + var current = FS.nameTable[hash]; + while (current) { + var next = current.name_next; + if (mounts.includes(current.mount)) { + FS.destroyNode(current); + } + current = next; + } + }); + node.mounted = null; + var idx = node.mount.mounts.indexOf(mount); + assert(idx !== -1); + node.mount.mounts.splice(idx, 1); + }, + lookup: (parent, name) => parent.node_ops.lookup(parent, name), + mknod: (path, mode, dev) => { + var lookup = FS.lookupPath(path, { parent: true }); + var parent = lookup.node; + var name = PATH.basename(path); + if (!name || name === '.' || name === '..') { + throw new FS.ErrnoError(28); + } + var errCode = FS.mayCreate(parent, name); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.mknod) { + throw new FS.ErrnoError(63); + } + return parent.node_ops.mknod(parent, name, mode, dev); + }, + create: (path, mode) => { + mode = mode !== undefined ? mode : 438; + mode &= 4095; + mode |= 32768; + return FS.mknod(path, mode, 0); + }, + mkdir: (path, mode) => { + mode = mode !== undefined ? mode : 511; + mode &= 511 | 512; + mode |= 16384; + return FS.mknod(path, mode, 0); + }, + mkdirTree: (path, mode) => { + var dirs = path.split('/'); + var d = ''; + for (var i = 0; i < dirs.length; ++i) { + if (!dirs[i]) continue; + d += '/' + dirs[i]; + try { + FS.mkdir(d, mode); + } catch (e) { + if (e.errno != 20) throw e; + } + } + }, + mkdev: (path, mode, dev) => { + if (typeof dev == 'undefined') { + dev = mode; + mode = 438; + } + mode |= 8192; + return FS.mknod(path, mode, dev); + }, + symlink: (oldpath, newpath) => { + if (!PATH_FS.resolve(oldpath)) { + throw new FS.ErrnoError(44); + } + var lookup = FS.lookupPath(newpath, { parent: true }); + var parent = lookup.node; + if (!parent) { + throw new FS.ErrnoError(44); + } + var newname = PATH.basename(newpath); + var errCode = FS.mayCreate(parent, newname); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.symlink) { + throw new FS.ErrnoError(63); + } + return parent.node_ops.symlink(parent, newname, oldpath); + }, + rename: (old_path, new_path) => { + var old_dirname = PATH.dirname(old_path); + var new_dirname = PATH.dirname(new_path); + var old_name = PATH.basename(old_path); + var new_name = PATH.basename(new_path); + var lookup, old_dir, new_dir; + lookup = FS.lookupPath(old_path, { parent: true }); + old_dir = lookup.node; + lookup = FS.lookupPath(new_path, { parent: true }); + new_dir = lookup.node; + if (!old_dir || !new_dir) throw new FS.ErrnoError(44); + if (old_dir.mount !== new_dir.mount) { + throw new FS.ErrnoError(75); + } + var old_node = FS.lookupNode(old_dir, old_name); + var relative = PATH_FS.relative(old_path, new_dirname); + if (relative.charAt(0) !== '.') { + throw new FS.ErrnoError(28); + } + relative = PATH_FS.relative(new_path, old_dirname); + if (relative.charAt(0) !== '.') { + throw new FS.ErrnoError(55); + } + var new_node; + try { + new_node = FS.lookupNode(new_dir, new_name); + } catch (e) {} + if (old_node === new_node) { + return; + } + var isdir = FS.isDir(old_node.mode); + var errCode = FS.mayDelete(old_dir, old_name, isdir); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + errCode = new_node + ? FS.mayDelete(new_dir, new_name, isdir) + : FS.mayCreate(new_dir, new_name); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!old_dir.node_ops.rename) { + throw new FS.ErrnoError(63); + } + if ( + FS.isMountpoint(old_node) || + (new_node && FS.isMountpoint(new_node)) + ) { + throw new FS.ErrnoError(10); + } + if (new_dir !== old_dir) { + errCode = FS.nodePermissions(old_dir, 'w'); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + } + FS.hashRemoveNode(old_node); + try { + old_dir.node_ops.rename(old_node, new_dir, new_name); + } catch (e) { + throw e; + } finally { + FS.hashAddNode(old_node); + } + }, + rmdir: (path) => { + var lookup = FS.lookupPath(path, { parent: true }); + var parent = lookup.node; + var name = PATH.basename(path); + var node = FS.lookupNode(parent, name); + var errCode = FS.mayDelete(parent, name, true); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.rmdir) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + parent.node_ops.rmdir(parent, name); + FS.destroyNode(node); + }, + readdir: (path) => { + var lookup = FS.lookupPath(path, { follow: true }); + var node = lookup.node; + if (!node.node_ops.readdir) { + throw new FS.ErrnoError(54); + } + return node.node_ops.readdir(node); + }, + unlink: (path) => { + var lookup = FS.lookupPath(path, { parent: true }); + var parent = lookup.node; + if (!parent) { + throw new FS.ErrnoError(44); + } + var name = PATH.basename(path); + var node = FS.lookupNode(parent, name); + var errCode = FS.mayDelete(parent, name, false); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.unlink) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + parent.node_ops.unlink(parent, name); + FS.destroyNode(node); + }, + readlink: (path) => { + var lookup = FS.lookupPath(path); + var link = lookup.node; + if (!link) { + throw new FS.ErrnoError(44); + } + if (!link.node_ops.readlink) { + throw new FS.ErrnoError(28); + } + return PATH_FS.resolve( + FS.getPath(link.parent), + link.node_ops.readlink(link) + ); + }, + stat: (path, dontFollow) => { + var lookup = FS.lookupPath(path, { follow: !dontFollow }); + var node = lookup.node; + if (!node) { + throw new FS.ErrnoError(44); + } + if (!node.node_ops.getattr) { + throw new FS.ErrnoError(63); + } + return node.node_ops.getattr(node); + }, + lstat: (path) => FS.stat(path, true), + chmod: (path, mode, dontFollow) => { + var node; + if (typeof path == 'string') { + var lookup = FS.lookupPath(path, { follow: !dontFollow }); + node = lookup.node; + } else { + node = path; + } + if (!node.node_ops.setattr) { + throw new FS.ErrnoError(63); + } + node.node_ops.setattr(node, { + mode: (mode & 4095) | (node.mode & ~4095), + timestamp: Date.now(), + }); + }, + lchmod: (path, mode) => { + FS.chmod(path, mode, true); + }, + fchmod: (fd, mode) => { + var stream = FS.getStreamChecked(fd); + FS.chmod(stream.node, mode); + }, + chown: (path, uid, gid, dontFollow) => { + var node; + if (typeof path == 'string') { + var lookup = FS.lookupPath(path, { follow: !dontFollow }); + node = lookup.node; + } else { + node = path; + } + if (!node.node_ops.setattr) { + throw new FS.ErrnoError(63); + } + node.node_ops.setattr(node, { timestamp: Date.now() }); + }, + lchown: (path, uid, gid) => { + FS.chown(path, uid, gid, true); + }, + fchown: (fd, uid, gid) => { + var stream = FS.getStreamChecked(fd); + FS.chown(stream.node, uid, gid); + }, + truncate: (path, len) => { + if (len < 0) { + throw new FS.ErrnoError(28); + } + var node; + if (typeof path == 'string') { + var lookup = FS.lookupPath(path, { follow: true }); + node = lookup.node; + } else { + node = path; + } + if (!node.node_ops.setattr) { + throw new FS.ErrnoError(63); + } + if (FS.isDir(node.mode)) { + throw new FS.ErrnoError(31); + } + if (!FS.isFile(node.mode)) { + throw new FS.ErrnoError(28); + } + var errCode = FS.nodePermissions(node, 'w'); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + node.node_ops.setattr(node, { + size: len, + timestamp: Date.now(), + }); + }, + ftruncate: (fd, len) => { + var stream = FS.getStreamChecked(fd); + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(28); + } + FS.truncate(stream.node, len); + }, + utime: (path, atime, mtime) => { + var lookup = FS.lookupPath(path, { follow: true }); + var node = lookup.node; + node.node_ops.setattr(node, { + timestamp: Math.max(atime, mtime), + }); + }, + open: (path, flags, mode) => { + if (path === '') { + throw new FS.ErrnoError(44); + } + flags = + typeof flags == 'string' + ? FS_modeStringToFlags(flags) + : flags; + mode = typeof mode == 'undefined' ? 438 : mode; + if (flags & 64) { + mode = (mode & 4095) | 32768; + } else { + mode = 0; + } + var node; + if (typeof path == 'object') { + node = path; + } else { + path = PATH.normalize(path); + try { + var lookup = FS.lookupPath(path, { + follow: !(flags & 131072), + }); + node = lookup.node; + } catch (e) {} + } + var created = false; + if (flags & 64) { + if (node) { + if (flags & 128) { + throw new FS.ErrnoError(20); + } + } else { + node = FS.mknod(path, mode, 0); + created = true; + } + } + if (!node) { + throw new FS.ErrnoError(44); + } + if (FS.isChrdev(node.mode)) { + flags &= ~512; + } + if (flags & 65536 && !FS.isDir(node.mode)) { + throw new FS.ErrnoError(54); + } + if (!created) { + var errCode = FS.mayOpen(node, flags); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + } + if (flags & 512 && !created) { + FS.truncate(node, 0); + } + flags &= ~(128 | 512 | 131072); + var stream = FS.createStream({ + node: node, + path: FS.getPath(node), + flags: flags, + seekable: true, + position: 0, + stream_ops: node.stream_ops, + ungotten: [], + error: false, + }); + if (stream.stream_ops.open) { + stream.stream_ops.open(stream); + } + if (Module['logReadFiles'] && !(flags & 1)) { + if (!FS.readFiles) FS.readFiles = {}; + if (!(path in FS.readFiles)) { + FS.readFiles[path] = 1; + } + } + return stream; + }, + close: (stream) => { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (stream.getdents) stream.getdents = null; + try { + if (stream.stream_ops.close) { + stream.stream_ops.close(stream); + } + } catch (e) { + throw e; + } finally { + FS.closeStream(stream.fd); + } + stream.fd = null; + }, + isClosed: (stream) => stream.fd === null, + llseek: (stream, offset, whence) => { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (!stream.seekable || !stream.stream_ops.llseek) { + throw new FS.ErrnoError(70); + } + if (whence != 0 && whence != 1 && whence != 2) { + throw new FS.ErrnoError(28); + } + stream.position = stream.stream_ops.llseek( + stream, + offset, + whence + ); + stream.ungotten = []; + return stream.position; + }, + read: (stream, buffer, offset, length, position) => { + assert(offset >= 0); + if (length < 0 || position < 0) { + throw new FS.ErrnoError(28); + } + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 1) { + throw new FS.ErrnoError(8); + } + if (FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(31); + } + if (!stream.stream_ops.read) { + throw new FS.ErrnoError(28); + } + var seeking = typeof position != 'undefined'; + if (!seeking) { + position = stream.position; + } else if (!stream.seekable) { + throw new FS.ErrnoError(70); + } + var bytesRead = stream.stream_ops.read( + stream, + buffer, + offset, + length, + position + ); + if (!seeking) stream.position += bytesRead; + return bytesRead; + }, + write: (stream, buffer, offset, length, position, canOwn) => { + assert(offset >= 0); + if (length < 0 || position < 0) { + throw new FS.ErrnoError(28); + } + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(8); + } + if (FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(31); + } + if (!stream.stream_ops.write) { + throw new FS.ErrnoError(28); + } + if (stream.seekable && stream.flags & 1024) { + FS.llseek(stream, 0, 2); + } + var seeking = typeof position != 'undefined'; + if (!seeking) { + position = stream.position; + } else if (!stream.seekable) { + throw new FS.ErrnoError(70); + } + var bytesWritten = stream.stream_ops.write( + stream, + buffer, + offset, + length, + position, + canOwn + ); + if (!seeking) stream.position += bytesWritten; + return bytesWritten; + }, + allocate: (stream, offset, length) => { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (offset < 0 || length <= 0) { + throw new FS.ErrnoError(28); + } + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(8); + } + if ( + !FS.isFile(stream.node.mode) && + !FS.isDir(stream.node.mode) + ) { + throw new FS.ErrnoError(43); + } + if (!stream.stream_ops.allocate) { + throw new FS.ErrnoError(138); + } + stream.stream_ops.allocate(stream, offset, length); + }, + mmap: (stream, length, position, prot, flags) => { + if ( + (prot & 2) !== 0 && + (flags & 2) === 0 && + (stream.flags & 2097155) !== 2 + ) { + throw new FS.ErrnoError(2); + } + if ((stream.flags & 2097155) === 1) { + throw new FS.ErrnoError(2); + } + if (!stream.stream_ops.mmap) { + throw new FS.ErrnoError(43); + } + return stream.stream_ops.mmap( + stream, + length, + position, + prot, + flags + ); + }, + msync: (stream, buffer, offset, length, mmapFlags) => { + assert(offset >= 0); + if (!stream.stream_ops.msync) { + return 0; + } + return stream.stream_ops.msync( + stream, + buffer, + offset, + length, + mmapFlags + ); + }, + munmap: (stream) => 0, + ioctl: (stream, cmd, arg) => { + if (!stream.stream_ops.ioctl) { + throw new FS.ErrnoError(59); + } + return stream.stream_ops.ioctl(stream, cmd, arg); + }, + readFile: (path, opts = {}) => { + opts.flags = opts.flags || 0; + opts.encoding = opts.encoding || 'binary'; + if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') { + throw new Error(`Invalid encoding type "${opts.encoding}"`); + } + var ret; + var stream = FS.open(path, opts.flags); + var stat = FS.stat(path); + var length = stat.size; + var buf = new Uint8Array(length); + FS.read(stream, buf, 0, length, 0); + if (opts.encoding === 'utf8') { + ret = UTF8ArrayToString(buf, 0); + } else if (opts.encoding === 'binary') { + ret = buf; + } + FS.close(stream); + return ret; + }, + writeFile: (path, data, opts = {}) => { + opts.flags = opts.flags || 577; + var stream = FS.open(path, opts.flags, opts.mode); + if (typeof data == 'string') { + var buf = new Uint8Array(lengthBytesUTF8(data) + 1); + var actualNumBytes = stringToUTF8Array( + data, + buf, + 0, + buf.length + ); + FS.write( + stream, + buf, + 0, + actualNumBytes, + undefined, + opts.canOwn + ); + } else if (ArrayBuffer.isView(data)) { + FS.write( + stream, + data, + 0, + data.byteLength, + undefined, + opts.canOwn + ); + } else { + throw new Error('Unsupported data type'); + } + FS.close(stream); + }, + cwd: () => FS.currentPath, + chdir: (path) => { + var lookup = FS.lookupPath(path, { follow: true }); + if (lookup.node === null) { + throw new FS.ErrnoError(44); + } + if (!FS.isDir(lookup.node.mode)) { + throw new FS.ErrnoError(54); + } + var errCode = FS.nodePermissions(lookup.node, 'x'); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + FS.currentPath = lookup.path; + }, + createDefaultDirectories: () => { + FS.mkdir('/tmp'); + FS.mkdir('/home'); + FS.mkdir('/home/web_user'); + }, + createDefaultDevices: () => { + FS.mkdir('/dev'); + FS.registerDevice(FS.makedev(1, 3), { + read: () => 0, + write: (stream, buffer, offset, length, pos) => length, + }); + FS.mkdev('/dev/null', FS.makedev(1, 3)); + TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); + TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); + FS.mkdev('/dev/tty', FS.makedev(5, 0)); + FS.mkdev('/dev/tty1', FS.makedev(6, 0)); + var randomBuffer = new Uint8Array(1024), + randomLeft = 0; + var randomByte = () => { + if (randomLeft === 0) { + randomLeft = randomFill(randomBuffer).byteLength; + } + return randomBuffer[--randomLeft]; + }; + FS.createDevice('/dev', 'random', randomByte); + FS.createDevice('/dev', 'urandom', randomByte); + FS.mkdir('/dev/shm'); + FS.mkdir('/dev/shm/tmp'); + }, + createSpecialDirectories: () => { + FS.mkdir('/proc'); + var proc_self = FS.mkdir('/proc/self'); + FS.mkdir('/proc/self/fd'); + FS.mount( + { + mount: () => { + var node = FS.createNode( + proc_self, + 'fd', + 16384 | 511, + 73 + ); + node.node_ops = { + lookup: (parent, name) => { + var fd = +name; + var stream = FS.getStreamChecked(fd); + var ret = { + parent: null, + mount: { mountpoint: 'fake' }, + node_ops: { + readlink: () => stream.path, + }, + }; + ret.parent = ret; + return ret; + }, + }; + return node; + }, + }, + {}, + '/proc/self/fd' + ); + }, + createStandardStreams: () => { + if (Module['stdin']) { + FS.createDevice('/dev', 'stdin', Module['stdin']); + } else { + FS.symlink('/dev/tty', '/dev/stdin'); + } + if (Module['stdout']) { + FS.createDevice('/dev', 'stdout', null, Module['stdout']); + } else { + FS.symlink('/dev/tty', '/dev/stdout'); + } + if (Module['stderr']) { + FS.createDevice('/dev', 'stderr', null, Module['stderr']); + } else { + FS.symlink('/dev/tty1', '/dev/stderr'); + } + var stdin = FS.open('/dev/stdin', 0); + var stdout = FS.open('/dev/stdout', 1); + var stderr = FS.open('/dev/stderr', 1); + assert( + stdin.fd === 0, + `invalid handle for stdin (${stdin.fd})` + ); + assert( + stdout.fd === 1, + `invalid handle for stdout (${stdout.fd})` + ); + assert( + stderr.fd === 2, + `invalid handle for stderr (${stderr.fd})` + ); + }, + ensureErrnoError: () => { + if (FS.ErrnoError) return; + FS.ErrnoError = function ErrnoError(errno, node) { + this.name = 'ErrnoError'; + this.node = node; + this.setErrno = function (errno) { + this.errno = errno; + for (var key in ERRNO_CODES) { + if (ERRNO_CODES[key] === errno) { + this.code = key; + break; + } + } + }; + this.setErrno(errno); + this.message = ERRNO_MESSAGES[errno]; + if (this.stack) { + Object.defineProperty(this, 'stack', { + value: new Error().stack, + writable: true, + }); + this.stack = demangleAll(this.stack); + } + }; + FS.ErrnoError.prototype = new Error(); + FS.ErrnoError.prototype.constructor = FS.ErrnoError; + [44].forEach((code) => { + FS.genericErrors[code] = new FS.ErrnoError(code); + FS.genericErrors[code].stack = ''; + }); + }, + staticInit: () => { + FS.ensureErrnoError(); + FS.nameTable = new Array(4096); + FS.mount(MEMFS, {}, '/'); + FS.createDefaultDirectories(); + FS.createDefaultDevices(); + FS.createSpecialDirectories(); + FS.filesystems = { MEMFS: MEMFS, NODEFS: NODEFS }; + }, + init: (input, output, error) => { + assert( + !FS.init.initialized, + 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)' + ); + FS.init.initialized = true; + FS.ensureErrnoError(); + Module['stdin'] = input || Module['stdin']; + Module['stdout'] = output || Module['stdout']; + Module['stderr'] = error || Module['stderr']; + FS.createStandardStreams(); + }, + quit: () => { + FS.init.initialized = false; + _fflush(0); + for (var i = 0; i < FS.streams.length; i++) { + var stream = FS.streams[i]; + if (!stream) { + continue; + } + FS.close(stream); + } + }, + findObject: (path, dontResolveLastLink) => { + var ret = FS.analyzePath(path, dontResolveLastLink); + if (!ret.exists) { + return null; + } + return ret.object; + }, + analyzePath: (path, dontResolveLastLink) => { + try { + var lookup = FS.lookupPath(path, { + follow: !dontResolveLastLink, + }); + path = lookup.path; + } catch (e) {} + var ret = { + isRoot: false, + exists: false, + error: 0, + name: null, + path: null, + object: null, + parentExists: false, + parentPath: null, + parentObject: null, + }; + try { + var lookup = FS.lookupPath(path, { parent: true }); + ret.parentExists = true; + ret.parentPath = lookup.path; + ret.parentObject = lookup.node; + ret.name = PATH.basename(path); + lookup = FS.lookupPath(path, { + follow: !dontResolveLastLink, + }); + ret.exists = true; + ret.path = lookup.path; + ret.object = lookup.node; + ret.name = lookup.node.name; + ret.isRoot = lookup.path === '/'; + } catch (e) { + ret.error = e.errno; + } + return ret; + }, + createPath: (parent, path, canRead, canWrite) => { + parent = + typeof parent == 'string' ? parent : FS.getPath(parent); + var parts = path.split('/').reverse(); + while (parts.length) { + var part = parts.pop(); + if (!part) continue; + var current = PATH.join2(parent, part); + try { + FS.mkdir(current); + } catch (e) {} + parent = current; + } + return current; + }, + createFile: (parent, name, properties, canRead, canWrite) => { + var path = PATH.join2( + typeof parent == 'string' ? parent : FS.getPath(parent), + name + ); + var mode = FS_getMode(canRead, canWrite); + return FS.create(path, mode); + }, + createDataFile: (parent, name, data, canRead, canWrite, canOwn) => { + var path = name; + if (parent) { + parent = + typeof parent == 'string' ? parent : FS.getPath(parent); + path = name ? PATH.join2(parent, name) : parent; + } + var mode = FS_getMode(canRead, canWrite); + var node = FS.create(path, mode); + if (data) { + if (typeof data == 'string') { + var arr = new Array(data.length); + for (var i = 0, len = data.length; i < len; ++i) + arr[i] = data.charCodeAt(i); + data = arr; + } + FS.chmod(node, mode | 146); + var stream = FS.open(node, 577); + FS.write(stream, data, 0, data.length, 0, canOwn); + FS.close(stream); + FS.chmod(node, mode); + } + return node; + }, + createDevice: (parent, name, input, output) => { + var path = PATH.join2( + typeof parent == 'string' ? parent : FS.getPath(parent), + name + ); + var mode = FS_getMode(!!input, !!output); + if (!FS.createDevice.major) FS.createDevice.major = 64; + var dev = FS.makedev(FS.createDevice.major++, 0); + FS.registerDevice(dev, { + open: (stream) => { + stream.seekable = false; + }, + close: (stream) => { + if (output && output.buffer && output.buffer.length) { + output(10); + } + }, + read: (stream, buffer, offset, length, pos) => { + var bytesRead = 0; + for (var i = 0; i < length; i++) { + var result; + try { + result = input(); + } catch (e) { + throw new FS.ErrnoError(29); + } + if (result === undefined && bytesRead === 0) { + throw new FS.ErrnoError(6); + } + if (result === null || result === undefined) break; + bytesRead++; + buffer[offset + i] = result; + } + if (bytesRead) { + stream.node.timestamp = Date.now(); + } + return bytesRead; + }, + write: (stream, buffer, offset, length, pos) => { + for (var i = 0; i < length; i++) { + try { + output(buffer[offset + i]); + } catch (e) { + throw new FS.ErrnoError(29); + } + } + if (length) { + stream.node.timestamp = Date.now(); + } + return i; + }, + }); + return FS.mkdev(path, mode, dev); + }, + forceLoadFile: (obj) => { + if (obj.isDevice || obj.isFolder || obj.link || obj.contents) + return true; + if (typeof XMLHttpRequest != 'undefined') { + throw new Error( + 'Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.' + ); + } else if (read_) { + try { + obj.contents = intArrayFromString(read_(obj.url), true); + obj.usedBytes = obj.contents.length; + } catch (e) { + throw new FS.ErrnoError(29); + } + } else { + throw new Error( + 'Cannot load without read() or XMLHttpRequest.' + ); + } + }, + createLazyFile: (parent, name, url, canRead, canWrite) => { + function LazyUint8Array() { + this.lengthKnown = false; + this.chunks = []; + } + LazyUint8Array.prototype.get = function LazyUint8Array_get( + idx + ) { + if (idx > this.length - 1 || idx < 0) { + return undefined; + } + var chunkOffset = idx % this.chunkSize; + var chunkNum = (idx / this.chunkSize) | 0; + return this.getter(chunkNum)[chunkOffset]; + }; + LazyUint8Array.prototype.setDataGetter = + function LazyUint8Array_setDataGetter(getter) { + this.getter = getter; + }; + LazyUint8Array.prototype.cacheLength = + function LazyUint8Array_cacheLength() { + var xhr = new XMLHttpRequest(); + xhr.open('HEAD', url, false); + xhr.send(null); + if ( + !( + (xhr.status >= 200 && xhr.status < 300) || + xhr.status === 304 + ) + ) + throw new Error( + "Couldn't load " + + url + + '. Status: ' + + xhr.status + ); + var datalength = Number( + xhr.getResponseHeader('Content-length') + ); + var header; + var hasByteServing = + (header = xhr.getResponseHeader('Accept-Ranges')) && + header === 'bytes'; + var usesGzip = + (header = + xhr.getResponseHeader('Content-Encoding')) && + header === 'gzip'; + var chunkSize = 1024 * 1024; + if (!hasByteServing) chunkSize = datalength; + var doXHR = (from, to) => { + if (from > to) + throw new Error( + 'invalid range (' + + from + + ', ' + + to + + ') or no bytes requested!' + ); + if (to > datalength - 1) + throw new Error( + 'only ' + + datalength + + ' bytes available! programmer error!' + ); + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + if (datalength !== chunkSize) + xhr.setRequestHeader( + 'Range', + 'bytes=' + from + '-' + to + ); + xhr.responseType = 'arraybuffer'; + if (xhr.overrideMimeType) { + xhr.overrideMimeType( + 'text/plain; charset=x-user-defined' + ); + } + xhr.send(null); + if ( + !( + (xhr.status >= 200 && xhr.status < 300) || + xhr.status === 304 + ) + ) + throw new Error( + "Couldn't load " + + url + + '. Status: ' + + xhr.status + ); + if (xhr.response !== undefined) { + return new Uint8Array(xhr.response || []); + } + return intArrayFromString( + xhr.responseText || '', + true + ); + }; + var lazyArray = this; + lazyArray.setDataGetter((chunkNum) => { + var start = chunkNum * chunkSize; + var end = (chunkNum + 1) * chunkSize - 1; + end = Math.min(end, datalength - 1); + if ( + typeof lazyArray.chunks[chunkNum] == 'undefined' + ) { + lazyArray.chunks[chunkNum] = doXHR(start, end); + } + if ( + typeof lazyArray.chunks[chunkNum] == 'undefined' + ) + throw new Error('doXHR failed!'); + return lazyArray.chunks[chunkNum]; + }); + if (usesGzip || !datalength) { + chunkSize = datalength = 1; + datalength = this.getter(0).length; + chunkSize = datalength; + out( + 'LazyFiles on gzip forces download of the whole file when length is accessed' + ); + } + this._length = datalength; + this._chunkSize = chunkSize; + this.lengthKnown = true; + }; + if (typeof XMLHttpRequest != 'undefined') { + if (!ENVIRONMENT_IS_WORKER) + throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc'; + var lazyArray = new LazyUint8Array(); + Object.defineProperties(lazyArray, { + length: { + get: function () { + if (!this.lengthKnown) { + this.cacheLength(); + } + return this._length; + }, + }, + chunkSize: { + get: function () { + if (!this.lengthKnown) { + this.cacheLength(); + } + return this._chunkSize; + }, + }, + }); + var properties = { isDevice: false, contents: lazyArray }; + } else { + var properties = { isDevice: false, url: url }; + } + var node = FS.createFile( + parent, + name, + properties, + canRead, + canWrite + ); + if (properties.contents) { + node.contents = properties.contents; + } else if (properties.url) { + node.contents = null; + node.url = properties.url; + } + Object.defineProperties(node, { + usedBytes: { + get: function () { + return this.contents.length; + }, + }, + }); + var stream_ops = {}; + var keys = Object.keys(node.stream_ops); + keys.forEach((key) => { + var fn = node.stream_ops[key]; + stream_ops[key] = function forceLoadLazyFile() { + FS.forceLoadFile(node); + return fn.apply(null, arguments); + }; + }); + function writeChunks(stream, buffer, offset, length, position) { + var contents = stream.node.contents; + if (position >= contents.length) return 0; + var size = Math.min(contents.length - position, length); + assert(size >= 0); + if (contents.slice) { + for (var i = 0; i < size; i++) { + buffer[offset + i] = contents[position + i]; + } + } else { + for (var i = 0; i < size; i++) { + buffer[offset + i] = contents.get(position + i); + } + } + return size; + } + stream_ops.read = ( + stream, + buffer, + offset, + length, + position + ) => { + FS.forceLoadFile(node); + return writeChunks( + stream, + buffer, + offset, + length, + position + ); + }; + stream_ops.mmap = (stream, length, position, prot, flags) => { + FS.forceLoadFile(node); + var ptr = mmapAlloc(length); + if (!ptr) { + throw new FS.ErrnoError(48); + } + writeChunks(stream, HEAP8, ptr, length, position); + return { ptr: ptr, allocated: true }; + }; + node.stream_ops = stream_ops; + return node; + }, + absolutePath: () => { + abort( + 'FS.absolutePath has been removed; use PATH_FS.resolve instead' + ); + }, + createFolder: () => { + abort('FS.createFolder has been removed; use FS.mkdir instead'); + }, + createLink: () => { + abort('FS.createLink has been removed; use FS.symlink instead'); + }, + joinPath: () => { + abort('FS.joinPath has been removed; use PATH.join instead'); + }, + mmapAlloc: () => { + abort( + 'FS.mmapAlloc has been replaced by the top level function mmapAlloc' + ); + }, + standardizePath: () => { + abort( + 'FS.standardizePath has been removed; use PATH.normalize instead' + ); + }, + }; + var SYSCALLS = { + DEFAULT_POLLMASK: 5, + calculateAt: function (dirfd, path, allowEmpty) { + if (PATH.isAbs(path)) { + return path; + } + var dir; + if (dirfd === -100) { + dir = FS.cwd(); + } else { + var dirstream = SYSCALLS.getStreamFromFD(dirfd); + dir = dirstream.path; + } + if (path.length == 0) { + if (!allowEmpty) { + throw new FS.ErrnoError(44); + } + return dir; + } + return PATH.join2(dir, path); + }, + doStat: function (func, path, buf) { + try { + var stat = func(path); + } catch (e) { + if ( + e && + e.node && + PATH.normalize(path) !== + PATH.normalize(FS.getPath(e.node)) + ) { + return -54; + } + throw e; + } + HEAP32[buf >> 2] = stat.dev; + checkInt32(stat.dev); + HEAP32[(buf + 4) >> 2] = stat.mode; + checkInt32(stat.mode); + HEAPU32[(buf + 8) >> 2] = stat.nlink; + checkInt32(stat.nlink); + HEAP32[(buf + 12) >> 2] = stat.uid; + checkInt32(stat.uid); + HEAP32[(buf + 16) >> 2] = stat.gid; + checkInt32(stat.gid); + HEAP32[(buf + 20) >> 2] = stat.rdev; + checkInt32(stat.rdev); + (tempI64 = [ + stat.size >>> 0, + ((tempDouble = stat.size), + +Math.abs(tempDouble) >= 1 + ? tempDouble > 0 + ? +Math.floor(tempDouble / 4294967296) >>> 0 + : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / + 4294967296 + ) >>> 0 + : 0), + ]), + (HEAP32[(buf + 24) >> 2] = tempI64[0]), + (HEAP32[(buf + 28) >> 2] = tempI64[1]); + checkInt64(stat.size); + HEAP32[(buf + 32) >> 2] = 4096; + checkInt32(4096); + HEAP32[(buf + 36) >> 2] = stat.blocks; + checkInt32(stat.blocks); + var atime = stat.atime.getTime(); + var mtime = stat.mtime.getTime(); + var ctime = stat.ctime.getTime(); + (tempI64 = [ + Math.floor(atime / 1e3) >>> 0, + ((tempDouble = Math.floor(atime / 1e3)), + +Math.abs(tempDouble) >= 1 + ? tempDouble > 0 + ? +Math.floor(tempDouble / 4294967296) >>> 0 + : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / + 4294967296 + ) >>> 0 + : 0), + ]), + (HEAP32[(buf + 40) >> 2] = tempI64[0]), + (HEAP32[(buf + 44) >> 2] = tempI64[1]); + checkInt64(Math.floor(atime / 1e3)); + HEAPU32[(buf + 48) >> 2] = (atime % 1e3) * 1e3; + checkInt32((atime % 1e3) * 1e3); + (tempI64 = [ + Math.floor(mtime / 1e3) >>> 0, + ((tempDouble = Math.floor(mtime / 1e3)), + +Math.abs(tempDouble) >= 1 + ? tempDouble > 0 + ? +Math.floor(tempDouble / 4294967296) >>> 0 + : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / + 4294967296 + ) >>> 0 + : 0), + ]), + (HEAP32[(buf + 56) >> 2] = tempI64[0]), + (HEAP32[(buf + 60) >> 2] = tempI64[1]); + checkInt64(Math.floor(mtime / 1e3)); + HEAPU32[(buf + 64) >> 2] = (mtime % 1e3) * 1e3; + checkInt32((mtime % 1e3) * 1e3); + (tempI64 = [ + Math.floor(ctime / 1e3) >>> 0, + ((tempDouble = Math.floor(ctime / 1e3)), + +Math.abs(tempDouble) >= 1 + ? tempDouble > 0 + ? +Math.floor(tempDouble / 4294967296) >>> 0 + : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / + 4294967296 + ) >>> 0 + : 0), + ]), + (HEAP32[(buf + 72) >> 2] = tempI64[0]), + (HEAP32[(buf + 76) >> 2] = tempI64[1]); + checkInt64(Math.floor(ctime / 1e3)); + HEAPU32[(buf + 80) >> 2] = (ctime % 1e3) * 1e3; + checkInt32((ctime % 1e3) * 1e3); + (tempI64 = [ + stat.ino >>> 0, + ((tempDouble = stat.ino), + +Math.abs(tempDouble) >= 1 + ? tempDouble > 0 + ? +Math.floor(tempDouble / 4294967296) >>> 0 + : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / + 4294967296 + ) >>> 0 + : 0), + ]), + (HEAP32[(buf + 88) >> 2] = tempI64[0]), + (HEAP32[(buf + 92) >> 2] = tempI64[1]); + checkInt64(stat.ino); + return 0; + }, + doMsync: function (addr, stream, len, flags, offset) { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + if (flags & 2) { + return 0; + } + var buffer = HEAPU8.slice(addr, addr + len); + FS.msync(stream, buffer, offset, len, flags); + }, + varargs: undefined, + get() { + assert(SYSCALLS.varargs != undefined); + SYSCALLS.varargs += 4; + var ret = HEAP32[(SYSCALLS.varargs - 4) >> 2]; + return ret; + }, + getStr(ptr) { + var ret = UTF8ToString(ptr); + return ret; + }, + getStreamFromFD: function (fd) { + var stream = FS.getStreamChecked(fd); + return stream; + }, + }; + function ___syscall_fcntl64(fd, cmd, varargs) { + SYSCALLS.varargs = varargs; + try { + var stream = SYSCALLS.getStreamFromFD(fd); + switch (cmd) { + case 0: { + var arg = SYSCALLS.get(); + if (arg < 0) { + return -28; + } + var newStream; + newStream = FS.createStream(stream, arg); + return newStream.fd; + } + case 1: + case 2: + return 0; + case 3: + return stream.flags; + case 4: { + var arg = SYSCALLS.get(); + stream.flags |= arg; + return 0; + } + case 5: { + var arg = SYSCALLS.get(); + var offset = 0; + HEAP16[(arg + offset) >> 1] = 2; + checkInt16(2); + return 0; + } + case 6: + case 7: + return 0; + case 16: + case 8: + return -28; + case 9: + setErrNo(28); + return -1; + default: { + return -28; + } + } + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) + throw e; + return -e.errno; + } + } + function ___syscall_fstat64(fd, buf) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + return SYSCALLS.doStat(FS.stat, stream.path, buf); + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) + throw e; + return -e.errno; + } + } + function ___syscall_ioctl(fd, op, varargs) { + SYSCALLS.varargs = varargs; + try { + var stream = SYSCALLS.getStreamFromFD(fd); + switch (op) { + case 21509: { + if (!stream.tty) return -59; + return 0; + } + case 21505: { + if (!stream.tty) return -59; + if (stream.tty.ops.ioctl_tcgets) { + var termios = stream.tty.ops.ioctl_tcgets(stream); + var argp = SYSCALLS.get(); + HEAP32[argp >> 2] = termios.c_iflag || 0; + checkInt32(termios.c_iflag || 0); + HEAP32[(argp + 4) >> 2] = termios.c_oflag || 0; + checkInt32(termios.c_oflag || 0); + HEAP32[(argp + 8) >> 2] = termios.c_cflag || 0; + checkInt32(termios.c_cflag || 0); + HEAP32[(argp + 12) >> 2] = termios.c_lflag || 0; + checkInt32(termios.c_lflag || 0); + for (var i = 0; i < 32; i++) { + HEAP8[(argp + i + 17) >> 0] = + termios.c_cc[i] || 0; + checkInt8(termios.c_cc[i] || 0); + } + return 0; + } + return 0; + } + case 21510: + case 21511: + case 21512: { + if (!stream.tty) return -59; + return 0; + } + case 21506: + case 21507: + case 21508: { + if (!stream.tty) return -59; + if (stream.tty.ops.ioctl_tcsets) { + var argp = SYSCALLS.get(); + var c_iflag = HEAP32[argp >> 2]; + var c_oflag = HEAP32[(argp + 4) >> 2]; + var c_cflag = HEAP32[(argp + 8) >> 2]; + var c_lflag = HEAP32[(argp + 12) >> 2]; + var c_cc = []; + for (var i = 0; i < 32; i++) { + c_cc.push(HEAP8[(argp + i + 17) >> 0]); + } + return stream.tty.ops.ioctl_tcsets(stream.tty, op, { + c_iflag: c_iflag, + c_oflag: c_oflag, + c_cflag: c_cflag, + c_lflag: c_lflag, + c_cc: c_cc, + }); + } + return 0; + } + case 21519: { + if (!stream.tty) return -59; + var argp = SYSCALLS.get(); + HEAP32[argp >> 2] = 0; + checkInt32(0); + return 0; + } + case 21520: { + if (!stream.tty) return -59; + return -28; + } + case 21531: { + var argp = SYSCALLS.get(); + return FS.ioctl(stream, op, argp); + } + case 21523: { + if (!stream.tty) return -59; + if (stream.tty.ops.ioctl_tiocgwinsz) { + var winsize = stream.tty.ops.ioctl_tiocgwinsz( + stream.tty + ); + var argp = SYSCALLS.get(); + HEAP16[argp >> 1] = winsize[0]; + checkInt16(winsize[0]); + HEAP16[(argp + 2) >> 1] = winsize[1]; + checkInt16(winsize[1]); + } + return 0; + } + case 21524: { + if (!stream.tty) return -59; + return 0; + } + case 21515: { + if (!stream.tty) return -59; + return 0; + } + default: + return -28; + } + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) + throw e; + return -e.errno; + } + } + function ___syscall_lstat64(path, buf) { + try { + path = SYSCALLS.getStr(path); + return SYSCALLS.doStat(FS.lstat, path, buf); + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) + throw e; + return -e.errno; + } + } + function ___syscall_newfstatat(dirfd, path, buf, flags) { + try { + path = SYSCALLS.getStr(path); + var nofollow = flags & 256; + var allowEmpty = flags & 4096; + flags = flags & ~6400; + assert( + !flags, + `unknown flags in __syscall_newfstatat: ${flags}` + ); + path = SYSCALLS.calculateAt(dirfd, path, allowEmpty); + return SYSCALLS.doStat( + nofollow ? FS.lstat : FS.stat, + path, + buf + ); + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) + throw e; + return -e.errno; + } + } + function ___syscall_openat(dirfd, path, flags, varargs) { + SYSCALLS.varargs = varargs; + try { + path = SYSCALLS.getStr(path); + path = SYSCALLS.calculateAt(dirfd, path); + var mode = varargs ? SYSCALLS.get() : 0; + return FS.open(path, flags, mode).fd; + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) + throw e; + return -e.errno; + } + } + function ___syscall_stat64(path, buf) { + try { + path = SYSCALLS.getStr(path); + return SYSCALLS.doStat(FS.stat, path, buf); + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) + throw e; + return -e.errno; + } + } + function ___throw_exception_with_stack_trace(ex) { + var e = new WebAssembly.Exception(getCppExceptionTag(), [ex], { + traceStack: true, + }); + e.message = getExceptionMessage(e); + if (e.stack) { + var arr = e.stack.split('\n'); + arr.splice(1, 1); + e.stack = arr.join('\n'); + } + throw e; + } + var structRegistrations = {}; + function runDestructors(destructors) { + while (destructors.length) { + var ptr = destructors.pop(); + var del = destructors.pop(); + del(ptr); + } + } + function simpleReadValueFromPointer(pointer) { + return this['fromWireType'](HEAP32[pointer >> 2]); + } + var awaitingDependencies = {}; + var registeredTypes = {}; + var typeDependencies = {}; + var InternalError = undefined; + function throwInternalError(message) { + throw new InternalError(message); + } + function whenDependentTypesAreResolved( + myTypes, + dependentTypes, + getTypeConverters + ) { + myTypes.forEach(function (type) { + typeDependencies[type] = dependentTypes; + }); + function onComplete(typeConverters) { + var myTypeConverters = getTypeConverters(typeConverters); + if (myTypeConverters.length !== myTypes.length) { + throwInternalError('Mismatched type converter count'); + } + for (var i = 0; i < myTypes.length; ++i) { + registerType(myTypes[i], myTypeConverters[i]); + } + } + var typeConverters = new Array(dependentTypes.length); + var unregisteredTypes = []; + var registered = 0; + dependentTypes.forEach((dt, i) => { + if (registeredTypes.hasOwnProperty(dt)) { + typeConverters[i] = registeredTypes[dt]; + } else { + unregisteredTypes.push(dt); + if (!awaitingDependencies.hasOwnProperty(dt)) { + awaitingDependencies[dt] = []; + } + awaitingDependencies[dt].push(() => { + typeConverters[i] = registeredTypes[dt]; + ++registered; + if (registered === unregisteredTypes.length) { + onComplete(typeConverters); + } + }); + } + }); + if (0 === unregisteredTypes.length) { + onComplete(typeConverters); + } + } + var __embind_finalize_value_object = function (structType) { + var reg = structRegistrations[structType]; + delete structRegistrations[structType]; + var rawConstructor = reg.rawConstructor; + var rawDestructor = reg.rawDestructor; + var fieldRecords = reg.fields; + var fieldTypes = fieldRecords + .map((field) => field.getterReturnType) + .concat(fieldRecords.map((field) => field.setterArgumentType)); + whenDependentTypesAreResolved( + [structType], + fieldTypes, + (fieldTypes) => { + var fields = {}; + fieldRecords.forEach((field, i) => { + var fieldName = field.fieldName; + var getterReturnType = fieldTypes[i]; + var getter = field.getter; + var getterContext = field.getterContext; + var setterArgumentType = + fieldTypes[i + fieldRecords.length]; + var setter = field.setter; + var setterContext = field.setterContext; + fields[fieldName] = { + read: (ptr) => + getterReturnType['fromWireType']( + getter(getterContext, ptr) + ), + write: (ptr, o) => { + var destructors = []; + setter( + setterContext, + ptr, + setterArgumentType['toWireType']( + destructors, + o + ) + ); + runDestructors(destructors); + }, + }; + }); + return [ + { + name: reg.name, + fromWireType: function (ptr) { + var rv = {}; + for (var i in fields) { + rv[i] = fields[i].read(ptr); + } + rawDestructor(ptr); + return rv; + }, + toWireType: function (destructors, o) { + for (var fieldName in fields) { + if (!(fieldName in o)) { + throw new TypeError( + `Missing field: "${fieldName}"` + ); + } + } + var ptr = rawConstructor(); + for (fieldName in fields) { + fields[fieldName].write(ptr, o[fieldName]); + } + if (destructors !== null) { + destructors.push(rawDestructor, ptr); + } + return ptr; + }, + argPackAdvance: 8, + readValueFromPointer: simpleReadValueFromPointer, + destructorFunction: rawDestructor, + }, + ]; + } + ); + }; + function __embind_register_bigint( + primitiveType, + name, + size, + minRange, + maxRange + ) {} + function getShiftFromSize(size) { + switch (size) { + case 1: + return 0; + case 2: + return 1; + case 4: + return 2; + case 8: + return 3; + default: + throw new TypeError(`Unknown type size: ${size}`); + } + } + function embind_init_charCodes() { + var codes = new Array(256); + for (var i = 0; i < 256; ++i) { + codes[i] = String.fromCharCode(i); + } + embind_charCodes = codes; + } + var embind_charCodes = undefined; + function readLatin1String(ptr) { + var ret = ''; + var c = ptr; + while (HEAPU8[c]) { + ret += embind_charCodes[HEAPU8[c++]]; + } + return ret; + } + var BindingError = undefined; + function throwBindingError(message) { + throw new BindingError(message); + } + function sharedRegisterType(rawType, registeredInstance, options = {}) { + var name = registeredInstance.name; + if (!rawType) { + throwBindingError( + `type "${name}" must have a positive integer typeid pointer` + ); + } + if (registeredTypes.hasOwnProperty(rawType)) { + if (options.ignoreDuplicateRegistrations) { + return; + } else { + throwBindingError(`Cannot register type '${name}' twice`); + } + } + registeredTypes[rawType] = registeredInstance; + delete typeDependencies[rawType]; + if (awaitingDependencies.hasOwnProperty(rawType)) { + var callbacks = awaitingDependencies[rawType]; + delete awaitingDependencies[rawType]; + callbacks.forEach((cb) => cb()); + } + } + function registerType(rawType, registeredInstance, options = {}) { + if (!('argPackAdvance' in registeredInstance)) { + throw new TypeError( + 'registerType registeredInstance requires argPackAdvance' + ); + } + return sharedRegisterType(rawType, registeredInstance, options); + } + function __embind_register_bool( + rawType, + name, + size, + trueValue, + falseValue + ) { + var shift = getShiftFromSize(size); + name = readLatin1String(name); + registerType(rawType, { + name: name, + fromWireType: function (wt) { + return !!wt; + }, + toWireType: function (destructors, o) { + return o ? trueValue : falseValue; + }, + argPackAdvance: 8, + readValueFromPointer: function (pointer) { + var heap; + if (size === 1) { + heap = HEAP8; + } else if (size === 2) { + heap = HEAP16; + } else if (size === 4) { + heap = HEAP32; + } else { + throw new TypeError( + 'Unknown boolean type size: ' + name + ); + } + return this['fromWireType'](heap[pointer >> shift]); + }, + destructorFunction: null, + }); + } + function ClassHandle_isAliasOf(other) { + if (!(this instanceof ClassHandle)) { + return false; + } + if (!(other instanceof ClassHandle)) { + return false; + } + var leftClass = this.$$.ptrType.registeredClass; + var left = this.$$.ptr; + var rightClass = other.$$.ptrType.registeredClass; + var right = other.$$.ptr; + while (leftClass.baseClass) { + left = leftClass.upcast(left); + leftClass = leftClass.baseClass; + } + while (rightClass.baseClass) { + right = rightClass.upcast(right); + rightClass = rightClass.baseClass; + } + return leftClass === rightClass && left === right; + } + function shallowCopyInternalPointer(o) { + return { + count: o.count, + deleteScheduled: o.deleteScheduled, + preservePointerOnDelete: o.preservePointerOnDelete, + ptr: o.ptr, + ptrType: o.ptrType, + smartPtr: o.smartPtr, + smartPtrType: o.smartPtrType, + }; + } + function throwInstanceAlreadyDeleted(obj) { + function getInstanceTypeName(handle) { + return handle.$$.ptrType.registeredClass.name; + } + throwBindingError( + getInstanceTypeName(obj) + ' instance already deleted' + ); + } + var finalizationRegistry = false; + function detachFinalizer(handle) {} + function runDestructor($$) { + if ($$.smartPtr) { + $$.smartPtrType.rawDestructor($$.smartPtr); + } else { + $$.ptrType.registeredClass.rawDestructor($$.ptr); + } + } + function releaseClassHandle($$) { + $$.count.value -= 1; + var toDelete = 0 === $$.count.value; + if (toDelete) { + runDestructor($$); + } + } + function downcastPointer(ptr, ptrClass, desiredClass) { + if (ptrClass === desiredClass) { + return ptr; + } + if (undefined === desiredClass.baseClass) { + return null; + } + var rv = downcastPointer(ptr, ptrClass, desiredClass.baseClass); + if (rv === null) { + return null; + } + return desiredClass.downcast(rv); + } + var registeredPointers = {}; + function getInheritedInstanceCount() { + return Object.keys(registeredInstances).length; + } + function getLiveInheritedInstances() { + var rv = []; + for (var k in registeredInstances) { + if (registeredInstances.hasOwnProperty(k)) { + rv.push(registeredInstances[k]); + } + } + return rv; + } + var deletionQueue = []; + function flushPendingDeletes() { + while (deletionQueue.length) { + var obj = deletionQueue.pop(); + obj.$$.deleteScheduled = false; + obj['delete'](); + } + } + var delayFunction = undefined; + function setDelayFunction(fn) { + delayFunction = fn; + if (deletionQueue.length && delayFunction) { + delayFunction(flushPendingDeletes); + } + } + function init_embind() { + Module['getInheritedInstanceCount'] = getInheritedInstanceCount; + Module['getLiveInheritedInstances'] = getLiveInheritedInstances; + Module['flushPendingDeletes'] = flushPendingDeletes; + Module['setDelayFunction'] = setDelayFunction; + } + var registeredInstances = {}; + function getBasestPointer(class_, ptr) { + if (ptr === undefined) { + throwBindingError('ptr should not be undefined'); + } + while (class_.baseClass) { + ptr = class_.upcast(ptr); + class_ = class_.baseClass; + } + return ptr; + } + function getInheritedInstance(class_, ptr) { + ptr = getBasestPointer(class_, ptr); + return registeredInstances[ptr]; + } + function makeClassHandle(prototype, record) { + if (!record.ptrType || !record.ptr) { + throwInternalError('makeClassHandle requires ptr and ptrType'); + } + var hasSmartPtrType = !!record.smartPtrType; + var hasSmartPtr = !!record.smartPtr; + if (hasSmartPtrType !== hasSmartPtr) { + throwInternalError( + 'Both smartPtrType and smartPtr must be specified' + ); + } + record.count = { value: 1 }; + return attachFinalizer( + Object.create(prototype, { $$: { value: record } }) + ); + } + function RegisteredPointer_fromWireType(ptr) { + var rawPointer = this.getPointee(ptr); + if (!rawPointer) { + this.destructor(ptr); + return null; + } + var registeredInstance = getInheritedInstance( + this.registeredClass, + rawPointer + ); + if (undefined !== registeredInstance) { + if (0 === registeredInstance.$$.count.value) { + registeredInstance.$$.ptr = rawPointer; + registeredInstance.$$.smartPtr = ptr; + return registeredInstance['clone'](); + } else { + var rv = registeredInstance['clone'](); + this.destructor(ptr); + return rv; + } + } + function makeDefaultHandle() { + if (this.isSmartPointer) { + return makeClassHandle( + this.registeredClass.instancePrototype, + { + ptrType: this.pointeeType, + ptr: rawPointer, + smartPtrType: this, + smartPtr: ptr, + } + ); + } else { + return makeClassHandle( + this.registeredClass.instancePrototype, + { ptrType: this, ptr: ptr } + ); + } + } + var actualType = this.registeredClass.getActualType(rawPointer); + var registeredPointerRecord = registeredPointers[actualType]; + if (!registeredPointerRecord) { + return makeDefaultHandle.call(this); + } + var toType; + if (this.isConst) { + toType = registeredPointerRecord.constPointerType; + } else { + toType = registeredPointerRecord.pointerType; + } + var dp = downcastPointer( + rawPointer, + this.registeredClass, + toType.registeredClass + ); + if (dp === null) { + return makeDefaultHandle.call(this); + } + if (this.isSmartPointer) { + return makeClassHandle( + toType.registeredClass.instancePrototype, + { + ptrType: toType, + ptr: dp, + smartPtrType: this, + smartPtr: ptr, + } + ); + } else { + return makeClassHandle( + toType.registeredClass.instancePrototype, + { ptrType: toType, ptr: dp } + ); + } + } + var attachFinalizer = function (handle) { + if ('undefined' === typeof FinalizationRegistry) { + attachFinalizer = (handle) => handle; + return handle; + } + finalizationRegistry = new FinalizationRegistry((info) => { + console.warn(info.leakWarning.stack.replace(/^Error: /, '')); + releaseClassHandle(info.$$); + }); + attachFinalizer = (handle) => { + var $$ = handle.$$; + var hasSmartPtr = !!$$.smartPtr; + if (hasSmartPtr) { + var info = { $$: $$ }; + var cls = $$.ptrType.registeredClass; + info.leakWarning = new Error( + `Embind found a leaked C++ instance ${ + cls.name + } <${ptrToString($$.ptr)}>.\n` + + "We'll free it automatically in this case, but this functionality is not reliable across various environments.\n" + + "Make sure to invoke .delete() manually once you're done with the instance instead.\n" + + 'Originally allocated' + ); + if ('captureStackTrace' in Error) { + Error.captureStackTrace( + info.leakWarning, + RegisteredPointer_fromWireType + ); + } + finalizationRegistry.register(handle, info, handle); + } + return handle; + }; + detachFinalizer = (handle) => + finalizationRegistry.unregister(handle); + return attachFinalizer(handle); + }; + function ClassHandle_clone() { + if (!this.$$.ptr) { + throwInstanceAlreadyDeleted(this); + } + if (this.$$.preservePointerOnDelete) { + this.$$.count.value += 1; + return this; + } else { + var clone = attachFinalizer( + Object.create(Object.getPrototypeOf(this), { + $$: { value: shallowCopyInternalPointer(this.$$) }, + }) + ); + clone.$$.count.value += 1; + clone.$$.deleteScheduled = false; + return clone; + } + } + function ClassHandle_delete() { + if (!this.$$.ptr) { + throwInstanceAlreadyDeleted(this); + } + if (this.$$.deleteScheduled && !this.$$.preservePointerOnDelete) { + throwBindingError('Object already scheduled for deletion'); + } + detachFinalizer(this); + releaseClassHandle(this.$$); + if (!this.$$.preservePointerOnDelete) { + this.$$.smartPtr = undefined; + this.$$.ptr = undefined; + } + } + function ClassHandle_isDeleted() { + return !this.$$.ptr; + } + function ClassHandle_deleteLater() { + if (!this.$$.ptr) { + throwInstanceAlreadyDeleted(this); + } + if (this.$$.deleteScheduled && !this.$$.preservePointerOnDelete) { + throwBindingError('Object already scheduled for deletion'); + } + deletionQueue.push(this); + if (deletionQueue.length === 1 && delayFunction) { + delayFunction(flushPendingDeletes); + } + this.$$.deleteScheduled = true; + return this; + } + function init_ClassHandle() { + ClassHandle.prototype['isAliasOf'] = ClassHandle_isAliasOf; + ClassHandle.prototype['clone'] = ClassHandle_clone; + ClassHandle.prototype['delete'] = ClassHandle_delete; + ClassHandle.prototype['isDeleted'] = ClassHandle_isDeleted; + ClassHandle.prototype['deleteLater'] = ClassHandle_deleteLater; + } + function ClassHandle() {} + var char_0 = 48; + var char_9 = 57; + function makeLegalFunctionName(name) { + if (undefined === name) { + return '_unknown'; + } + name = name.replace(/[^a-zA-Z0-9_]/g, '$'); + var f = name.charCodeAt(0); + if (f >= char_0 && f <= char_9) { + return `_${name}`; + } + return name; + } + function createNamedFunction(name, body) { + name = makeLegalFunctionName(name); + return { + [name]: function () { + return body.apply(this, arguments); + }, + }[name]; + } + function ensureOverloadTable(proto, methodName, humanName) { + if (undefined === proto[methodName].overloadTable) { + var prevFunc = proto[methodName]; + proto[methodName] = function () { + if ( + !proto[methodName].overloadTable.hasOwnProperty( + arguments.length + ) + ) { + throwBindingError( + `Function '${humanName}' called with an invalid number of arguments (${arguments.length}) - expects one of (${proto[methodName].overloadTable})!` + ); + } + return proto[methodName].overloadTable[ + arguments.length + ].apply(this, arguments); + }; + proto[methodName].overloadTable = []; + proto[methodName].overloadTable[prevFunc.argCount] = prevFunc; + } + } + function exposePublicSymbol(name, value, numArguments) { + if (Module.hasOwnProperty(name)) { + if ( + undefined === numArguments || + (undefined !== Module[name].overloadTable && + undefined !== Module[name].overloadTable[numArguments]) + ) { + throwBindingError( + `Cannot register public name '${name}' twice` + ); + } + ensureOverloadTable(Module, name, name); + if (Module.hasOwnProperty(numArguments)) { + throwBindingError( + `Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!` + ); + } + Module[name].overloadTable[numArguments] = value; + } else { + Module[name] = value; + if (undefined !== numArguments) { + Module[name].numArguments = numArguments; + } + } + } + function RegisteredClass( + name, + constructor, + instancePrototype, + rawDestructor, + baseClass, + getActualType, + upcast, + downcast + ) { + this.name = name; + this.constructor = constructor; + this.instancePrototype = instancePrototype; + this.rawDestructor = rawDestructor; + this.baseClass = baseClass; + this.getActualType = getActualType; + this.upcast = upcast; + this.downcast = downcast; + this.pureVirtualFunctions = []; + } + function upcastPointer(ptr, ptrClass, desiredClass) { + while (ptrClass !== desiredClass) { + if (!ptrClass.upcast) { + throwBindingError( + `Expected null or instance of ${desiredClass.name}, got an instance of ${ptrClass.name}` + ); + } + ptr = ptrClass.upcast(ptr); + ptrClass = ptrClass.baseClass; + } + return ptr; + } + function constNoSmartPtrRawPointerToWireType(destructors, handle) { + if (handle === null) { + if (this.isReference) { + throwBindingError(`null is not a valid ${this.name}`); + } + return 0; + } + if (!handle.$$) { + throwBindingError( + `Cannot pass "${embindRepr(handle)}" as a ${this.name}` + ); + } + if (!handle.$$.ptr) { + throwBindingError( + `Cannot pass deleted object as a pointer of type ${this.name}` + ); + } + var handleClass = handle.$$.ptrType.registeredClass; + var ptr = upcastPointer( + handle.$$.ptr, + handleClass, + this.registeredClass + ); + return ptr; + } + function genericPointerToWireType(destructors, handle) { + var ptr; + if (handle === null) { + if (this.isReference) { + throwBindingError(`null is not a valid ${this.name}`); + } + if (this.isSmartPointer) { + ptr = this.rawConstructor(); + if (destructors !== null) { + destructors.push(this.rawDestructor, ptr); + } + return ptr; + } else { + return 0; + } + } + if (!handle.$$) { + throwBindingError( + `Cannot pass "${embindRepr(handle)}" as a ${this.name}` + ); + } + if (!handle.$$.ptr) { + throwBindingError( + `Cannot pass deleted object as a pointer of type ${this.name}` + ); + } + if (!this.isConst && handle.$$.ptrType.isConst) { + throwBindingError( + `Cannot convert argument of type ${ + handle.$$.smartPtrType + ? handle.$$.smartPtrType.name + : handle.$$.ptrType.name + } to parameter type ${this.name}` + ); + } + var handleClass = handle.$$.ptrType.registeredClass; + ptr = upcastPointer( + handle.$$.ptr, + handleClass, + this.registeredClass + ); + if (this.isSmartPointer) { + if (undefined === handle.$$.smartPtr) { + throwBindingError( + 'Passing raw pointer to smart pointer is illegal' + ); + } + switch (this.sharingPolicy) { + case 0: + if (handle.$$.smartPtrType === this) { + ptr = handle.$$.smartPtr; + } else { + throwBindingError( + `Cannot convert argument of type ${ + handle.$$.smartPtrType + ? handle.$$.smartPtrType.name + : handle.$$.ptrType.name + } to parameter type ${this.name}` + ); + } + break; + case 1: + ptr = handle.$$.smartPtr; + break; + case 2: + if (handle.$$.smartPtrType === this) { + ptr = handle.$$.smartPtr; + } else { + var clonedHandle = handle['clone'](); + ptr = this.rawShare( + ptr, + Emval.toHandle(function () { + clonedHandle['delete'](); + }) + ); + if (destructors !== null) { + destructors.push(this.rawDestructor, ptr); + } + } + break; + default: + throwBindingError('Unsupporting sharing policy'); + } + } + return ptr; + } + function nonConstNoSmartPtrRawPointerToWireType(destructors, handle) { + if (handle === null) { + if (this.isReference) { + throwBindingError(`null is not a valid ${this.name}`); + } + return 0; + } + if (!handle.$$) { + throwBindingError( + `Cannot pass "${embindRepr(handle)}" as a ${this.name}` + ); + } + if (!handle.$$.ptr) { + throwBindingError( + `Cannot pass deleted object as a pointer of type ${this.name}` + ); + } + if (handle.$$.ptrType.isConst) { + throwBindingError( + `Cannot convert argument of type ${handle.$$.ptrType.name} to parameter type ${this.name}` + ); + } + var handleClass = handle.$$.ptrType.registeredClass; + var ptr = upcastPointer( + handle.$$.ptr, + handleClass, + this.registeredClass + ); + return ptr; + } + function RegisteredPointer_getPointee(ptr) { + if (this.rawGetPointee) { + ptr = this.rawGetPointee(ptr); + } + return ptr; + } + function RegisteredPointer_destructor(ptr) { + if (this.rawDestructor) { + this.rawDestructor(ptr); + } + } + function RegisteredPointer_deleteObject(handle) { + if (handle !== null) { + handle['delete'](); + } + } + function init_RegisteredPointer() { + RegisteredPointer.prototype.getPointee = + RegisteredPointer_getPointee; + RegisteredPointer.prototype.destructor = + RegisteredPointer_destructor; + RegisteredPointer.prototype['argPackAdvance'] = 8; + RegisteredPointer.prototype['readValueFromPointer'] = + simpleReadValueFromPointer; + RegisteredPointer.prototype['deleteObject'] = + RegisteredPointer_deleteObject; + RegisteredPointer.prototype['fromWireType'] = + RegisteredPointer_fromWireType; + } + function RegisteredPointer( + name, + registeredClass, + isReference, + isConst, + isSmartPointer, + pointeeType, + sharingPolicy, + rawGetPointee, + rawConstructor, + rawShare, + rawDestructor + ) { + this.name = name; + this.registeredClass = registeredClass; + this.isReference = isReference; + this.isConst = isConst; + this.isSmartPointer = isSmartPointer; + this.pointeeType = pointeeType; + this.sharingPolicy = sharingPolicy; + this.rawGetPointee = rawGetPointee; + this.rawConstructor = rawConstructor; + this.rawShare = rawShare; + this.rawDestructor = rawDestructor; + if (!isSmartPointer && registeredClass.baseClass === undefined) { + if (isConst) { + this['toWireType'] = constNoSmartPtrRawPointerToWireType; + this.destructorFunction = null; + } else { + this['toWireType'] = nonConstNoSmartPtrRawPointerToWireType; + this.destructorFunction = null; + } + } else { + this['toWireType'] = genericPointerToWireType; + } + } + function replacePublicSymbol(name, value, numArguments) { + if (!Module.hasOwnProperty(name)) { + throwInternalError('Replacing nonexistant public symbol'); + } + if ( + undefined !== Module[name].overloadTable && + undefined !== numArguments + ) { + Module[name].overloadTable[numArguments] = value; + } else { + Module[name] = value; + Module[name].argCount = numArguments; + } + } + var dynCallLegacy = (sig, ptr, args) => { + assert( + 'dynCall_' + sig in Module, + `bad function pointer type - dynCall function not found for sig '${sig}'` + ); + if (args && args.length) { + assert( + args.length === sig.substring(1).replace(/j/g, '--').length + ); + } else { + assert(sig.length == 1); + } + var f = Module['dynCall_' + sig]; + return args && args.length + ? f.apply(null, [ptr].concat(args)) + : f.call(null, ptr); + }; + var wasmTableMirror = []; + var getWasmTableEntry = (funcPtr) => { + var func = wasmTableMirror[funcPtr]; + if (!func) { + if (funcPtr >= wasmTableMirror.length) + wasmTableMirror.length = funcPtr + 1; + wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr); + } + assert( + wasmTable.get(funcPtr) == func, + 'JavaScript-side Wasm function table mirror is out of date!' + ); + return func; + }; + var dynCall = (sig, ptr, args) => { + if (sig.includes('j')) { + return dynCallLegacy(sig, ptr, args); + } + assert( + getWasmTableEntry(ptr), + `missing table entry in dynCall: ${ptr}` + ); + var rtn = getWasmTableEntry(ptr).apply(null, args); + return rtn; + }; + var getDynCaller = (sig, ptr) => { + assert( + sig.includes('j') || sig.includes('p'), + 'getDynCaller should only be called with i64 sigs' + ); + var argCache = []; + return function () { + argCache.length = 0; + Object.assign(argCache, arguments); + return dynCall(sig, ptr, argCache); + }; + }; + function embind__requireFunction(signature, rawFunction) { + signature = readLatin1String(signature); + function makeDynCaller() { + if (signature.includes('j')) { + return getDynCaller(signature, rawFunction); + } + return getWasmTableEntry(rawFunction); + } + var fp = makeDynCaller(); + if (typeof fp != 'function') { + throwBindingError( + `unknown function pointer with signature ${signature}: ${rawFunction}` + ); + } + return fp; + } + function extendError(baseErrorType, errorName) { + var errorClass = createNamedFunction(errorName, function (message) { + this.name = errorName; + this.message = message; + var stack = new Error(message).stack; + if (stack !== undefined) { + this.stack = + this.toString() + + '\n' + + stack.replace(/^Error(:[^\n]*)?\n/, ''); + } + }); + errorClass.prototype = Object.create(baseErrorType.prototype); + errorClass.prototype.constructor = errorClass; + errorClass.prototype.toString = function () { + if (this.message === undefined) { + return this.name; + } else { + return `${this.name}: ${this.message}`; + } + }; + return errorClass; + } + var UnboundTypeError = undefined; + function getTypeName(type) { + var ptr = ___getTypeName(type); + var rv = readLatin1String(ptr); + _free(ptr); + return rv; + } + function throwUnboundTypeError(message, types) { + var unboundTypes = []; + var seen = {}; + function visit(type) { + if (seen[type]) { + return; + } + if (registeredTypes[type]) { + return; + } + if (typeDependencies[type]) { + typeDependencies[type].forEach(visit); + return; + } + unboundTypes.push(type); + seen[type] = true; + } + types.forEach(visit); + throw new UnboundTypeError( + `${message}: ` + unboundTypes.map(getTypeName).join([', ']) + ); + } + function __embind_register_class( + rawType, + rawPointerType, + rawConstPointerType, + baseClassRawType, + getActualTypeSignature, + getActualType, + upcastSignature, + upcast, + downcastSignature, + downcast, + name, + destructorSignature, + rawDestructor + ) { + name = readLatin1String(name); + getActualType = embind__requireFunction( + getActualTypeSignature, + getActualType + ); + if (upcast) { + upcast = embind__requireFunction(upcastSignature, upcast); + } + if (downcast) { + downcast = embind__requireFunction(downcastSignature, downcast); + } + rawDestructor = embind__requireFunction( + destructorSignature, + rawDestructor + ); + var legalFunctionName = makeLegalFunctionName(name); + exposePublicSymbol(legalFunctionName, function () { + throwUnboundTypeError( + `Cannot construct ${name} due to unbound types`, + [baseClassRawType] + ); + }); + whenDependentTypesAreResolved( + [rawType, rawPointerType, rawConstPointerType], + baseClassRawType ? [baseClassRawType] : [], + function (base) { + base = base[0]; + var baseClass; + var basePrototype; + if (baseClassRawType) { + baseClass = base.registeredClass; + basePrototype = baseClass.instancePrototype; + } else { + basePrototype = ClassHandle.prototype; + } + var constructor = createNamedFunction( + legalFunctionName, + function () { + if ( + Object.getPrototypeOf(this) !== + instancePrototype + ) { + throw new BindingError( + "Use 'new' to construct " + name + ); + } + if ( + undefined === registeredClass.constructor_body + ) { + throw new BindingError( + name + ' has no accessible constructor' + ); + } + var body = + registeredClass.constructor_body[ + arguments.length + ]; + if (undefined === body) { + throw new BindingError( + `Tried to invoke ctor of ${name} with invalid number of parameters (${ + arguments.length + }) - expected (${Object.keys( + registeredClass.constructor_body + ).toString()}) parameters instead!` + ); + } + return body.apply(this, arguments); + } + ); + var instancePrototype = Object.create(basePrototype, { + constructor: { value: constructor }, + }); + constructor.prototype = instancePrototype; + var registeredClass = new RegisteredClass( + name, + constructor, + instancePrototype, + rawDestructor, + baseClass, + getActualType, + upcast, + downcast + ); + if (registeredClass.baseClass) { + if ( + registeredClass.baseClass.__derivedClasses === + undefined + ) { + registeredClass.baseClass.__derivedClasses = []; + } + registeredClass.baseClass.__derivedClasses.push( + registeredClass + ); + } + var referenceConverter = new RegisteredPointer( + name, + registeredClass, + true, + false, + false + ); + var pointerConverter = new RegisteredPointer( + name + '*', + registeredClass, + false, + false, + false + ); + var constPointerConverter = new RegisteredPointer( + name + ' const*', + registeredClass, + false, + true, + false + ); + registeredPointers[rawType] = { + pointerType: pointerConverter, + constPointerType: constPointerConverter, + }; + replacePublicSymbol(legalFunctionName, constructor); + return [ + referenceConverter, + pointerConverter, + constPointerConverter, + ]; + } + ); + } + function heap32VectorToArray(count, firstElement) { + var array = []; + for (var i = 0; i < count; i++) { + array.push(HEAPU32[(firstElement + i * 4) >> 2]); + } + return array; + } + function newFunc(constructor, argumentList) { + if (!(constructor instanceof Function)) { + throw new TypeError( + `new_ called with constructor type ${typeof constructor} which is not a function` + ); + } + var dummy = createNamedFunction( + constructor.name || 'unknownFunctionName', + function () {} + ); + dummy.prototype = constructor.prototype; + var obj = new dummy(); + var r = constructor.apply(obj, argumentList); + return r instanceof Object ? r : obj; + } + function craftInvokerFunction( + humanName, + argTypes, + classType, + cppInvokerFunc, + cppTargetFunc, + isAsync + ) { + var argCount = argTypes.length; + if (argCount < 2) { + throwBindingError( + "argTypes array size mismatch! Must at least get return value and 'this' types!" + ); + } + assert(!isAsync, 'Async bindings are only supported with JSPI.'); + var isClassMethodFunc = argTypes[1] !== null && classType !== null; + var needsDestructorStack = false; + for (var i = 1; i < argTypes.length; ++i) { + if ( + argTypes[i] !== null && + argTypes[i].destructorFunction === undefined + ) { + needsDestructorStack = true; + break; + } + } + var returns = argTypes[0].name !== 'void'; + var argsList = ''; + var argsListWired = ''; + for (var i = 0; i < argCount - 2; ++i) { + argsList += (i !== 0 ? ', ' : '') + 'arg' + i; + argsListWired += (i !== 0 ? ', ' : '') + 'arg' + i + 'Wired'; + } + var invokerFnBody = `\n return function ${makeLegalFunctionName( + humanName + )}(${argsList}) {\n if (arguments.length !== ${ + argCount - 2 + }) {\n throwBindingError('function ${humanName} called with ${ + arguments.length + } arguments, expected ${argCount - 2} args!');\n }`; + if (needsDestructorStack) { + invokerFnBody += 'var destructors = [];\n'; + } + var dtorStack = needsDestructorStack ? 'destructors' : 'null'; + var args1 = [ + 'throwBindingError', + 'invoker', + 'fn', + 'runDestructors', + 'retType', + 'classParam', + ]; + var args2 = [ + throwBindingError, + cppInvokerFunc, + cppTargetFunc, + runDestructors, + argTypes[0], + argTypes[1], + ]; + if (isClassMethodFunc) { + invokerFnBody += + 'var thisWired = classParam.toWireType(' + + dtorStack + + ', this);\n'; + } + for (var i = 0; i < argCount - 2; ++i) { + invokerFnBody += + 'var arg' + + i + + 'Wired = argType' + + i + + '.toWireType(' + + dtorStack + + ', arg' + + i + + '); // ' + + argTypes[i + 2].name + + '\n'; + args1.push('argType' + i); + args2.push(argTypes[i + 2]); + } + if (isClassMethodFunc) { + argsListWired = + 'thisWired' + + (argsListWired.length > 0 ? ', ' : '') + + argsListWired; + } + invokerFnBody += + (returns || isAsync ? 'var rv = ' : '') + + 'invoker(fn' + + (argsListWired.length > 0 ? ', ' : '') + + argsListWired + + ');\n'; + if (needsDestructorStack) { + invokerFnBody += 'runDestructors(destructors);\n'; + } else { + for ( + var i = isClassMethodFunc ? 1 : 2; + i < argTypes.length; + ++i + ) { + var paramName = + i === 1 ? 'thisWired' : 'arg' + (i - 2) + 'Wired'; + if (argTypes[i].destructorFunction !== null) { + invokerFnBody += + paramName + + '_dtor(' + + paramName + + '); // ' + + argTypes[i].name + + '\n'; + args1.push(paramName + '_dtor'); + args2.push(argTypes[i].destructorFunction); + } + } + } + if (returns) { + invokerFnBody += + 'var ret = retType.fromWireType(rv);\n' + 'return ret;\n'; + } else { + } + invokerFnBody += '}\n'; + args1.push(invokerFnBody); + return newFunc(Function, args1).apply(null, args2); + } + function __embind_register_class_constructor( + rawClassType, + argCount, + rawArgTypesAddr, + invokerSignature, + invoker, + rawConstructor + ) { + assert(argCount > 0); + var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); + invoker = embind__requireFunction(invokerSignature, invoker); + whenDependentTypesAreResolved( + [], + [rawClassType], + function (classType) { + classType = classType[0]; + var humanName = `constructor ${classType.name}`; + if ( + undefined === classType.registeredClass.constructor_body + ) { + classType.registeredClass.constructor_body = []; + } + if ( + undefined !== + classType.registeredClass.constructor_body[argCount - 1] + ) { + throw new BindingError( + `Cannot register multiple constructors with identical number of parameters (${ + argCount - 1 + }) for class '${ + classType.name + }'! Overload resolution is currently only performed using the parameter count, not actual type info!` + ); + } + classType.registeredClass.constructor_body[argCount - 1] = + () => { + throwUnboundTypeError( + `Cannot construct ${classType.name} due to unbound types`, + rawArgTypes + ); + }; + whenDependentTypesAreResolved( + [], + rawArgTypes, + function (argTypes) { + argTypes.splice(1, 0, null); + classType.registeredClass.constructor_body[ + argCount - 1 + ] = craftInvokerFunction( + humanName, + argTypes, + null, + invoker, + rawConstructor + ); + return []; + } + ); + return []; + } + ); + } + function __embind_register_class_function( + rawClassType, + methodName, + argCount, + rawArgTypesAddr, + invokerSignature, + rawInvoker, + context, + isPureVirtual, + isAsync + ) { + var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); + methodName = readLatin1String(methodName); + rawInvoker = embind__requireFunction(invokerSignature, rawInvoker); + whenDependentTypesAreResolved( + [], + [rawClassType], + function (classType) { + classType = classType[0]; + var humanName = `${classType.name}.${methodName}`; + if (methodName.startsWith('@@')) { + methodName = Symbol[methodName.substring(2)]; + } + if (isPureVirtual) { + classType.registeredClass.pureVirtualFunctions.push( + methodName + ); + } + function unboundTypesHandler() { + throwUnboundTypeError( + `Cannot call ${humanName} due to unbound types`, + rawArgTypes + ); + } + var proto = classType.registeredClass.instancePrototype; + var method = proto[methodName]; + if ( + undefined === method || + (undefined === method.overloadTable && + method.className !== classType.name && + method.argCount === argCount - 2) + ) { + unboundTypesHandler.argCount = argCount - 2; + unboundTypesHandler.className = classType.name; + proto[methodName] = unboundTypesHandler; + } else { + ensureOverloadTable(proto, methodName, humanName); + proto[methodName].overloadTable[argCount - 2] = + unboundTypesHandler; + } + whenDependentTypesAreResolved( + [], + rawArgTypes, + function (argTypes) { + var memberFunction = craftInvokerFunction( + humanName, + argTypes, + classType, + rawInvoker, + context, + isAsync + ); + if (undefined === proto[methodName].overloadTable) { + memberFunction.argCount = argCount - 2; + proto[methodName] = memberFunction; + } else { + proto[methodName].overloadTable[argCount - 2] = + memberFunction; + } + return []; + } + ); + return []; + } + ); + } + function handleAllocatorInit() { + Object.assign(HandleAllocator.prototype, { + get(id) { + assert( + this.allocated[id] !== undefined, + `invalid handle: ${id}` + ); + return this.allocated[id]; + }, + has(id) { + return this.allocated[id] !== undefined; + }, + allocate(handle) { + var id = this.freelist.pop() || this.allocated.length; + this.allocated[id] = handle; + return id; + }, + free(id) { + assert(this.allocated[id] !== undefined); + this.allocated[id] = undefined; + this.freelist.push(id); + }, + }); + } + function HandleAllocator() { + this.allocated = [undefined]; + this.freelist = []; + } + var emval_handles = new HandleAllocator(); + function __emval_decref(handle) { + if ( + handle >= emval_handles.reserved && + 0 === --emval_handles.get(handle).refcount + ) { + emval_handles.free(handle); + } + } + function count_emval_handles() { + var count = 0; + for ( + var i = emval_handles.reserved; + i < emval_handles.allocated.length; + ++i + ) { + if (emval_handles.allocated[i] !== undefined) { + ++count; + } + } + return count; + } + function init_emval() { + emval_handles.allocated.push( + { value: undefined }, + { value: null }, + { value: true }, + { value: false } + ); + emval_handles.reserved = emval_handles.allocated.length; + Module['count_emval_handles'] = count_emval_handles; + } + var Emval = { + toValue: (handle) => { + if (!handle) { + throwBindingError( + 'Cannot use deleted val. handle = ' + handle + ); + } + return emval_handles.get(handle).value; + }, + toHandle: (value) => { + switch (value) { + case undefined: + return 1; + case null: + return 2; + case true: + return 3; + case false: + return 4; + default: { + return emval_handles.allocate({ + refcount: 1, + value: value, + }); + } + } + }, + }; + function __embind_register_emval(rawType, name) { + name = readLatin1String(name); + registerType(rawType, { + name: name, + fromWireType: function (handle) { + var rv = Emval.toValue(handle); + __emval_decref(handle); + return rv; + }, + toWireType: function (destructors, value) { + return Emval.toHandle(value); + }, + argPackAdvance: 8, + readValueFromPointer: simpleReadValueFromPointer, + destructorFunction: null, + }); + } + function embindRepr(v) { + if (v === null) { + return 'null'; + } + var t = typeof v; + if (t === 'object' || t === 'array' || t === 'function') { + return v.toString(); + } else { + return '' + v; + } + } + function floatReadValueFromPointer(name, shift) { + switch (shift) { + case 2: + return function (pointer) { + return this['fromWireType'](HEAPF32[pointer >> 2]); + }; + case 3: + return function (pointer) { + return this['fromWireType'](HEAPF64[pointer >> 3]); + }; + default: + throw new TypeError('Unknown float type: ' + name); + } + } + function __embind_register_float(rawType, name, size) { + var shift = getShiftFromSize(size); + name = readLatin1String(name); + registerType(rawType, { + name: name, + fromWireType: function (value) { + return value; + }, + toWireType: function (destructors, value) { + if (typeof value != 'number' && typeof value != 'boolean') { + throw new TypeError( + `Cannot convert ${embindRepr(value)} to ${ + this.name + }` + ); + } + return value; + }, + argPackAdvance: 8, + readValueFromPointer: floatReadValueFromPointer(name, shift), + destructorFunction: null, + }); + } + function __embind_register_function( + name, + argCount, + rawArgTypesAddr, + signature, + rawInvoker, + fn, + isAsync + ) { + var argTypes = heap32VectorToArray(argCount, rawArgTypesAddr); + name = readLatin1String(name); + rawInvoker = embind__requireFunction(signature, rawInvoker); + exposePublicSymbol( + name, + function () { + throwUnboundTypeError( + `Cannot call ${name} due to unbound types`, + argTypes + ); + }, + argCount - 1 + ); + whenDependentTypesAreResolved([], argTypes, function (argTypes) { + var invokerArgsArray = [argTypes[0], null].concat( + argTypes.slice(1) + ); + replacePublicSymbol( + name, + craftInvokerFunction( + name, + invokerArgsArray, + null, + rawInvoker, + fn, + isAsync + ), + argCount - 1 + ); + return []; + }); + } + function integerReadValueFromPointer(name, shift, signed) { + switch (shift) { + case 0: + return signed + ? function readS8FromPointer(pointer) { + return HEAP8[pointer]; + } + : function readU8FromPointer(pointer) { + return HEAPU8[pointer]; + }; + case 1: + return signed + ? function readS16FromPointer(pointer) { + return HEAP16[pointer >> 1]; + } + : function readU16FromPointer(pointer) { + return HEAPU16[pointer >> 1]; + }; + case 2: + return signed + ? function readS32FromPointer(pointer) { + return HEAP32[pointer >> 2]; + } + : function readU32FromPointer(pointer) { + return HEAPU32[pointer >> 2]; + }; + default: + throw new TypeError('Unknown integer type: ' + name); + } + } + function __embind_register_integer( + primitiveType, + name, + size, + minRange, + maxRange + ) { + name = readLatin1String(name); + if (maxRange === -1) { + maxRange = 4294967295; + } + var shift = getShiftFromSize(size); + var fromWireType = (value) => value; + if (minRange === 0) { + var bitshift = 32 - 8 * size; + fromWireType = (value) => (value << bitshift) >>> bitshift; + } + var isUnsignedType = name.includes('unsigned'); + var checkAssertions = (value, toTypeName) => { + if (typeof value != 'number' && typeof value != 'boolean') { + throw new TypeError( + `Cannot convert "${embindRepr(value)}" to ${toTypeName}` + ); + } + if (value < minRange || value > maxRange) { + throw new TypeError( + `Passing a number "${embindRepr( + value + )}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!` + ); + } + }; + var toWireType; + if (isUnsignedType) { + toWireType = function (destructors, value) { + checkAssertions(value, this.name); + return value >>> 0; + }; + } else { + toWireType = function (destructors, value) { + checkAssertions(value, this.name); + return value; + }; + } + registerType(primitiveType, { + name: name, + fromWireType: fromWireType, + toWireType: toWireType, + argPackAdvance: 8, + readValueFromPointer: integerReadValueFromPointer( + name, + shift, + minRange !== 0 + ), + destructorFunction: null, + }); + } + function __embind_register_memory_view(rawType, dataTypeIndex, name) { + var typeMapping = [ + Int8Array, + Uint8Array, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array, + ]; + var TA = typeMapping[dataTypeIndex]; + function decodeMemoryView(handle) { + handle = handle >> 2; + var heap = HEAPU32; + var size = heap[handle]; + var data = heap[handle + 1]; + return new TA(heap.buffer, data, size); + } + name = readLatin1String(name); + registerType( + rawType, + { + name: name, + fromWireType: decodeMemoryView, + argPackAdvance: 8, + readValueFromPointer: decodeMemoryView, + }, + { ignoreDuplicateRegistrations: true } + ); + } + var stringToUTF8 = (str, outPtr, maxBytesToWrite) => { + assert( + typeof maxBytesToWrite == 'number', + 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!' + ); + return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite); + }; + function __embind_register_std_string(rawType, name) { + name = readLatin1String(name); + var stdStringIsUTF8 = name === 'std::string'; + registerType(rawType, { + name: name, + fromWireType: function (value) { + var length = HEAPU32[value >> 2]; + var payload = value + 4; + var str; + if (stdStringIsUTF8) { + var decodeStartPtr = payload; + for (var i = 0; i <= length; ++i) { + var currentBytePtr = payload + i; + if (i == length || HEAPU8[currentBytePtr] == 0) { + var maxRead = currentBytePtr - decodeStartPtr; + var stringSegment = UTF8ToString( + decodeStartPtr, + maxRead + ); + if (str === undefined) { + str = stringSegment; + } else { + str += String.fromCharCode(0); + str += stringSegment; + } + decodeStartPtr = currentBytePtr + 1; + } + } + } else { + var a = new Array(length); + for (var i = 0; i < length; ++i) { + a[i] = String.fromCharCode(HEAPU8[payload + i]); + } + str = a.join(''); + } + _free(value); + return str; + }, + toWireType: function (destructors, value) { + if (value instanceof ArrayBuffer) { + value = new Uint8Array(value); + } + var length; + var valueIsOfTypeString = typeof value == 'string'; + if ( + !( + valueIsOfTypeString || + value instanceof Uint8Array || + value instanceof Uint8ClampedArray || + value instanceof Int8Array + ) + ) { + throwBindingError( + 'Cannot pass non-string to std::string' + ); + } + if (stdStringIsUTF8 && valueIsOfTypeString) { + length = lengthBytesUTF8(value); + } else { + length = value.length; + } + var base = _malloc(4 + length + 1); + var ptr = base + 4; + HEAPU32[base >> 2] = length; + checkInt32(length); + if (stdStringIsUTF8 && valueIsOfTypeString) { + stringToUTF8(value, ptr, length + 1); + } else { + if (valueIsOfTypeString) { + for (var i = 0; i < length; ++i) { + var charCode = value.charCodeAt(i); + if (charCode > 255) { + _free(ptr); + throwBindingError( + 'String has UTF-16 code units that do not fit in 8 bits' + ); + } + HEAPU8[ptr + i] = charCode; + } + } else { + for (var i = 0; i < length; ++i) { + HEAPU8[ptr + i] = value[i]; + } + } + } + if (destructors !== null) { + destructors.push(_free, base); + } + return base; + }, + argPackAdvance: 8, + readValueFromPointer: simpleReadValueFromPointer, + destructorFunction: function (ptr) { + _free(ptr); + }, + }); + } + var UTF16Decoder = + typeof TextDecoder != 'undefined' + ? new TextDecoder('utf-16le') + : undefined; + var UTF16ToString = (ptr, maxBytesToRead) => { + assert( + ptr % 2 == 0, + 'Pointer passed to UTF16ToString must be aligned to two bytes!' + ); + var endPtr = ptr; + var idx = endPtr >> 1; + var maxIdx = idx + maxBytesToRead / 2; + while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx; + endPtr = idx << 1; + if (endPtr - ptr > 32 && UTF16Decoder) + return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr)); + var str = ''; + for (var i = 0; !(i >= maxBytesToRead / 2); ++i) { + var codeUnit = HEAP16[(ptr + i * 2) >> 1]; + if (codeUnit == 0) break; + str += String.fromCharCode(codeUnit); + } + return str; + }; + var stringToUTF16 = (str, outPtr, maxBytesToWrite) => { + assert( + outPtr % 2 == 0, + 'Pointer passed to stringToUTF16 must be aligned to two bytes!' + ); + assert( + typeof maxBytesToWrite == 'number', + 'stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!' + ); + if (maxBytesToWrite === undefined) { + maxBytesToWrite = 2147483647; + } + if (maxBytesToWrite < 2) return 0; + maxBytesToWrite -= 2; + var startPtr = outPtr; + var numCharsToWrite = + maxBytesToWrite < str.length * 2 + ? maxBytesToWrite / 2 + : str.length; + for (var i = 0; i < numCharsToWrite; ++i) { + var codeUnit = str.charCodeAt(i); + HEAP16[outPtr >> 1] = codeUnit; + checkInt16(codeUnit); + outPtr += 2; + } + HEAP16[outPtr >> 1] = 0; + checkInt16(0); + return outPtr - startPtr; + }; + var lengthBytesUTF16 = (str) => str.length * 2; + var UTF32ToString = (ptr, maxBytesToRead) => { + assert( + ptr % 4 == 0, + 'Pointer passed to UTF32ToString must be aligned to four bytes!' + ); + var i = 0; + var str = ''; + while (!(i >= maxBytesToRead / 4)) { + var utf32 = HEAP32[(ptr + i * 4) >> 2]; + if (utf32 == 0) break; + ++i; + if (utf32 >= 65536) { + var ch = utf32 - 65536; + str += String.fromCharCode( + 55296 | (ch >> 10), + 56320 | (ch & 1023) + ); + } else { + str += String.fromCharCode(utf32); + } + } + return str; + }; + var stringToUTF32 = (str, outPtr, maxBytesToWrite) => { + assert( + outPtr % 4 == 0, + 'Pointer passed to stringToUTF32 must be aligned to four bytes!' + ); + assert( + typeof maxBytesToWrite == 'number', + 'stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!' + ); + if (maxBytesToWrite === undefined) { + maxBytesToWrite = 2147483647; + } + if (maxBytesToWrite < 4) return 0; + var startPtr = outPtr; + var endPtr = startPtr + maxBytesToWrite - 4; + for (var i = 0; i < str.length; ++i) { + var codeUnit = str.charCodeAt(i); + if (codeUnit >= 55296 && codeUnit <= 57343) { + var trailSurrogate = str.charCodeAt(++i); + codeUnit = + (65536 + ((codeUnit & 1023) << 10)) | + (trailSurrogate & 1023); + } + HEAP32[outPtr >> 2] = codeUnit; + checkInt32(codeUnit); + outPtr += 4; + if (outPtr + 4 > endPtr) break; + } + HEAP32[outPtr >> 2] = 0; + checkInt32(0); + return outPtr - startPtr; + }; + var lengthBytesUTF32 = (str) => { + var len = 0; + for (var i = 0; i < str.length; ++i) { + var codeUnit = str.charCodeAt(i); + if (codeUnit >= 55296 && codeUnit <= 57343) ++i; + len += 4; + } + return len; + }; + var __embind_register_std_wstring = function (rawType, charSize, name) { + name = readLatin1String(name); + var decodeString, encodeString, getHeap, lengthBytesUTF, shift; + if (charSize === 2) { + decodeString = UTF16ToString; + encodeString = stringToUTF16; + lengthBytesUTF = lengthBytesUTF16; + getHeap = () => HEAPU16; + shift = 1; + } else if (charSize === 4) { + decodeString = UTF32ToString; + encodeString = stringToUTF32; + lengthBytesUTF = lengthBytesUTF32; + getHeap = () => HEAPU32; + shift = 2; + } + registerType(rawType, { + name: name, + fromWireType: function (value) { + var length = HEAPU32[value >> 2]; + var HEAP = getHeap(); + var str; + var decodeStartPtr = value + 4; + for (var i = 0; i <= length; ++i) { + var currentBytePtr = value + 4 + i * charSize; + if (i == length || HEAP[currentBytePtr >> shift] == 0) { + var maxReadBytes = currentBytePtr - decodeStartPtr; + var stringSegment = decodeString( + decodeStartPtr, + maxReadBytes + ); + if (str === undefined) { + str = stringSegment; + } else { + str += String.fromCharCode(0); + str += stringSegment; + } + decodeStartPtr = currentBytePtr + charSize; + } + } + _free(value); + return str; + }, + toWireType: function (destructors, value) { + if (!(typeof value == 'string')) { + throwBindingError( + `Cannot pass non-string to C++ string type ${name}` + ); + } + var length = lengthBytesUTF(value); + var ptr = _malloc(4 + length + charSize); + HEAPU32[ptr >> 2] = length >> shift; + encodeString(value, ptr + 4, length + charSize); + if (destructors !== null) { + destructors.push(_free, ptr); + } + return ptr; + }, + argPackAdvance: 8, + readValueFromPointer: simpleReadValueFromPointer, + destructorFunction: function (ptr) { + _free(ptr); + }, + }); + }; + function __embind_register_value_object( + rawType, + name, + constructorSignature, + rawConstructor, + destructorSignature, + rawDestructor + ) { + structRegistrations[rawType] = { + name: readLatin1String(name), + rawConstructor: embind__requireFunction( + constructorSignature, + rawConstructor + ), + rawDestructor: embind__requireFunction( + destructorSignature, + rawDestructor + ), + fields: [], + }; + } + function __embind_register_value_object_field( + structType, + fieldName, + getterReturnType, + getterSignature, + getter, + getterContext, + setterArgumentType, + setterSignature, + setter, + setterContext + ) { + structRegistrations[structType].fields.push({ + fieldName: readLatin1String(fieldName), + getterReturnType: getterReturnType, + getter: embind__requireFunction(getterSignature, getter), + getterContext: getterContext, + setterArgumentType: setterArgumentType, + setter: embind__requireFunction(setterSignature, setter), + setterContext: setterContext, + }); + } + function __embind_register_void(rawType, name) { + name = readLatin1String(name); + registerType(rawType, { + isVoid: true, + name: name, + argPackAdvance: 0, + fromWireType: function () { + return undefined; + }, + toWireType: function (destructors, o) { + return undefined; + }, + }); + } + function __emval_incref(handle) { + if (handle > 4) { + emval_handles.get(handle).refcount += 1; + } + } + function requireRegisteredType(rawType, humanName) { + var impl = registeredTypes[rawType]; + if (undefined === impl) { + throwBindingError( + humanName + ' has unknown type ' + getTypeName(rawType) + ); + } + return impl; + } + function __emval_take_value(type, arg) { + type = requireRegisteredType(type, '_emval_take_value'); + var v = type['readValueFromPointer'](arg); + return Emval.toHandle(v); + } + function convertI32PairToI53Checked(lo, hi) { + assert(lo == lo >>> 0 || lo == (lo | 0)); + assert(hi === (hi | 0)); + return (hi + 2097152) >>> 0 < 4194305 - !!lo + ? (lo >>> 0) + hi * 4294967296 + : NaN; + } + function __mmap_js( + len, + prot, + flags, + fd, + offset_low, + offset_high, + allocated, + addr + ) { + var offset = convertI32PairToI53Checked(offset_low, offset_high); + try { + if (isNaN(offset)) return 61; + var stream = SYSCALLS.getStreamFromFD(fd); + var res = FS.mmap(stream, len, offset, prot, flags); + var ptr = res.ptr; + HEAP32[allocated >> 2] = res.allocated; + checkInt32(res.allocated); + HEAPU32[addr >> 2] = ptr; + return 0; + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) + throw e; + return -e.errno; + } + } + function __munmap_js( + addr, + len, + prot, + flags, + fd, + offset_low, + offset_high + ) { + var offset = convertI32PairToI53Checked(offset_low, offset_high); + try { + if (isNaN(offset)) return 61; + var stream = SYSCALLS.getStreamFromFD(fd); + if (prot & 2) { + SYSCALLS.doMsync(addr, stream, len, flags, offset); + } + FS.munmap(stream); + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) + throw e; + return -e.errno; + } + } + var _abort = () => { + abort('native code called abort()'); + }; + var _emscripten_memcpy_big = (dest, src, num) => + HEAPU8.copyWithin(dest, src, src + num); + var getHeapMax = () => 2147483648; + var _emscripten_get_now; + _emscripten_get_now = () => performance.now(); + var growMemory = (size) => { + var b = wasmMemory.buffer; + var pages = (size - b.byteLength + 65535) >>> 16; + try { + wasmMemory.grow(pages); + updateMemoryViews(); + return 1; + } catch (e) { + err( + `growMemory: Attempted to grow heap from ${b.byteLength} bytes to ${size} bytes, but got error: ${e}` + ); + } + }; + var _emscripten_resize_heap = (requestedSize) => { + var oldSize = HEAPU8.length; + requestedSize >>>= 0; + assert(requestedSize > oldSize); + var maxHeapSize = getHeapMax(); + if (requestedSize > maxHeapSize) { + err( + `Cannot enlarge memory, asked to go up to ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!` + ); + return false; + } + var alignUp = (x, multiple) => + x + ((multiple - (x % multiple)) % multiple); + for (var cutDown = 1; cutDown <= 4; cutDown *= 2) { + var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); + overGrownHeapSize = Math.min( + overGrownHeapSize, + requestedSize + 100663296 + ); + var newSize = Math.min( + maxHeapSize, + alignUp(Math.max(requestedSize, overGrownHeapSize), 65536) + ); + var t0 = _emscripten_get_now(); + var replacement = growMemory(newSize); + var t1 = _emscripten_get_now(); + out( + `Heap resize call from ${oldSize} to ${newSize} took ${ + t1 - t0 + } msecs. Success: ${!!replacement}` + ); + if (replacement) { + return true; + } + } + err( + `Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!` + ); + return false; + }; + var ENV = {}; + var getExecutableName = () => thisProgram || './this.program'; + var getEnvStrings = () => { + if (!getEnvStrings.strings) { + var lang = + ( + (typeof navigator == 'object' && + navigator.languages && + navigator.languages[0]) || + 'C' + ).replace('-', '_') + '.UTF-8'; + var env = { + USER: 'web_user', + LOGNAME: 'web_user', + PATH: '/', + PWD: '/', + HOME: '/home/web_user', + LANG: lang, + _: getExecutableName(), + }; + for (var x in ENV) { + if (ENV[x] === undefined) delete env[x]; + else env[x] = ENV[x]; + } + var strings = []; + for (var x in env) { + strings.push(`${x}=${env[x]}`); + } + getEnvStrings.strings = strings; + } + return getEnvStrings.strings; + }; + var stringToAscii = (str, buffer) => { + for (var i = 0; i < str.length; ++i) { + assert(str.charCodeAt(i) === (str.charCodeAt(i) & 255)); + HEAP8[buffer++ >> 0] = str.charCodeAt(i); + checkInt8(str.charCodeAt(i)); + } + HEAP8[buffer >> 0] = 0; + checkInt8(0); + }; + var _environ_get = (__environ, environ_buf) => { + var bufSize = 0; + getEnvStrings().forEach(function (string, i) { + var ptr = environ_buf + bufSize; + HEAPU32[(__environ + i * 4) >> 2] = ptr; + checkInt32(ptr); + stringToAscii(string, ptr); + bufSize += string.length + 1; + }); + return 0; + }; + var _environ_sizes_get = (penviron_count, penviron_buf_size) => { + var strings = getEnvStrings(); + HEAPU32[penviron_count >> 2] = strings.length; + checkInt32(strings.length); + var bufSize = 0; + strings.forEach(function (string) { + bufSize += string.length + 1; + }); + HEAPU32[penviron_buf_size >> 2] = bufSize; + checkInt32(bufSize); + return 0; + }; + function _fd_close(fd) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + FS.close(stream); + return 0; + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) + throw e; + return e.errno; + } + } + var doReadv = (stream, iov, iovcnt, offset) => { + var ret = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = HEAPU32[iov >> 2]; + var len = HEAPU32[(iov + 4) >> 2]; + iov += 8; + var curr = FS.read(stream, HEAP8, ptr, len, offset); + if (curr < 0) return -1; + ret += curr; + if (curr < len) break; + if (typeof offset !== 'undefined') { + offset += curr; + } + } + return ret; + }; + function _fd_read(fd, iov, iovcnt, pnum) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var num = doReadv(stream, iov, iovcnt); + HEAPU32[pnum >> 2] = num; + checkInt32(num); + return 0; + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) + throw e; + return e.errno; + } + } + function _fd_seek(fd, offset_low, offset_high, whence, newOffset) { + var offset = convertI32PairToI53Checked(offset_low, offset_high); + try { + if (isNaN(offset)) return 61; + var stream = SYSCALLS.getStreamFromFD(fd); + FS.llseek(stream, offset, whence); + (tempI64 = [ + stream.position >>> 0, + ((tempDouble = stream.position), + +Math.abs(tempDouble) >= 1 + ? tempDouble > 0 + ? +Math.floor(tempDouble / 4294967296) >>> 0 + : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / + 4294967296 + ) >>> 0 + : 0), + ]), + (HEAP32[newOffset >> 2] = tempI64[0]), + (HEAP32[(newOffset + 4) >> 2] = tempI64[1]); + checkInt64(stream.position); + if (stream.getdents && offset === 0 && whence === 0) + stream.getdents = null; + return 0; + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) + throw e; + return e.errno; + } + } + var doWritev = (stream, iov, iovcnt, offset) => { + var ret = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = HEAPU32[iov >> 2]; + var len = HEAPU32[(iov + 4) >> 2]; + iov += 8; + var curr = FS.write(stream, HEAP8, ptr, len, offset); + if (curr < 0) return -1; + ret += curr; + if (typeof offset !== 'undefined') { + offset += curr; + } + } + return ret; + }; + function _fd_write(fd, iov, iovcnt, pnum) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var num = doWritev(stream, iov, iovcnt); + HEAPU32[pnum >> 2] = num; + checkInt32(num); + return 0; + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) + throw e; + return e.errno; + } + } + var isLeapYear = (year) => + year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0); + var arraySum = (array, index) => { + var sum = 0; + for (var i = 0; i <= index; sum += array[i++]) {} + return sum; + }; + var MONTH_DAYS_LEAP = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + var MONTH_DAYS_REGULAR = [ + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, + ]; + var addDays = (date, days) => { + var newDate = new Date(date.getTime()); + while (days > 0) { + var leap = isLeapYear(newDate.getFullYear()); + var currentMonth = newDate.getMonth(); + var daysInCurrentMonth = ( + leap ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR + )[currentMonth]; + if (days > daysInCurrentMonth - newDate.getDate()) { + days -= daysInCurrentMonth - newDate.getDate() + 1; + newDate.setDate(1); + if (currentMonth < 11) { + newDate.setMonth(currentMonth + 1); + } else { + newDate.setMonth(0); + newDate.setFullYear(newDate.getFullYear() + 1); + } + } else { + newDate.setDate(newDate.getDate() + days); + return newDate; + } + } + return newDate; + }; + var writeArrayToMemory = (array, buffer) => { + assert( + array.length >= 0, + 'writeArrayToMemory array must have a length (should be an array or typed array)' + ); + HEAP8.set(array, buffer); + }; + var _strftime = (s, maxsize, format, tm) => { + var tm_zone = HEAP32[(tm + 40) >> 2]; + var date = { + tm_sec: HEAP32[tm >> 2], + tm_min: HEAP32[(tm + 4) >> 2], + tm_hour: HEAP32[(tm + 8) >> 2], + tm_mday: HEAP32[(tm + 12) >> 2], + tm_mon: HEAP32[(tm + 16) >> 2], + tm_year: HEAP32[(tm + 20) >> 2], + tm_wday: HEAP32[(tm + 24) >> 2], + tm_yday: HEAP32[(tm + 28) >> 2], + tm_isdst: HEAP32[(tm + 32) >> 2], + tm_gmtoff: HEAP32[(tm + 36) >> 2], + tm_zone: tm_zone ? UTF8ToString(tm_zone) : '', + }; + var pattern = UTF8ToString(format); + var EXPANSION_RULES_1 = { + '%c': '%a %b %d %H:%M:%S %Y', + '%D': '%m/%d/%y', + '%F': '%Y-%m-%d', + '%h': '%b', + '%r': '%I:%M:%S %p', + '%R': '%H:%M', + '%T': '%H:%M:%S', + '%x': '%m/%d/%y', + '%X': '%H:%M:%S', + '%Ec': '%c', + '%EC': '%C', + '%Ex': '%m/%d/%y', + '%EX': '%H:%M:%S', + '%Ey': '%y', + '%EY': '%Y', + '%Od': '%d', + '%Oe': '%e', + '%OH': '%H', + '%OI': '%I', + '%Om': '%m', + '%OM': '%M', + '%OS': '%S', + '%Ou': '%u', + '%OU': '%U', + '%OV': '%V', + '%Ow': '%w', + '%OW': '%W', + '%Oy': '%y', + }; + for (var rule in EXPANSION_RULES_1) { + pattern = pattern.replace( + new RegExp(rule, 'g'), + EXPANSION_RULES_1[rule] + ); + } + var WEEKDAYS = [ + 'Sunday', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + ]; + var MONTHS = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', + ]; + function leadingSomething(value, digits, character) { + var str = + typeof value == 'number' ? value.toString() : value || ''; + while (str.length < digits) { + str = character[0] + str; + } + return str; + } + function leadingNulls(value, digits) { + return leadingSomething(value, digits, '0'); + } + function compareByDay(date1, date2) { + function sgn(value) { + return value < 0 ? -1 : value > 0 ? 1 : 0; + } + var compare; + if ( + (compare = sgn( + date1.getFullYear() - date2.getFullYear() + )) === 0 + ) { + if ( + (compare = sgn(date1.getMonth() - date2.getMonth())) === + 0 + ) { + compare = sgn(date1.getDate() - date2.getDate()); + } + } + return compare; + } + function getFirstWeekStartDate(janFourth) { + switch (janFourth.getDay()) { + case 0: + return new Date(janFourth.getFullYear() - 1, 11, 29); + case 1: + return janFourth; + case 2: + return new Date(janFourth.getFullYear(), 0, 3); + case 3: + return new Date(janFourth.getFullYear(), 0, 2); + case 4: + return new Date(janFourth.getFullYear(), 0, 1); + case 5: + return new Date(janFourth.getFullYear() - 1, 11, 31); + case 6: + return new Date(janFourth.getFullYear() - 1, 11, 30); + } + } + function getWeekBasedYear(date) { + var thisDate = addDays( + new Date(date.tm_year + 1900, 0, 1), + date.tm_yday + ); + var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4); + var janFourthNextYear = new Date( + thisDate.getFullYear() + 1, + 0, + 4 + ); + var firstWeekStartThisYear = + getFirstWeekStartDate(janFourthThisYear); + var firstWeekStartNextYear = + getFirstWeekStartDate(janFourthNextYear); + if (compareByDay(firstWeekStartThisYear, thisDate) <= 0) { + if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) { + return thisDate.getFullYear() + 1; + } + return thisDate.getFullYear(); + } + return thisDate.getFullYear() - 1; + } + var EXPANSION_RULES_2 = { + '%a': (date) => WEEKDAYS[date.tm_wday].substring(0, 3), + '%A': (date) => WEEKDAYS[date.tm_wday], + '%b': (date) => MONTHS[date.tm_mon].substring(0, 3), + '%B': (date) => MONTHS[date.tm_mon], + '%C': (date) => { + var year = date.tm_year + 1900; + return leadingNulls((year / 100) | 0, 2); + }, + '%d': (date) => leadingNulls(date.tm_mday, 2), + '%e': (date) => leadingSomething(date.tm_mday, 2, ' '), + '%g': (date) => getWeekBasedYear(date).toString().substring(2), + '%G': (date) => getWeekBasedYear(date), + '%H': (date) => leadingNulls(date.tm_hour, 2), + '%I': (date) => { + var twelveHour = date.tm_hour; + if (twelveHour == 0) twelveHour = 12; + else if (twelveHour > 12) twelveHour -= 12; + return leadingNulls(twelveHour, 2); + }, + '%j': (date) => + leadingNulls( + date.tm_mday + + arraySum( + isLeapYear(date.tm_year + 1900) + ? MONTH_DAYS_LEAP + : MONTH_DAYS_REGULAR, + date.tm_mon - 1 + ), + 3 + ), + '%m': (date) => leadingNulls(date.tm_mon + 1, 2), + '%M': (date) => leadingNulls(date.tm_min, 2), + '%n': () => '\n', + '%p': (date) => { + if (date.tm_hour >= 0 && date.tm_hour < 12) { + return 'AM'; + } + return 'PM'; + }, + '%S': (date) => leadingNulls(date.tm_sec, 2), + '%t': () => '\t', + '%u': (date) => date.tm_wday || 7, + '%U': (date) => { + var days = date.tm_yday + 7 - date.tm_wday; + return leadingNulls(Math.floor(days / 7), 2); + }, + '%V': (date) => { + var val = Math.floor( + (date.tm_yday + 7 - ((date.tm_wday + 6) % 7)) / 7 + ); + if ((date.tm_wday + 371 - date.tm_yday - 2) % 7 <= 2) { + val++; + } + if (!val) { + val = 52; + var dec31 = (date.tm_wday + 7 - date.tm_yday - 1) % 7; + if ( + dec31 == 4 || + (dec31 == 5 && isLeapYear((date.tm_year % 400) - 1)) + ) { + val++; + } + } else if (val == 53) { + var jan1 = (date.tm_wday + 371 - date.tm_yday) % 7; + if ( + jan1 != 4 && + (jan1 != 3 || !isLeapYear(date.tm_year)) + ) + val = 1; + } + return leadingNulls(val, 2); + }, + '%w': (date) => date.tm_wday, + '%W': (date) => { + var days = date.tm_yday + 7 - ((date.tm_wday + 6) % 7); + return leadingNulls(Math.floor(days / 7), 2); + }, + '%y': (date) => (date.tm_year + 1900).toString().substring(2), + '%Y': (date) => date.tm_year + 1900, + '%z': (date) => { + var off = date.tm_gmtoff; + var ahead = off >= 0; + off = Math.abs(off) / 60; + off = (off / 60) * 100 + (off % 60); + return (ahead ? '+' : '-') + String('0000' + off).slice(-4); + }, + '%Z': (date) => date.tm_zone, + '%%': () => '%', + }; + pattern = pattern.replace(/%%/g, '\0\0'); + for (var rule in EXPANSION_RULES_2) { + if (pattern.includes(rule)) { + pattern = pattern.replace( + new RegExp(rule, 'g'), + EXPANSION_RULES_2[rule](date) + ); + } + } + pattern = pattern.replace(/\0\0/g, '%'); + var bytes = intArrayFromString(pattern, false); + if (bytes.length > maxsize) { + return 0; + } + writeArrayToMemory(bytes, s); + return bytes.length - 1; + }; + var _strftime_l = (s, maxsize, format, tm, loc) => + _strftime(s, maxsize, format, tm); + var FSNode = function (parent, name, mode, rdev) { + if (!parent) { + parent = this; + } + this.parent = parent; + this.mount = parent.mount; + this.mounted = null; + this.id = FS.nextInode++; + this.name = name; + this.mode = mode; + this.node_ops = {}; + this.stream_ops = {}; + this.rdev = rdev; + }; + var readMode = 292 | 73; + var writeMode = 146; + Object.defineProperties(FSNode.prototype, { + read: { + get: function () { + return (this.mode & readMode) === readMode; + }, + set: function (val) { + val ? (this.mode |= readMode) : (this.mode &= ~readMode); + }, + }, + write: { + get: function () { + return (this.mode & writeMode) === writeMode; + }, + set: function (val) { + val ? (this.mode |= writeMode) : (this.mode &= ~writeMode); + }, + }, + isFolder: { + get: function () { + return FS.isDir(this.mode); + }, + }, + isDevice: { + get: function () { + return FS.isChrdev(this.mode); + }, + }, + }); + FS.FSNode = FSNode; + FS.createPreloadedFile = FS_createPreloadedFile; + FS.staticInit(); + Module['FS_createPath'] = FS.createPath; + Module['FS_createDataFile'] = FS.createDataFile; + Module['FS_createPreloadedFile'] = FS.createPreloadedFile; + Module['FS_unlink'] = FS.unlink; + Module['FS_createLazyFile'] = FS.createLazyFile; + Module['FS_createDevice'] = FS.createDevice; + if (ENVIRONMENT_IS_NODE) { + NODEFS.staticInit(); + } + ERRNO_CODES = { + EPERM: 63, + ENOENT: 44, + ESRCH: 71, + EINTR: 27, + EIO: 29, + ENXIO: 60, + E2BIG: 1, + ENOEXEC: 45, + EBADF: 8, + ECHILD: 12, + EAGAIN: 6, + EWOULDBLOCK: 6, + ENOMEM: 48, + EACCES: 2, + EFAULT: 21, + ENOTBLK: 105, + EBUSY: 10, + EEXIST: 20, + EXDEV: 75, + ENODEV: 43, + ENOTDIR: 54, + EISDIR: 31, + EINVAL: 28, + ENFILE: 41, + EMFILE: 33, + ENOTTY: 59, + ETXTBSY: 74, + EFBIG: 22, + ENOSPC: 51, + ESPIPE: 70, + EROFS: 69, + EMLINK: 34, + EPIPE: 64, + EDOM: 18, + ERANGE: 68, + ENOMSG: 49, + EIDRM: 24, + ECHRNG: 106, + EL2NSYNC: 156, + EL3HLT: 107, + EL3RST: 108, + ELNRNG: 109, + EUNATCH: 110, + ENOCSI: 111, + EL2HLT: 112, + EDEADLK: 16, + ENOLCK: 46, + EBADE: 113, + EBADR: 114, + EXFULL: 115, + ENOANO: 104, + EBADRQC: 103, + EBADSLT: 102, + EDEADLOCK: 16, + EBFONT: 101, + ENOSTR: 100, + ENODATA: 116, + ETIME: 117, + ENOSR: 118, + ENONET: 119, + ENOPKG: 120, + EREMOTE: 121, + ENOLINK: 47, + EADV: 122, + ESRMNT: 123, + ECOMM: 124, + EPROTO: 65, + EMULTIHOP: 36, + EDOTDOT: 125, + EBADMSG: 9, + ENOTUNIQ: 126, + EBADFD: 127, + EREMCHG: 128, + ELIBACC: 129, + ELIBBAD: 130, + ELIBSCN: 131, + ELIBMAX: 132, + ELIBEXEC: 133, + ENOSYS: 52, + ENOTEMPTY: 55, + ENAMETOOLONG: 37, + ELOOP: 32, + EOPNOTSUPP: 138, + EPFNOSUPPORT: 139, + ECONNRESET: 15, + ENOBUFS: 42, + EAFNOSUPPORT: 5, + EPROTOTYPE: 67, + ENOTSOCK: 57, + ENOPROTOOPT: 50, + ESHUTDOWN: 140, + ECONNREFUSED: 14, + EADDRINUSE: 3, + ECONNABORTED: 13, + ENETUNREACH: 40, + ENETDOWN: 38, + ETIMEDOUT: 73, + EHOSTDOWN: 142, + EHOSTUNREACH: 23, + EINPROGRESS: 26, + EALREADY: 7, + EDESTADDRREQ: 17, + EMSGSIZE: 35, + EPROTONOSUPPORT: 66, + ESOCKTNOSUPPORT: 137, + EADDRNOTAVAIL: 4, + ENETRESET: 39, + EISCONN: 30, + ENOTCONN: 53, + ETOOMANYREFS: 141, + EUSERS: 136, + EDQUOT: 19, + ESTALE: 72, + ENOTSUP: 138, + ENOMEDIUM: 148, + EILSEQ: 25, + EOVERFLOW: 61, + ECANCELED: 11, + ENOTRECOVERABLE: 56, + EOWNERDEAD: 62, + ESTRPIPE: 135, + }; + InternalError = Module['InternalError'] = class InternalError extends ( + Error + ) { + constructor(message) { + super(message); + this.name = 'InternalError'; + } + }; + embind_init_charCodes(); + BindingError = Module['BindingError'] = class BindingError extends ( + Error + ) { + constructor(message) { + super(message); + this.name = 'BindingError'; + } + }; + init_ClassHandle(); + init_embind(); + init_RegisteredPointer(); + UnboundTypeError = Module['UnboundTypeError'] = extendError( + Error, + 'UnboundTypeError' + ); + handleAllocatorInit(); + init_emval(); + function checkIncomingModuleAPI() { + ignoredModuleProp('fetchSettings'); + } + var wasmImports = { + __assert_fail: ___assert_fail, + __handle_stack_overflow: ___handle_stack_overflow, + __syscall_fcntl64: ___syscall_fcntl64, + __syscall_fstat64: ___syscall_fstat64, + __syscall_ioctl: ___syscall_ioctl, + __syscall_lstat64: ___syscall_lstat64, + __syscall_newfstatat: ___syscall_newfstatat, + __syscall_openat: ___syscall_openat, + __syscall_stat64: ___syscall_stat64, + __throw_exception_with_stack_trace: + ___throw_exception_with_stack_trace, + _embind_finalize_value_object: __embind_finalize_value_object, + _embind_register_bigint: __embind_register_bigint, + _embind_register_bool: __embind_register_bool, + _embind_register_class: __embind_register_class, + _embind_register_class_constructor: + __embind_register_class_constructor, + _embind_register_class_function: __embind_register_class_function, + _embind_register_emval: __embind_register_emval, + _embind_register_float: __embind_register_float, + _embind_register_function: __embind_register_function, + _embind_register_integer: __embind_register_integer, + _embind_register_memory_view: __embind_register_memory_view, + _embind_register_std_string: __embind_register_std_string, + _embind_register_std_wstring: __embind_register_std_wstring, + _embind_register_value_object: __embind_register_value_object, + _embind_register_value_object_field: + __embind_register_value_object_field, + _embind_register_void: __embind_register_void, + _emval_decref: __emval_decref, + _emval_incref: __emval_incref, + _emval_take_value: __emval_take_value, + _mmap_js: __mmap_js, + _munmap_js: __munmap_js, + abort: _abort, + emscripten_memcpy_big: _emscripten_memcpy_big, + emscripten_resize_heap: _emscripten_resize_heap, + environ_get: _environ_get, + environ_sizes_get: _environ_sizes_get, + fd_close: _fd_close, + fd_read: _fd_read, + fd_seek: _fd_seek, + fd_write: _fd_write, + strftime_l: _strftime_l, + }; + var asm = createWasm(); + var ___wasm_call_ctors = createExportWrapper('__wasm_call_ctors'); + var _malloc = createExportWrapper('malloc'); + var _fflush = (Module['_fflush'] = createExportWrapper('fflush')); + var _free = (Module['_free'] = createExportWrapper('free')); + var ___errno_location = createExportWrapper('__errno_location'); + var ___getTypeName = createExportWrapper('__getTypeName'); + var __embind_initialize_bindings = (Module[ + '__embind_initialize_bindings' + ] = createExportWrapper('_embind_initialize_bindings')); + var ___funcs_on_exit = createExportWrapper('__funcs_on_exit'); + var _emscripten_builtin_memalign = createExportWrapper( + 'emscripten_builtin_memalign' + ); + var ___trap = function () { + return (___trap = Module['asm']['__trap']).apply(null, arguments); + }; + var setTempRet0 = createExportWrapper('setTempRet0'); + var _emscripten_stack_init = function () { + return (_emscripten_stack_init = + Module['asm']['emscripten_stack_init']).apply(null, arguments); + }; + var _emscripten_stack_get_free = function () { + return (_emscripten_stack_get_free = + Module['asm']['emscripten_stack_get_free']).apply( + null, + arguments + ); + }; + var _emscripten_stack_get_base = function () { + return (_emscripten_stack_get_base = + Module['asm']['emscripten_stack_get_base']).apply( + null, + arguments + ); + }; + var _emscripten_stack_get_end = function () { + return (_emscripten_stack_get_end = + Module['asm']['emscripten_stack_get_end']).apply( + null, + arguments + ); + }; + var stackSave = createExportWrapper('stackSave'); + var stackRestore = createExportWrapper('stackRestore'); + var stackAlloc = createExportWrapper('stackAlloc'); + var _emscripten_stack_get_current = function () { + return (_emscripten_stack_get_current = + Module['asm']['emscripten_stack_get_current']).apply( + null, + arguments + ); + }; + var ___cxa_decrement_exception_refcount = (Module[ + '___cxa_decrement_exception_refcount' + ] = createExportWrapper('__cxa_decrement_exception_refcount')); + var ___cxa_increment_exception_refcount = (Module[ + '___cxa_increment_exception_refcount' + ] = createExportWrapper('__cxa_increment_exception_refcount')); + var ___thrown_object_from_unwind_exception = (Module[ + '___thrown_object_from_unwind_exception' + ] = createExportWrapper('__thrown_object_from_unwind_exception')); + var ___get_exception_message = (Module['___get_exception_message'] = + createExportWrapper('__get_exception_message')); + var ___set_stack_limits = (Module['___set_stack_limits'] = + createExportWrapper('__set_stack_limits')); + var dynCall_jiji = (Module['dynCall_jiji'] = + createExportWrapper('dynCall_jiji')); + var dynCall_viijii = (Module['dynCall_viijii'] = + createExportWrapper('dynCall_viijii')); + var dynCall_iiiiij = (Module['dynCall_iiiiij'] = + createExportWrapper('dynCall_iiiiij')); + var dynCall_iiiiijj = (Module['dynCall_iiiiijj'] = + createExportWrapper('dynCall_iiiiijj')); + var dynCall_iiiiiijj = (Module['dynCall_iiiiiijj'] = + createExportWrapper('dynCall_iiiiiijj')); + function intArrayFromBase64(s) { + if ( + typeof ENVIRONMENT_IS_NODE != 'undefined' && + ENVIRONMENT_IS_NODE + ) { + var buf = Buffer.from(s, 'base64'); + return new Uint8Array( + buf['buffer'], + buf['byteOffset'], + buf['byteLength'] + ); + } + try { + var decoded = atob(s); + var bytes = new Uint8Array(decoded.length); + for (var i = 0; i < decoded.length; ++i) { + bytes[i] = decoded.charCodeAt(i); + } + return bytes; + } catch (_) { + throw new Error('Converting base64 string to bytes failed.'); + } + } + Module['addRunDependency'] = addRunDependency; + Module['removeRunDependency'] = removeRunDependency; + Module['FS_createPath'] = FS.createPath; + Module['FS_createDataFile'] = FS.createDataFile; + Module['FS_createLazyFile'] = FS.createLazyFile; + Module['FS_createDevice'] = FS.createDevice; + Module['FS_unlink'] = FS.unlink; + Module['FS_createPreloadedFile'] = FS.createPreloadedFile; + Module['FS'] = FS; + var missingLibrarySymbols = [ + 'writeI53ToI64', + 'writeI53ToI64Clamped', + 'writeI53ToI64Signaling', + 'writeI53ToU64Clamped', + 'writeI53ToU64Signaling', + 'readI53FromI64', + 'readI53FromU64', + 'convertI32PairToI53', + 'convertU32PairToI53', + 'exitJS', + 'ydayFromDate', + 'inetPton4', + 'inetNtop4', + 'inetPton6', + 'inetNtop6', + 'readSockaddr', + 'writeSockaddr', + 'getHostByName', + 'traverseStack', + 'getCallstack', + 'emscriptenLog', + 'convertPCtoSourceLocation', + 'readEmAsmArgs', + 'jstoi_q', + 'jstoi_s', + 'listenOnce', + 'autoResumeAudioContext', + 'handleException', + 'runtimeKeepalivePush', + 'runtimeKeepalivePop', + 'callUserCallback', + 'maybeExit', + 'safeSetTimeout', + 'asmjsMangle', + 'getNativeTypeSize', + 'STACK_SIZE', + 'STACK_ALIGN', + 'POINTER_SIZE', + 'ASSERTIONS', + 'getCFunc', + 'ccall', + 'cwrap', + 'uleb128Encode', + 'sigToWasmTypes', + 'generateFuncType', + 'convertJsFunctionToWasm', + 'getEmptyTableSlot', + 'updateTableMap', + 'getFunctionAddress', + 'addFunction', + 'removeFunction', + 'reallyNegative', + 'unSign', + 'strLen', + 'reSign', + 'formatString', + 'intArrayToString', + 'AsciiToString', + 'stringToNewUTF8', + 'stringToUTF8OnStack', + 'registerKeyEventCallback', + 'maybeCStringToJsString', + 'findEventTarget', + 'findCanvasEventTarget', + 'getBoundingClientRect', + 'fillMouseEventData', + 'registerMouseEventCallback', + 'registerWheelEventCallback', + 'registerUiEventCallback', + 'registerFocusEventCallback', + 'fillDeviceOrientationEventData', + 'registerDeviceOrientationEventCallback', + 'fillDeviceMotionEventData', + 'registerDeviceMotionEventCallback', + 'screenOrientation', + 'fillOrientationChangeEventData', + 'registerOrientationChangeEventCallback', + 'fillFullscreenChangeEventData', + 'registerFullscreenChangeEventCallback', + 'JSEvents_requestFullscreen', + 'JSEvents_resizeCanvasForFullscreen', + 'registerRestoreOldStyle', + 'hideEverythingExceptGivenElement', + 'restoreHiddenElements', + 'setLetterbox', + 'softFullscreenResizeWebGLRenderTarget', + 'doRequestFullscreen', + 'fillPointerlockChangeEventData', + 'registerPointerlockChangeEventCallback', + 'registerPointerlockErrorEventCallback', + 'requestPointerLock', + 'fillVisibilityChangeEventData', + 'registerVisibilityChangeEventCallback', + 'registerTouchEventCallback', + 'fillGamepadEventData', + 'registerGamepadEventCallback', + 'registerBeforeUnloadEventCallback', + 'fillBatteryEventData', + 'battery', + 'registerBatteryEventCallback', + 'setCanvasElementSize', + 'getCanvasElementSize', + 'jsStackTrace', + 'stackTrace', + 'checkWasiClock', + 'wasiRightsToMuslOFlags', + 'wasiOFlagsToMuslOFlags', + 'createDyncallWrapper', + 'setImmediateWrapped', + 'clearImmediateWrapped', + 'polyfillSetImmediate', + 'getPromise', + 'makePromise', + 'idsToPromises', + 'makePromiseCallback', + 'setMainLoop', + 'getSocketFromFD', + 'getSocketAddress', + '_setNetworkCallback', + 'heapObjectForWebGLType', + 'heapAccessShiftForWebGLHeap', + 'webgl_enable_ANGLE_instanced_arrays', + 'webgl_enable_OES_vertex_array_object', + 'webgl_enable_WEBGL_draw_buffers', + 'webgl_enable_WEBGL_multi_draw', + 'emscriptenWebGLGet', + 'computeUnpackAlignedImageSize', + 'colorChannelsInGlTextureFormat', + 'emscriptenWebGLGetTexPixelData', + '__glGenObject', + 'emscriptenWebGLGetUniform', + 'webglGetUniformLocation', + 'webglPrepareUniformLocationsBeforeFirstUse', + 'webglGetLeftBracePos', + 'emscriptenWebGLGetVertexAttrib', + '__glGetActiveAttribOrUniform', + 'writeGLArray', + 'registerWebGlEventCallback', + 'runAndAbortIfError', + 'SDL_unicode', + 'SDL_ttfContext', + 'SDL_audio', + 'GLFW_Window', + 'ALLOC_NORMAL', + 'ALLOC_STACK', + 'allocate', + 'writeStringToMemory', + 'writeAsciiToMemory', + 'registerInheritedInstance', + 'unregisterInheritedInstance', + 'enumReadValueFromPointer', + 'validateThis', + 'getStringOrSymbol', + 'craftEmvalAllocator', + 'emval_get_global', + 'emval_lookupTypes', + 'emval_allocateDestructors', + 'emval_addMethodCaller', + ]; + missingLibrarySymbols.forEach(missingLibrarySymbol); + var unexportedSymbols = [ + 'run', + 'addOnPreRun', + 'addOnInit', + 'addOnPreMain', + 'addOnExit', + 'addOnPostRun', + 'FS_createFolder', + 'FS_createLink', + 'out', + 'err', + 'callMain', + 'abort', + 'keepRuntimeAlive', + 'wasmMemory', + 'stackAlloc', + 'stackSave', + 'stackRestore', + 'getTempRet0', + 'setTempRet0', + 'writeStackCookie', + 'checkStackCookie', + 'convertI32PairToI53Checked', + 'ptrToString', + 'zeroMemory', + 'getHeapMax', + 'growMemory', + 'ENV', + 'setStackLimits', + 'MONTH_DAYS_REGULAR', + 'MONTH_DAYS_LEAP', + 'MONTH_DAYS_REGULAR_CUMULATIVE', + 'MONTH_DAYS_LEAP_CUMULATIVE', + 'isLeapYear', + 'arraySum', + 'addDays', + 'ERRNO_CODES', + 'ERRNO_MESSAGES', + 'setErrNo', + 'DNS', + 'Protocols', + 'Sockets', + 'initRandomFill', + 'randomFill', + 'timers', + 'warnOnce', + 'UNWIND_CACHE', + 'readEmAsmArgsArray', + 'getExecutableName', + 'dynCallLegacy', + 'getDynCaller', + 'dynCall', + 'asyncLoad', + 'alignMemory', + 'mmapAlloc', + 'handleAllocatorInit', + 'HandleAllocator', + 'freeTableIndexes', + 'functionsInTableMap', + 'setValue', + 'getValue', + 'PATH', + 'PATH_FS', + 'UTF8Decoder', + 'UTF8ArrayToString', + 'UTF8ToString', + 'stringToUTF8Array', + 'stringToUTF8', + 'lengthBytesUTF8', + 'intArrayFromString', + 'stringToAscii', + 'UTF16Decoder', + 'UTF16ToString', + 'stringToUTF16', + 'lengthBytesUTF16', + 'UTF32ToString', + 'stringToUTF32', + 'lengthBytesUTF32', + 'writeArrayToMemory', + 'JSEvents', + 'specialHTMLTargets', + 'currentFullscreenStrategy', + 'restoreOldWindowedStyle', + 'demangle', + 'demangleAll', + 'ExitStatus', + 'getEnvStrings', + 'doReadv', + 'doWritev', + 'promiseMap', + 'getExceptionMessageCommon', + 'getCppExceptionTag', + 'getCppExceptionThrownObjectFromWebAssemblyException', + 'incrementExceptionRefcount', + 'decrementExceptionRefcount', + 'getExceptionMessage', + 'Browser', + 'wget', + 'SYSCALLS', + 'preloadPlugins', + 'FS_modeStringToFlags', + 'FS_getMode', + 'FS_stdin_getChar_buffer', + 'FS_stdin_getChar', + 'MEMFS', + 'TTY', + 'PIPEFS', + 'SOCKFS', + 'tempFixedLengthArray', + 'miniTempWebGLFloatBuffers', + 'miniTempWebGLIntBuffers', + 'GL', + 'emscripten_webgl_power_preferences', + 'AL', + 'GLUT', + 'EGL', + 'GLEW', + 'IDBStore', + 'SDL', + 'SDL_gfx', + 'GLFW', + 'allocateUTF8', + 'allocateUTF8OnStack', + 'InternalError', + 'BindingError', + 'throwInternalError', + 'throwBindingError', + 'registeredTypes', + 'awaitingDependencies', + 'typeDependencies', + 'tupleRegistrations', + 'structRegistrations', + 'sharedRegisterType', + 'whenDependentTypesAreResolved', + 'embind_charCodes', + 'embind_init_charCodes', + 'readLatin1String', + 'getTypeName', + 'heap32VectorToArray', + 'requireRegisteredType', + 'UnboundTypeError', + 'PureVirtualError', + 'init_embind', + 'throwUnboundTypeError', + 'ensureOverloadTable', + 'exposePublicSymbol', + 'replacePublicSymbol', + 'extendError', + 'createNamedFunction', + 'embindRepr', + 'registeredInstances', + 'getBasestPointer', + 'getInheritedInstance', + 'getInheritedInstanceCount', + 'getLiveInheritedInstances', + 'registeredPointers', + 'registerType', + 'getShiftFromSize', + 'integerReadValueFromPointer', + 'floatReadValueFromPointer', + 'simpleReadValueFromPointer', + 'runDestructors', + 'newFunc', + 'craftInvokerFunction', + 'embind__requireFunction', + 'genericPointerToWireType', + 'constNoSmartPtrRawPointerToWireType', + 'nonConstNoSmartPtrRawPointerToWireType', + 'init_RegisteredPointer', + 'RegisteredPointer', + 'RegisteredPointer_getPointee', + 'RegisteredPointer_destructor', + 'RegisteredPointer_deleteObject', + 'RegisteredPointer_fromWireType', + 'runDestructor', + 'releaseClassHandle', + 'finalizationRegistry', + 'detachFinalizer_deps', + 'detachFinalizer', + 'attachFinalizer', + 'makeClassHandle', + 'init_ClassHandle', + 'ClassHandle', + 'ClassHandle_isAliasOf', + 'throwInstanceAlreadyDeleted', + 'ClassHandle_clone', + 'ClassHandle_delete', + 'deletionQueue', + 'ClassHandle_isDeleted', + 'ClassHandle_deleteLater', + 'flushPendingDeletes', + 'delayFunction', + 'setDelayFunction', + 'RegisteredClass', + 'shallowCopyInternalPointer', + 'downcastPointer', + 'upcastPointer', + 'char_0', + 'char_9', + 'makeLegalFunctionName', + 'emval_handles', + 'emval_symbols', + 'init_emval', + 'count_emval_handles', + 'Emval', + 'emval_newers', + 'emval_methodCallers', + 'emval_registeredMethods', + 'NODEFS', + ]; + unexportedSymbols.forEach(unexportedRuntimeSymbol); + var calledRun; + dependenciesFulfilled = function runCaller() { + if (!calledRun) run(); + if (!calledRun) dependenciesFulfilled = runCaller; + }; + function stackCheckInit() { + _emscripten_stack_init(); + writeStackCookie(); + } + function run() { + if (runDependencies > 0) { + return; + } + stackCheckInit(); + preRun(); + if (runDependencies > 0) { + return; + } + function doRun() { + if (calledRun) return; + calledRun = true; + Module['calledRun'] = true; + if (ABORT) return; + initRuntime(); + readyPromiseResolve(Module); + if (Module['onRuntimeInitialized']) + Module['onRuntimeInitialized'](); + assert( + !Module['_main'], + 'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]' + ); + postRun(); + } + if (Module['setStatus']) { + Module['setStatus']('Running...'); + setTimeout(function () { + setTimeout(function () { + Module['setStatus'](''); + }, 1); + doRun(); + }, 1); + } else { + doRun(); + } + checkStackCookie(); + } + if (Module['preInit']) { + if (typeof Module['preInit'] == 'function') + Module['preInit'] = [Module['preInit']]; + while (Module['preInit'].length > 0) { + Module['preInit'].pop()(); + } + } + run(); -); + return moduleArg.ready; + }; })(); -export default privateer_module; \ No newline at end of file +export default privateer_module; diff --git a/webapp/src/wasm/privateer.wasm b/webapp/src/wasm/privateer.wasm index 76474897602ad5c559932940cabc4d79ef129276..1f733e473d8923c3454c0435ae08cb2c4f074536 100755 GIT binary patch literal 1978727 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 k>S_IMnNy^`4; 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 z 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%0A?fTvGthNvL@I2fWp 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 z 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

ES$U!@w7#Ac!cGpwxvH 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¨sayzTR}zJ=0~c;y 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 h5;!qF=t4{g=nCxc=np4!Gdz+iLfFaK@5k z!NFUfd+Ux*J@nkfrpnv4YJFm_^IHyGdBK>k8}{F?{^H1#KmV}yjL;FAJaBGb-H%Ur z2VX6z`s0D|Jv{dN$3=elxpkXUzdz=pdG~&HdhPnhC*S?&Yg@~Q{}R8WeCXgk&w6v7 ztMvHR2WDSVv&Zt&cE0JJ9g<^y`1G2aFMQ(o&vsu@u;Sy_AAex@>g^ZSM|T`reB7BA zpZ3_F{)PBZ_pZ1UT89RBRQ z8>Wt5Z9jSIV@|p0&ULpuv-#)e9=XMgpKsazn%iFg;L6>OdTf8K>#3(!y>;I6Z=b&Q z)GNDI)$OObFMjd(wUhexExzZ`wSAGLGf!PFj`g$E9wd-5^AIjb)G*w`cbmLB%i%P$>z>ov=#J$J=H=^`#rtqtCPNX^^9p>%zf(i1;g9c96oQ{9WRcneR%PwhfVs+jypbaN&n*=Th2aV zaZC3leV4rP`XNt@|LKr53rf$pdXp{2Z?S#Lf}aBiFYuI4`|i27uXumY6I;H&@W#HK zW{r9Hpoh-e`l5lGKDzUfoyT9i!hQRB<@Z1T$O*el>iV{Q_G7`0__pV+GyZwO>9_27&_2oO^Y>ZT z`}n_BoL#qK&1c2uZg!O^p{7PR|V~}*44bfuCQZL`JBIgds)RZ z3vc*+{Z?n3dtb%dXD-?K=p&B&`rLDN{QX@s`j2QksP&z~_xBvU|IcsC{l}VP-!Faj zAD?x~#KoU4c=XxzGvfEnAG^in_uh7OWYN%pn}5314}D+!z3Hh>-ae!7 zk!{-=KYVW0dta|uzn}BOeP6lf+Lvqxbga9;^-yuuvYT#QbIn;z!zZrldf5Hd693BA zS1xb;apgb>{WqJe_+`NjpR8*7%TePZSN-_Y@=cZ>`qe9) zwu{@Zdc5n|gMOOyVEnDr)BD|fS?$$tE?eIBr*GOWe8OM1^poG77}+6q*|-k|*B^P` zE8#hvdk=iL&+wDS?{-@6;U9jDJ-wrDuMll_s;u6S_8 zP180TtSEc;i68e{wd9&pzI<@Sabvgf{`lH`)9$)%`xkEe;!CfsVf)q}PW$ZPe;sez zY?~d=owZAoZTmNN9=d(~XG`l}*!Qms;wzWVf4=?M_pY0=<2e&tpSuozbcX|u{o$zJ zU3cK`E;?%2nJb%WZ}^~m!SmbB{o}LsSFOE!{Kc!=_FF!9>`T{Obkw|O&-rNfV>1RS zFMDRMv8#7)S+e|>Q`fvPx&G3z@q@HTYWd++pF z7w#Ip`*D5xS5uB@KkD?8R(y7N>Y&^H+;ZYAs=UQ>&F-P|Vi$g7-|fLKzdP)a zH=jRa-8MY*Tamrf)oV;>>%OzqxRr(trH+TioD#zTxKPYbTwx_=K^4 z{Or{eUzt1p{5K}Oc>T1;cD!uO^H+U)^o#E=oAA=*f%os-^~B#yc<$?~1G`OpGO*^N zg?l9ij#z#4;Pbn6^=SHo{>9T~Jo4;Y&p&!ZdaYag@|AT($e&A$`!N9RvlAc;{7Rp#jbrj%sTm$lIe@LU$C4HQ_+kg-~QtBnS~D=^LE*pE#DmcY_!byVl*Oz4F_eAOB(6=RJQry8h0(D?ghV+IvCm_Y)RvdTY_V z54PQV$~Ko?e%qF>fAF_=w%X~NldnzP{qd3iSnof5W%{+#*M52HoUM8iT@ycTyYral zXYc&OKi3vV9-RI_Pj^|mHMKk)I{Snleqa6fKh(MZwC3YrNAvEhZv6h7ao=5d+B5Gj zzr6jBNxj#-R`u6echrC5dnNbE!rjL&3T^Y%VF%xK;k6wJ$Bfde z`^R3=n!4ot*ikR8`uXSI9Tb`H=#fK5`^NnA`=g+H{891X*j4`se{`1n$8)aSbm|?u zS8mf#yzE*>oZ9o5;hZ;Vp{r!=jAO1tZKVC~Wopat-uSS16uk+eV z@BU=%vrq3g{efGbxnt|kW}LP9sy)x$e6#OPwD0!F`)7Q#=AK`|1BW)&FZtr9=g!~i zr!QhJT;#ms^G}ce`1YS4Jv?%7|J{%O{r-~|eN=LJ$Il1FyLX<@v+BE>(vMtv;8Q=< z+NMw3`-<2OD}v+py<*FY?;CsPi9PRc_5IEdwomxinowhZ!=7I}_~z-~zVol|SAYKC zrLX-z_WnGsrtga%$M?Mrw`9mXMr0a&b_x@ulMWo`2GI*em{?g&Fb#qdDdEc?X}n0=iIZ;UDW^Jly)Nr z+#elP?a}1^P7NaSeajgKHFsZh%%X4E_pA0D`7*cP62H`~jovhF()ac3m=TlSRy=6i zrpx{C%xZrnxyGi&y~@gVbE;D2aM|opUfwPrR}3v*{n_o9$efC1>E8~U@18pNlJ(o5 z+JlxiDPxv7sodpa$^Hd9;u81oKisEw*%hnjm3Th*ct)AZ7EgzddcEpP!DG{9>sFnP zfBSjq37=2ZzuPQ5zc1j|fyj{)_w1duXKVhlW+^e*M~BREx|;Ri{=lnW_RUJjF8SqH ziN>22kKEqQZpOPyBcoUBYf}1P*Tgd(=dMSMIuYbBb?}UgA<=gZ#?4e6KRZ5WN!MAU z3_QITPH;{fa=TjR(v}0)o;~xW-S#VM?{qAY9hEV?#r)~hk`~=KndZ9G)U2TEg~9K; zT`+AGc(`rPz6~cly!<=)b@kuj_FL))`@TtXU6t0U-uA5>XM|t2e)+qBcdd>S7bZ6d z9(u9bJWqF<{#^!3GN-|&5R zw59!*j0#-~_E&UrX%cHwAyV;jwWDk3@oSg6xwTz-W$ll7LsD-&9^W)5ZBTabxRdi| zY?}S9dw^(Iak*t_oGPb(VUn{m*gbw%4FV=fz~?8uB> z7}oDuc>^=k5yk8-9(cJut=IRzmRVYq={nzO`-UODy*}pVTkiW7ADLMzYGvn?ISt0u zp8D-eRQ5idxTKpIQ(c z(Qo~sd$02xLtDjr=C1Xa{OhYSDY#tHt4hiX_e;-(-s2sWH`d*dmg0VEle=ox zW{1@op3d)_nvZ_bZOh6)%jf6kF1T;mr?_qGxUr$h&yqK!JlyJjXk;n3OWiN*ty^Q8 zDsk1-ZQGp6#xnCcO{YyvuYGaQ{Pg<8Lx!@Oq3!#GeYc$ZWz%=-QceBYq6z0mwwV5{ zdeVhM1=rif*f#2MG-%%KgLOCljyt~4Io$xHl?ZK!~8NnoIGS>w|c^p?^`Mxk32m1^r|X1{myMzcqy~g;0p%1 z$p=!*&z(53Fqicz+on@z3%}a0hqd3kBiBOFz~pIA@hPdT!fX2ODmLLj%(u&Hk9Y zk(czbib<;jJKI#ZcF!^&Wm5mi?#D|{`rJEH$J1kRxP_|U(vpd7`p@aI?yuH43Dfhs z?AqP)&Y5@7{R1o=YE_D=SM`3TZ)pA~N2~1ok>yJr&wppMxS(&6F*6KLNX~L7K%NOnl%ul>s>d1(TW_L>d{qk`5OZOuegL0G7Hk9d{8?`03?Us5k z=f>6c-q-ndl!Z;nA;F=0vNv2$Y!_3x#N52lMV-ojd-G;S>EoR|dshtgziN_wY{{J?Pi~DVd9Y#h zo|sc5qj&DSJmT*q#jX#Ttp6Z=vb#h7{_`C_G+AnRY{i1|Kg#%JynFZL)|-x%P92yz z@%6fqgBL{Ja&hY2z53+X{#Wat3QDfqq5I=iJ0AM3a2c=P{BzvUX5BX2?U)ficjnbI zPi$5BpX7w7aW(sNDVwEN4BH@})PLEk;_t|;6La=>%qnxlePD^cl~M=y-ZlO~^suV8bGIg$j;a1Gc}EFVym!s< zbywt!JFj0ha^LxD>AjB(FR}YTtrEXZubMfyqe1&d4NsX4$R6P~>)`A)$stem|6Vg= z@u5(=y@@MA2Y;Me?aX`I%CG(Q-l*QM_1-q`dT(ysWVvUK;$iU6rl%h`jT(98$|P zy{s18tI55o>RWDeuCJIle0A;GJ8}!66FuHN@n zb;t|sRNCZi`}h4*yt2MuP3cx|YiP!$mx~kkzG)5&y^2d=WTgi>4D#;pZ47v z@4Gzj_T_O4!>_#bxB6Lb&{t2pO-q$7+ouQA+1RQ5nwFoxUO(T=KBjEn>@mhA&a;3I z`xpND=@DFMO!WCBUFJMme(>6)^>bSEzA|LfpsDww`%bB2SmsR3yoP$eyS9qxdHT(b zoeLwsn%4RpkdhV9&b|F)hfC#-t?_R;eM01j6{qSgUJ=38j6T5vE0*eDaB%XT#$ONn zvvcp+u&gpm&eZmJGxOdgw-~ck%>VqW3O~Qxcv+?NiXleNj^b><{cv3f|%sabR}W z>Ud&l+|{SKR*h5x%~piIS+Npd8F)9bE@oQ@_6jUL^(f(nNrK`r233yr8$|#{){~^V0ZywhXe`5LHaUCy8>5}v*-DdS?>TTx? zOcXIpeULuWnffe!erM`i_*B}iqYeAWxShm3Wy;k4#MBGU8<^<%M@BJq1m(<+9%Je) zl&e4T4O8!@+&5(eQ=dXk-}a#WVWz%GS<@{ybC^1tvJGDZE@$eG$Qt;6GJn3GsRJ$` zA7i!M^C?rWq`dy|b5%o`dNbuuH#xd#4^!_&-q03HEt3aKokoS6Mfw(J7c=#BDtITH zel;zTsUM@D@}E)hVBOnynEE}H!V<<D!hNoCt-CWl(x zRxR5omE9h=`srUf_u-sWj*YA}&(U_)SUfeylS}meagE{Z6l=9tP6muSnKs2b3PwF4Cmz8eX)W+hJdM)w!9MSEcf@>4t9R_q!aal9qz+ zx{z)LRsR%RV!zw!DUnq4cPLlZ>XqA*SetT~JB-EjzFYBEoo7`-dsKc!Wuy2j1CO=7 zay9wd+Z9xPc79|3L<2p8dS~KkYk}?hj$PkZK5Ktw_rb_#C|@ww|*L zkq&$!6$GjH~EdiU`jvn}m8C98OcQkQCfY&7LgFiRitV|cOP zEgtO6+XE|0#Q6}N6zu8zK<{`xfOQ^5v@*YnCOn>RnU=As!T-{&7c z8!@cb?GH6Kml)Bgvb*KiU2TsjUxkc)c_GYU%7(4^pVk_UI9X?$$+O={86KUlw)&uS zthJ_M-FiJXg!zUyw)4KNxV6JS`t7?~XFtz5bntpR7rP}Hj{+MdzRKVGV4Ls4MUSpe zT~NF^zA;$a^i}YNPrWbtWNf`s;9O%`+K)OT&yF8?yu;$KlXI)ptMGBgTgSGpPH&g= zX?O3+_&cvxCG5ZO^xcxltMbyX+K0O4rc~T~tlH~0?j7s>ICax%lh5m{Zf|_zc5LgO zU+qV2Psc&wBi>HxwEcX}vR2t`-yFC#`H(}SGNB&7p6qiNn7(~T_Zu%N9Ecnrcl7?? zuIC6_gQhdjAv`Fc)=$jCE! zi(|$OJ~(ITrVhQXJTt5QGcGYbq>b-`-50twu=m_jr+t~b-**N5E}wO5{l~HgOTKlE zKl{_N+;Pjrt?j3cvL4=YOyswjZSOWYl%U@$QZ@Hvn)8pZ_ZBXj@#3~&?#y$8CNXDic;i98o?i+YJ7|AhW%t+9 zyiCsYAGF&)$>49RzVmwYy45yx>ifx=F*VQb>A2I&XL$GY@fo96mOYo-ruwDI?T+es zw!7Tbd0O8e7H55JW4gra&&*D}Y}u`1^ptfr^@o&r<-Nviyxljmfv3U)dRV7i-O`@< zmRLE}chcwSL!Qpbb69rX+%xCMh~vXnU#RYSrRm=eW9cJM?Svc+-`sCm$Uc6)?5oxnM9)>0iN?D{%sonWSsnhJ~oK<`OI?y<8dEV>3 zk3GJmt{v3z;p?ZZ{SNpwXgccC>b^Dq4q7tl&3tzK(e#vs<5PF$zW3W%ddFse!+v-2 za+i*)GUScoUPSms^Dbjc=Ireo6!yD?IyftHZn>of##RsBY-`bJe$O4{Z*J)K&Z%2U z~`54cT@;iIHpEoCUu+6eL7kW5PeYdf`{! ztmj5W%Ue!ok`?89{dzoaukRLPyR;>DzSgy?vVB(nS~WaXPQ&~C^u`{6BkUh8DS>VXoNi(Mze^?W1kuosEFV))TvYX2*$5oG5FPvH_ zYx>6QUP(VnpNw)mcDOcn$x?1b*1cF z#U95ORdz3%+vMw&fvJNA4zV+ukQpZz#@%lDd`{T{A?{}_zFV*|UjzGWT1DhP)@utm{fNvfR4@c~c zS@nHDQp1PMHG4NQ~Wqr$4+xL9NkjmHhq%W(p^UmHe{hoTptWMeB^x(+Hop(b$&yRi6 zUf=(gMc(3GeM@vXH1k27+^z=Z7aMO&9I?}M&9*9icEv^;)-U*KdRPBmxPQ-$jj9IK z(w|C#3ED7HMm@M1&2W6L9FeeUrDUGHH92SB`wr8xvVHH@xdTWaaU-3zl!HfBtvo6}`#JX3n0r zOZlSZg}pyJ-8|{wKJngw_(ZSWisNsiw+;C|qHM5Hy9$+OR7=}A^7PeT$&QtFEH?Uk zL)7L8YtDRe>{#!w^}P}oulBLoy3oACnr=bUzC7ub&}wdnE6cXmzmS@>twK`O5q|}4 zFgf}0#)n_;GJ00qxXEF(ultH6E1MFtFpo ze$$KptX1&WtC!n)Uo+faeEXdX3$rE{R9N{TIK!^?`)$UTkLC9AIG%a1>8r&aqhFUU zKCembhV|dxc=mnE=(zM@6_%Ms_o*^{a_q9B3mt~fR*d=9+aYi8?G;P+C2Ws4nK|!V z>k+-{wO#sk+@p%+W`6Q`a%6#bM6!MI8mExZyo=K&jgDA(hwLVn*_%m3qMt;iEyc!PuukU!1)wDzW$+}Y#tL4KD82IhB@?E_x z(+1pFd)fTrCw0=-rFwZ*mm`~}+bJ6qjCbESdAz>g9Cau2l;InvZwR^(n0v;XmAd9K ztnn%1zGsISJ>NWSW~#fR*ZkHki#Pc;fAPbMeb$WIc45{YyNzd$u3dh>#CFQyt--(V z4_vwETYOr}*pgRQ=3g1{+r4G}tFL`N+PjoFmHZ{Z;DJZYnIHRCi0V3S$&BVRCY-z# zm)mdm`>MwVbZ^oxwNj5s#mf#ESMANF*ApL3AN%fscj*^PI-R+8b3u4qqXfr37qS*V zZgRP`Vb^VkRkyHTfz(W?)iIK8l1>73U3Sr-p1{hl6EZuR|}dx|aJRI8Znil}vF z>HX%G={m?|f4BJJR}UQ1tJAJoja8ZZW1g7ZDit_nr$dw4b0$96K0bEo^=FH&|IT|k zAaS5+pK_rk_H_1ays%STok^7@hmTzS-Yu*0)UWkj%QU^#^jwFh1(EKH$L?5jcihO7 z`7?i*WFGJEBEh7$!qnx=D4+h{OWt^EQuB`M4n?m=Upsf0HX!%ug)aYe^wZ2n)vDaN! z4jy=5*vJFfu{H}T_Hl_b%Rlt#shwfA+2zoo(eZ=J)M@o`+U4AUo!9*<54IaQtI_Qf z%_`bu*Y2;{SR=no(BEIW@BO*X-E3zw=X3QAtn&NN{LzCB4%=ey&RY9p&*s^Rx3*Cg zwk*yuG-{%bb`5$nIHG=yP}jswMvJE}KlP+u!$XHZY<<6}?}f#AxA%X(zh{!)@Li@m zeJdWn^>OR+)eYXpJ=!?>e1c8Zn2Wnjza0PA@J8Qa#=k0thA%G24FC9c_h;4H?%jT7 z-CcK}MzN0h5ux9PlsDa#(zTRB?6&URryP0T`dF2lRYpgb?Y;Dx=R=Q|uTPJzxyUO$ zuyODFCu>JeT9LFiJLz+WU)EDc9JoI}sPw^&X=b&Wha9yjZxFk}A}1reYx6BHZFa?% zvJBYTzQP`ZWhHI5eOTynp+UYy*!jQB&h9N^+VgF$d8bKV8n;N1Ri9}KzHhCb;k%{N+**?w z_I}WE32Ar!JSD%<7jk^GwFo%uWVp z?DyQ8S2c6&#wz*648lW$4u)sdw_2Y2EY@^w-GFM9lRnHkKVkM~pBk5Mo_M#}r-oP4 zYQL^ze(11G(e*=KNC&^R?R}0a&Q}aFQjb|x_RfMwdIrZb<{ypT*7cfmN+s8AcN~H& zyKQQ;pl7t>y1ex@ua&&@B0tNq{YUrt@sC&P?YBGkEbPenip6%n@UCz#+1`6)`x=u+ zbc`;(ZsU)&rY~-`n^w%P%<1A!7AhQPdyNP?U3ea?NVQP3m88yw8VW z145dP7*P3V-Rq^T3dZI&37B|rVA|bf1N#QV&nYgDG`s7iA z$G2@;Y~65j|A_Q$-+zB>)cNjGw-d`2w(wc-z2~9d@4iI!*mM2Pp_^>b%5^uIZ|Jk; z__Z;r9y!MIS|*=NXPxu>n+6q2_xA4o*lz2m@2P$3c^#>DDP?xbm5aGAqSj4Ym0T^O zjep~;1U=jAn#WJ}NqO#5tn;I3<)ZZ62EKeVDPh#3pBMX9x={R~(tU<|MEWcH;?@0I zm-=-jGT?coZHEs(@3pMXV1paK0%p}Vf9RGw+`Qq(Cdp?y&$)i7!lWhFm#gswh*|T@ z?q;3mRqNTL^8xqV{KRaVvX7ocZS;Be?atG!7E|wLm8#TtS%Jf#rtADdyG(hx?WJ+4 zzp(M{fB)yt=Su)-*WdpJ|1UmtAkzQu2mZfz2=>YS-=**$ZU6ta0B*$fnyFxTZzjVV zBpJOX60a0wc!eONS770Fa;z~(`{LC$_`&s2^sY0j7Q;v5SCi=7aHUKS&Kb_Y?)$0uHA#_&on))Yjqd7@V#(W`#wl{WO+7J7{ez3xLRLZgRu z%OPV&i{CDs;8|3x4xYbq56dPat(#-=4q%T%gZ z$*fXs^G5hh;tu9c_1)_KUEiuS(u6M!1a_Jz~j-9TUz?$emDZW}}%dGsgw23^*8&8K4ZQAJQXa zYWRlm^zaYssu_rXOda#hz~okO1EqmNX<(={(8Gslqqg+>H&PH@6}BsxZ(~DvXqd#xR6JUl@rxtui#kO9}M!VG^cN3VSKhdp$7H zH!xJ`=|KxaXh5T)&^N$%!R8QSXb4q|n4vJEN~tn{!iEZ1PfuTIV9fONghllX^;E_x zBO{EWu|lO#8XG7eQWzKhX>4Syk8#yEFfuUIR~bO6u(L5U);HEyF@;K{g#DFZqA*~> zW%OYOeU+X8Gcq#7SSY~7KqWhpQmN8YVT29z_4Qy6*c?WKa$+D93Oz$38gZ2pBV-8k z!+PK?xt)Qbk-i?fU}T8B)kaJKr!h7(GB%c+QE8;FRG=UFunqn(xRJh*zP_DP(~MLKg;HM$eZ`zGFi@(XBN>dg zdK<%~4KOhj7zb%ERVqV0=m}59#&832Mne^j#Yn)E-1&`+j1(&PG4x_ImtY4y9BiPc z2fr0Vtgo-njL5Z(AOucF#=y}^LqnAkBPQk`rk=h&+#T+P$)QIkq2u-R;1EXA{Gnw6 zoS!N6X)YTW8o)5b0fTIWz3I}lGJxMG6o>*ekyS=Y6;oo=FzfUHH^2)xxOJ46R0bGH zI6Aqm0!G8|F^oL$I7XU+3QRThSOu5jt_<5@CSf|lhcLc~2*OR^>qbV12;?63aObQL;!SDu5T_a2&6#^(`hvYnnA}|l!6yC%g8c_-XLLXB~ z&lph#(?v{fBjgMfa6~v3cW)Irq9I&?K@P;|8A?;0P9~M+7e1NMyOZdBMD*?)I+@YC zW&Z7?&`RgmO#X2e0be?4WzW-|wCLoed(xzrWXMEv+Jh(^g+BBi6MDY~y=%h;WD8P* z2xkZS7kyf^6+euLw|7pYAM6~5-^#{sY8257FR%0zKf{Ngun=!Rp9FdGiIq-XvQGc& z(;o62aE{v)WN4zO#nij#vnf+&;X=Uw#H<{ws06po446!))X9M1~4y}>stlKzHtPINHvkT~7 z@Kf<~^BhluG2kD#=J+{g{Kgqxs3|ihzJY~!HJ6nd>NSbKd7KYyoW#o^bj`Z6uKR5+ zz5hC`r2A=`tmM5`>-wIyS-!dMi#;A0HkDO@C-eJc*mQ8cwtT?vhc^6cb@s@n_0Cbn z>-BkNQ+-=bmnH>oZ3^)286~Zuk>c=LZ{70XDR=|5Y>PIs%FcMNZ!5ebA8(zf_sJts zAKNUzoB4G0*W$ehMVMg{Mjg4tP`ow&fSkF7%sYCKzLfg%cPn>sWZj*aog>2rEPFT~ zfBCQzG8iK@bLq^~-I<3oZK3o4pgU8$)0>m+)y%`5^>U`S_S(BM7gy%w$n1MCS7&D5 zoAq~Poz<+fBU5`Y4{*jI?#$hedAQTtc>B9ES3Bm?gY~j!?!B3N7v|=`)Sa2V19Ns| z9{6v^dO6a2n)`yM2eVVN?rLW5$lP$C19Nj>9xlwWH|y-cdf73DeymFm=IG9Pxv+kA ztb1?P#fkM&)2oEt9a#?#=IqYgdNDQXJF{NhnVTK6Lw9;GbuZ=)wV{}rVYgW?sG+8p z7rVMKx86+c!t7m`T{mX$#2h`ClM8ckV6Ht_ci^3v1NzdL*>z!EJeW%_=HS8Hp}#A0 z?ZTY8GZ%Z-y$|c6W#p z%<Mop&|72&n0-P+Ixn`}#Hyq=o5SYzTlJZ{R>J#hW7qNQik^a zZ9zut{o7ADzW47m<@nye49fAnf7!@Md;dOBR_y%?Jcg{;`?nHVdGFt5%1e9y_EBEi z`*)J^(%!%8$ZPigJ)wfU_wNH0NogXLh~1SQjY;xi^lAZ_jFx8CrkBD~Ftr^lc9LyheGn)bY$ZPJTB z&WK+<;LkDg`&ej+nc!N9o?Nt@VfwK@KK;+c&RI%APK^B!WP#7c1E)FqK**47`wl$9 zbClw4m1V`M1=VhEEL(9(%-fEZ!{(-jg%rH7QrP@HlxZ_nF?0Dg)u{^6BU8l_l;9%w zM<^wJ=MdHWckk(Qyo78iJ zcPwIJS{M4vRbL!QGM764s)F4Sn%;<;aCrDLH^Fimy2*dW0YBPkb?eFGqj-GybCWSH zJNGEqxtDbV{H7VP*AZ#U4Ei@@^6j-cv8>pV^R@I3wa~LZ_$jemw954R%Co+HOnvA% z?(xxXN_zeidHUR)V`yUARqfi$%E{5LnYD}By;*a$n|resF6w^GT6XR2+N@RA-rbwE zR`>4Qtc{1GTeG%3?0Z=?bM4W`%F4mf-pZO1Q~T!{nq1IRoBNuNHn*nU@t>u(L&;Yv zA4i>?xiukpdn*3gqYMNupWtO2EtS(yCVoKh_LEZCOX7DPWjk|k4gU+gO#Hn${v!So ze;8|wDUp8_agnR91EANolq9~aQRlw zh0E4mQFb%8w&MT2@bjNaF$GYKdMl>Bn}-|BJeP-DaWpd`H*-rgE_jW*%a*(~3RyGw zDgPl;)WE`4C^5$6Ld0~uo(`C5gn5NOgaL|UeCRJQOq~ZvO%hHpN~k3u&qF_6F^#FC z-WZzHB1PyKXCf|A0%}BhGj%$EW(3I7%H-T+nLbSYj+l{9!cpQDk(gh|G*&IsWJwmj1E3iJ z-e`tZOc-fcEh!p(l!ldXl-!6_VPCQ&?GgaApk9!ML?qQmmP);ayIW6(r(^=zjS!Rw zHAY5JUpdN)Ye4OEw$jCV$yn;Iz#{T~f|BS%A*7W#_d4by%ZBe|0%$=4tjiJ#poTFY zS-clqKKL_O()pN>Z#DMuCLr^Xg#(xbpaqSHmZi7WK(g#G~O(_eX z=B??wNg=MVrHqxuPlGj+zd%uvO(RZ3(@8VhB;TIw&eS;oRwn=@@_!A8M5_fT?5ku+ z8Az_J0SX`E+>QcRlV+3*6f;Wl9}-I(A(e1sal*ZW9mSNAa3tA|~dvr~(6hKRw z-oz5Xp8)cyD037_3fY!4y}6P=#{B|In%y!|$QA*^l7y3Nbmu037UXU+kk$bjFVeUh zSo;5#X19#AFFL!qziI7WT8FDMSzUK_lX#llcfi%6j1H34F*4GUP9mHukbwn|PjNt& zZ>J;Q(hHsE6GQ8F6kTMjvrexpy`=6_%*q5;el8(n5%DELQxOsP2w>$x(Iv!RWnxBv z4;UZ<;e6PXW-s?M0wGia!yz*R;3$|9?h`nR znE;k3^V63lU!bHCj)JMoPq?>)lLaG20>^`?jKk5|0pW7R5+y27$1dOtyXXLUm&F?8 z6amQ#Wsc~emZK~gL;Mav9!x2y5edf79kQG`MBsJ$=u`%KD^tI4R?qMk{qWfkV1;EHv!>?7lGsfg^-`MzSxw! zl?O9Y6u^99NkgM$Y28!~DST1L=Kzqg3sqvdpo^3j3^bp4e~K&@bg^=vp!qDYu;x#2 ztxW?&VV_8vTHNqjyJHceP6$?+)F8+M;3XKhyw>nz5Fvr;L1ri98O$&V$?dLVc0O$Z z;TI)@r9@a5-ij>mqcJ?mUIcrRr~d;vM#u6He+NJdiYEm8qBXn~Szc>+unb%bMalA7 zmJlqNUTb-brj(RLv6At%wuk&o;!1I)5Le0cTFYxalx$CDJtBJ^54h=dq6>6QUIL#d z1SJt(bbX$}i&jsXYBE+t7+s&I2m@CR34xu+J7lEbDv*2uVad5dHjsP)AtQyBLOx$W z@EEA=QCS_XLcZt`UqJ8(haQD3#emWRLgq^H3(q;ohoVOTW8 zp=6{SK2n*gQ)$S0@FQC5;<^96(@DG6jAu_U*X zk+N(GA$$Qr9Y=SfmVqTLAY>qg*uwLjLM&LG0+L@I$ViH@lFKpSa};B>b}y~NmBK8n zF3zNyFblh{3xoVJI!NLwBl!Y?Mw6Br=|J)Yge;#lmF4pV1X*dC*6+ycWh}{;d&L(J z)P3qz%yN}USz0uc{fQ6;=^s<4pv8cfXbZK<#FY9&Bq4BXBp20&DEbioCkoxD{TrX< zbh`!BNIs+zP+nwkDN*Pk>|-9f00f$vynO)S0-)Q~6^MmO)RKLO&_K~hKv5P*8gKuV zDw7!mInN`UU}%N1EZm!PloAOi>=PlJD@s^dxEHYUFp_whKtvkx1g1otA}kaL42Olv zp^nI2*bo+qMztY|K;beNg>KYN369DIQ=ThHo{RrfrbJ50Sd6Qt+gwRrK~f_ydZc1` zi6qJRRYSBG@DkQ_$X6!>C5Vv+MkAM$%LIr=bQ#EHNJi5N#g%uYB(nmz5jja5)mzYF zz)Ofy$d{sf+eGj+E>nGt5WIx79P;Ls&`N|lF|x90QQ-}#E+4 zTJk(B!x55Ds6ow?s1hKamj>Sw(jgBhTe7MaNw;7HQW|<7!B9$M*D4Z`V2mL~G%-qL zqJj_~E;<#ZR|-N=asviDc^|yJEPY5B!ug11ehWg2MUO|D^YPZ`sp9~oX(6n1_tnzJ z+Y5ZDPyAS7jR~iNh26lJ>UDeNO%+ITuP9Hw0+u&HU2o3UTWbP38`E1Eh^TMei}$Y) z2H^ctr=#S@-`v14*5+QKOY+3SRhr~OXs14DvCvb9*6K;JB}GZkY7&v2#72E+twuIt z_eGTQ6a=E=hHE794N9`{wd}!Uo(; zag1yO5--`5JD?Veq4yF-(6xc=Rb+!gSg3$1oINE6$}oNr+p2#v`G)g_|4ab$M&xeY24Bbw&u7c7v8VxEFfl*m$J{^wKFVMw$NjD<37SOs3d4U#7u1#waohj%=zKt^l5?Mftg|@<2Ok)9VEpeZb zEKoxt@))4u1=ltT6F^xCfY~U%QV@(18LDU$(&5NWpv6+G5V~qj0QH5Y+ysTNU`;YK zCIHfhDv-zoS}ZC0FHuMWlL@p~9)-BQG$!EYBCg_gx;Z|HXp-|taCfuD381Pv55-{w zphUjmBiU5bDV+s?0vK}wB9Xr!Xz{$pTe(?9zev%V5|LrWEX;}((#ia|$ash1D+R$Q zk&b+rkk_4rl1aJ!wOCkbjL@}^szM`f|3X-JH_6c0AA%$(x4#z4Cn3jbx;2J8Pz-?F zE#gJpf)<>O*8ZYv)J`r~OCrJo&D77fY9cWVkdKldVJMOLf#P{hpXeYdDe$SqqM_(i zAw9+6e5zOgPb9ulgzVgHVo}9?|0fDHsF{))%nF_S)xeOtv2oJLUq;ex=|Yj3?!FO2 zDJk(;TOtxn=49&EV572^PyYVfY1j!xiSGOrnsyS-M>O+cm$A^Z@X4R_glow|NhT_U z)jj!(KFLr%>@t?_eioW`Qm?!v9pqk7ky}9bIy+9@fl|)p^|{IpeuSUvWSCl1A*ToLXz2KBu0<85=$}L>>-!b2uW0#jMOWHEaFNW zsj(yXVVNs+Ms_xv{)Kb(WEf|W{lt@3?O64 z0J5<(27vA|mJFc9YCEMdfDbz5BhX|387n+MSVm(2FEXyck^ve>L>|BmuzWAhH)?1E z7+fG0#a9YKQ6dY-BctmAvI$hcXt703jobyaCQ#^Lg#`o`jRm~4CLjyQd?`Tu(*?)` zUfc#`0U0Y?pr{4N2hcYpvOq(LoG@NAy6V+QnEZ5YNs~VTg&G8*M3wSH<%8-33>|V4 zD0;MnGZRSdEjubH^NZ8?Ze3&9BU$td|zJ0+?uw7BBm#1-ze7F)zC2&*&M$>2>SqE2(! z+mki2>2@PZuM`BLL<*8+C~;R8I&!z6I&yU_w#Z}`!V8U#F1FBQC#=@f`8igLrB00| zapJ;NU<*xlEtZV0Qz-OkhGrtM`Wk~Av!XwI zsRi$_;#J~)5#cE5U`3aSqZej6T{Epaf}1MDf=FE1L-2mos)S%*(ox!~5ON4a!y|ga zeVwx_JnUL5jglA??(2jl$)pz&4Lj*XBo_4l(j^fK_>C=j$aJtpx`Y+zQI*MYg%(NI zid>!**Oproh7uQ5{I=DrE*$F5Fsk2dhr63d~vVdlCfhBh< zy112CQV7&y$q9;BfO;iOE=3_MS)hm$04XWTL!g!~S)hm$XfzP6t;JH{5ISfqKsr!o zkjMh9BodJb7Pxy#>jcn1orm%(1;Ho@*gu^>R+UVk#nLH_&scFwQg$uQNjQNPOLy4> zR_g@XiJ(`6uY4NRH~}99!I+#t%a?Qz`f5y|9R+TJ*1!{q7>8i|_>ANPe6-Y`Q1l}J zCGr$mxW=Qs<^ieJ7syW(mbt3PMpLCB0%iTBB+@#bdh`O9N1J^r3@~ zU`!LBokSwM!2<8kYfi-&j=&3aDkcym5hsew>LT}7v{;H30;^FJSWzQpYJ2b`BEAw< zoXJJB#(K?)4_0{zXQ5vRE1XW_ELf;sq*F0*q$J`Mj}@9zF^#``GOhs3zhJeeVqoQH zNyDYZQnVC&dC%ySK_iQc4lB59#ec_w7lw_rB`h$M$O$`0B%BaN|8+@JL=nr@K|gtKY7 zCF?8C!$L7g#|t|GNF+>vFudTZ90tf(ut5|m+7pD5FoBSzU5*e^@FZ0`NhG`gEVIBt zoZfk#)bCJ!r63q3;oASkQnXWK*J7#n;v}T8s?d{z$*Ni`%|T&8&D^GOm3l9$N(YMI zDvhk{EQIA;g|le+QX~{QXspURCcreeZ6vaX20XewyH0c4o_io7D@v~v1fnEvA_|7W zrUEDF$=yoE(wzi32nhqIp`}()GJq~tR#X@OSS^$XHyJDLs7N|+1K1H(aw=f}EtYf; zO~L@cB53l?;13zVRw7{l_`vI%6yDJ>@>P6ypFtKN6eVE+T^Epm(pZrT*b)#)%`XSV zz-TQ%Fl?vEV*xL% z3CIF!iO2%@huf&P=n@Ydqy7iq#)UmWD2YK8qBUJ2)NY_Gs6#T61QRn#I!a>23?zRj zzz!`$WK!;V-_XK6kK&X%ia z5`+E=(ztARD1zx-mB|hz0VoN(NDN^_{uHNMdd*9pPjmEf(FDusU8Z z>&d-d#*#V7NR%|4(wQMj9lm1B1y(!e=$Dje%pD{W#`mHYaaQG{F3wR@SqVf~N;+8S ztV+I5^8_~n?yF4B>J>)vj#%+H@qgsXvDTWH0F^aZRk8!cD!an^(i0T24mwzA z6#%dfUu6-jmzdR7e1!iGd?l>4#v7onmt+X?21kj+{Y*rFh=&vb=nf)gLmUb{oB-j( z?>r7cNpctt!VvH(@c;$kD2cn2yg_mpfG1Bex1KT;arF^y@^l7@NZeC|;MJ%#q^G|~ zZ~{TPpqWVA{R8AQYE=RP$Gd})AGK2=HifS|zzJh6T1A-9VrlmAF_&f(u&|5lA7pQ5 znRvuSm^k;C&J6+x;h8A5ClDoi3STm`xcf&q9fzw1Ojn6Sf5C9$6R9(hjI}9BFBAl# zBtSwRF*5{1p|g0bLyIjMcYyWL&LRc)X|YA)4zSve^SGnM7L7X`E33d4ak^Of940(X z=)gOJKjdlMByuxvfybn>RkX1YxueJx?~XPi)Zoj^3{>eO3s=dZRu{Aop$e9o_e`{6 z5WMvv$6=ukI0OteAlg6I4huom7p zGz$6RJ<&vjhnjHg9#laq%ATTDceD`U&MB(0s8wX&AzQ)&EksZS58101y+AV-_du>g zwq!3f5ut`2u2=6zr2)00SLw)i?TtnvI$kXKq)CSgga+x#M?A1XI7&KLY0?pxsbg~R zcwZj?h){*6GYPI`i0`%KJGK1z55iH>!D<=enn#@vjwSvAf(Z7cE-cTbE^_0>BHOJm znut)tAJazG3dAeCr$Qp^OsNKlaFlegl0ejW;p>f`;8?035JXT*M2U!(Vz7CrLf*7L zT8TJ<9>-LlKs6pqBAf9Gg_{KX8xSJYi$@*RuThPM=UPnV3lRTTSkeptfJlIdnUpv; z0LQ>j5`Z)vhz24w&^ZZGPoo-70k*(2M4Upwd=T1+1g0=Itl{ZeIuEQo0U-jcxnLEI zYCKc~hvus7M$uw05JUo1gc)#N5IpvL;4JD3|g9ga{(}%0+z%wbVs?Z-6hU2}04Hh$<11@Vz){Np<>a0oQ0DZy?SW z03uY2uQAnIP|Z6?-)!JJ9YPHSf{3H&T1tIQLWxH()Y&MO@&kg1L|`F_r5tK$6a}ZS zx4;ZTI}z35Vi%DIwGswKKZ=s+aI_O~X$X3VKoW?)Cqxh;&rA7imL?)&co;ne=_^M3UDU~3j&`d;?w6Ig(MJ>M6lGM&a$&{9GM5v|bF)#xb zyoZ@kq^Sd)qEIxYX-vdXK7`tXYH94aHBS+2EFeS_yfDO&n1yN#9u@JB5Mjolok+r< zdy77BLlFk0btu&w4*-z>Nl#IsELG4Trvqm`0aZjYjvR+4Q31Pu0?c$G>WFwP|6XzF zM_DHIF$N{mNdORW5T8$nPz{HHV!VqN2{joAB3{i;sLxQ1iO*4_SU$m~07As;G3^kw zK53ajuUHgKDJ~IFIEV3pN|E-vpWl01>a{dgT%;2?UG%B-C^uhcFom6W2Mw5D6U3wIV#F z(^xqPhYwwBVV+Pl6HIH)1&D~4;&Pr86-o4m1~xb!{q{#Kk-%}`C?N?PMm7mBmwBim z5;}4tigOYw#2G^L-AuyaLl;{}N1RwgzMwY26jh*b6o%o5y#Ph`)J1o(}3gWij6zYE9x*!N3B8e%5X-&t$ROZQ_QY0KD9c&S%P&E%+Yb^wdNa_-) zDw5Q58uF;0=zB1#i6o$W$4&HIoKjB#=eh_OB1trvQddpQ+Q(eN;X@Z&SWOK2x?kw~ zVt|Mwret_srhJ7)7Og4a@S%$>!W4b~1g(C5JUo{9dp_g zDuVSzz+9FBLWD}JzxYW+sE7)2YR3rS{9a4K;X@ZIsYqb{xJhgQY#9m+k;IcuIfZz7 zN$WZb35O3|Y+;`0^-nN0Sq2c1n>p6+5&lMWVSrp5a>c_?PlOt*&`+QWOK{5Gq}JtV zAwm_5^IB@9SUAtfq}mF!5V?b!l)CUws!%5YVn)p~^b0}UIRqRVLI^OXwNbHBBAhpH z=zCPtVjkJR`QQ?cRw8$56-fxPJC6;2qIo*4qI$QEzagZ)Iyv?!E_axiBQQm%Q5vOR9o<(wR!z!=FQAo zG(bCk&Qc<&3EaK`i3Ji4Bz7TzV7D3|BGl50L!ihOR1-T|?{aq5g54URh@>X4y9Ok& z0}|}AQL3>P03uiiym-pt#A_fdvtyz|A2u11%&I3k1l_ zL8(+U+KH%^7B1>}L6XsEr4f!osr6_kA_#3nR41Yq3k}W&&YDV~4FC`cKB&EmT1gg4 zc_^93pq+^NC!Mgg{o^V{Ei^K5AxN;)K?$bQL8v7q@`{ZT5lbl`7Gep}@4&MI;TB0e zC0rq%Jjw$@JU2;1PAzP*KNvP4hct&x(orzo3=ENkftbgrre|@0LFp5LVgVrHAU*&~ z7imBkfEbiaw*WxILEOBDP)(1Nkl%vUMHJ1q0zpJmNwS^jCru^p8~K2_5G0g$Qv(y- zcgI)N&LEXv-b)*WaeLRCwIEU6V){}8msqlE~q7=hKOqGORwpwkGc#(&Y zmLi1g1BwVuEd{f05|WA>X(f14RTR&X9z>CLyV)8^8_# zMFb@LjgY^9!~}08mQ!J2=W0uUm=;Dg*;C?Rn_ByOJotC@xx zA_-P#;VcbdOgKFLBrrtuC;_I+A=F`X$Zt@(NQhHtC8E3BsCz~TamO2_d_tT?D-qon zMcwiUAox8}D#fBy@(fyuz}bo_Q&3qG1uqyJYeadqz|I0ggrhkw7dTwTTjNUBhmQM6 z%+diMqVIue84?jG;-{o^9EwBFp`D1n)|M6;Rw#;oLQ8p3UJg}+qojisffE)b?eJZM zM#J;K5z*HKBzyHLlC3dE0*XT~pq+^B{TGrg!617Gn)yac!co$}O0oeK-xFwLUj&Yb zZi}$DBiDP2P{fmc9%Ok+X#R3|ukdC0japH74&BAc(NK zhsoet8&M1QpkM(7l29_eigqHp0uZ1}sK&f(LDxP&Jt9umfFN>`IejBeRN|PBHQ;m| z?L?@>;FGv5s5U~8p3DZPWE4x?0D=fhZvnc7TDY6UDVsRmL^~0bXf8m%P>mql!pjG| zbUZEtC?YgTGPkc4NLuad0NE{|h-k?#cxC`u3`Ih6@617k>1|+$5Clj;3TErLJ?Ksc z^&%Wa(>p*A;Q@CEl}IRF}WRgt`X=kt7k<_zR*%6q1J^ z3T4y#fDlO{5l{9IjEcB>L7JT+SSBDul1$u%$wIXS73Geil~R^OVjfaY7p;eO@HVNZ z>rfo_04O3cyZ9p>@=W9~-I+)@N;+80Oe7_BCL((X9FZg)y=7VD z63fxZYQ%G#B)__Z!-pDm2mjb#Y$QNJO%fvL2^LN298ML>w~Q5y$)Y|t-$I? zIDF`0wR|VT$94EV1CB_9BI^C>P1JkMG)zFz^f?ejBFNBf+0&@DB2*DqG5~66Swdn_ zBwoV7yj$=?t*3iqQMlR2q*h&&37BF+U&QMGTcXk)Z)pKA0l-luQ7!}eu18~OZH0gJ zy~I+9S5Qp%LOUhG(n;Vau;4-etTb3u&>4zwl{vJ z0E;

sxXSa|l5i$_P7-SP(}Du46c|rlg~cu;++99Kp3rB?M_HBM=NBC5t1to_T~I zJ!J&qAP|eTlN7FL6td=|DTa_Ia!rg4&->79gKr?V0#>sLN*EKKBp9ELG7N6<4!Bx` zD=y)n23`##y)TZY1g$pkzPNQeaMj-wWm^fTHm4^;FclA>r520?AMx^*8cDf+Qr@1& zXXx|{K)iwkVHk@>kVV^V@SHTkYxtyz&chrXQP!pOZsM+$b40?Z0uOWn9dEP(yYVnzQ-%n*7R!87mZO?pq{$@uW z#Iu85r&+r(wb^wSJLYWoh#9|Z!m6#f#$K8IW)1dKV>z9+vCl2%GlwHh*t*<6mQ;5f zQ_t~ax0bhM9szCHx=(G{63;+Z|62;nuhE`8C|JcxMH#TtP2aL&{g<%OHAb^5b6PRu z3-y>&kArOeP#b3X(vuyoH<>+qb(VFU`JR1kt70qM7qcHDU$Po|JekqJrL37=A2#!+ z6MGjwl9?a9!diV=!=7$8V}rbwGoz}{*@D%+ET)_%TWULu`QIsE^(MM7LqjWezE62} zE^Z>5`D8E~8IsB>pX$sm`JH6OIhm|qKtr}<$|<(BS|oGWmBlLmb&YN5WWWqm1+4iT z8vJLrzSj!si*xV22+53fNY*tuJHlp?{mNDi#Yi2o> zm2Yp)_Ln=uPF9X)iKo(7V;416M*~^VY$x_~yd_(EW({kOC1cX{SuAPWD%QGp2D{zq z3)^g3iMdSq$%aHXWaDnfGoM-cY{u@tSjF-$SgLa$*8bLAwk@y?t8Hbz>jRwy{c&{$@?e zwqOBeyjegO1^XQOH%r_-msQXGz`As`XQqBP*p93_Y^SFk8{u`C6{{c1ZmdpXhFd?d z0aNF)&1nJ5t3xnbJaHP^71E!Ly`91=xB9S8$1kv@^WL($C;V9N^N#HN-BzrA+;x`b zwUm`PHx-#|jC+yS1MJy+L6?^hLkgc{_#e!dtWS*X_*pXi)S(i0Q z%rABn8$ZF0EgfjhHk40hN1qw9rB-#=*GX+zGlOcZL~#Y{W;Bd7e$$tA-Vw$oy->20 zTeaEO*<0C|E)&>>3U66x_*Ry*{0qD0(UV;%_JNs4HD{l@&0%|ehOw+pp3HWj9$TpQQ)l)^Yf%{A8@LNUZJaRTOt9O`14sXEDTufkz<$AHOCnH$!-9@bN1UIH1dyGw0g|m;%#^LI` z9(y@Hjtxz7WsE&I+bAu6frS*6-ZzYH0`D zo%ea(-}~3sKaX8?`c|ELtE#KxH0;Qz?W{@$8xHR#sEz%GyTlWzE0VXWc$*XK8!>Vl^h+ zVk-x^viPxYnazok>|-T6cI{qy_VdQYtZlhpndd177Si-FE52tjbE~|Wy5X1Dw^YcwdC4KtKvUq*aoH5%n(nglmi%V{`kwfhh3Pixt)Nd`70!H22#c4Qe> z0-5WrQtXI}AFHbIV8@bAGuIQ_*k1h?JeXa`Z1wk8hwS;RqOm!PEq0!5kIrDpnjqFa z>NcAZX2n7yy;y}yTbbLdgRHnAhIMki$A;Bi&dP5%z!s=Inf=zq?2q-Bquy0yzb4*e z)xY*)1*`{QUUy-wPt9k_B{SH@g%?=8PWjoU4^3Io>nB+MJ!jdh8~fPG(!1I5g@c)W zw`f*3vNTS_BiXV*!kUWm|@~! zwyJI?R>=Pub8gg>X%3EHHNQM&4=?}4D)l?gj1xSV{p~~S>y>fL(Csc;_vJ8~WWSH~ z>ttfxS8rga40Bkcl)mh6(QfSBndPiz>MgeU*bY2fY{TwuD9B7Zs<8Y0yD-z$(X3#} zI&8300X86hGP9~#ip}fOlYRNJheZXvVApW$etNAq8?$3OJ2>q#Q!T5`UKtLs$%j1I z)n!p^)3VL%%*jHm*eDlfZ0pYIM2%uIPXEp>E4Q=moma3%wPv%TF(=s<#}@3)>rd>L z21)Gh@H*`A#SHd&({lFW`8ihC;~1;wqha0^{aLwdN7>-d`Pruy-B>;6t1Ns|1`C-n zmPJ%L$!bMrvCPAlnPZu$tZec&mN-Srs&(kX8ize+1B(`BuQwNEpHIAD?z>!o=j>6Z zlPtS)7nbnLEH=^Y1v^%H8`HF##qPA-#o7!#%&s;n!m@h=G8gA;w$^C@t5~NQYya03 zcCF8JHa8-ZwI2SFMcI93_j|8lqbhka@70x9!lWz~`Dg_jQq7wke>jV^DY%%;a9huo zUn#^AZ3CHZ!%H@B}%9x z=3MwVJJfzOoBXjhyRh#ND}3k-yU}3{Ykp`r8|D|wDh_YJ>hzw>ifBf#TETtUpgLul z-`-+uWVP`uz2PXf?BG3i|3+VSu>O8l?e!n*T>{3y#Jxt)mv%=fe?6)_+uo6)ZS;bfO zY%|Vjj00M+C1u*M%^y~>A-68Gso5G<%2NT&d2Hyy1uW%R67w0?hYi`boOM@6vu4#h z;tLYb@U*HI`}{hRS+#G)Zuc0(d@o$GcidmN$)}1RgiBZ#e^Voz-VU1H?0rM5yRa zCZ$GcGWBMmx|F2E)KpZc)ane0IxTCRtV(Hw!YD&=_gBa@8tRd#9Roc&3d@ z`5Y@S$;K2-N}|5EGR>grsY%oeK?fOnYV?UHq|*A>IF!s2-)SBqk zv?Pox=F1akO@t@(xY3Zn!h0vh8uf{BLL)2nMq{!tJ`9>9J}k&60^=h|W9Y3kCL>U4 ze<66@2Z&VY60J_WWnoN#uiv`0sYYwQnZ{LI*F?QmDGf<7lA1>tp5I1fjy8>gR4Pi% zCs+73{^o)hx{*4kRj{n3Sy7QCo_=m4qRn!7hUx0g+Q5iaSjZc2rYhd?Kn%!Ht`qu=W@G znkvyKaom9aYXMyd`mK_fK9 zXfnnb^}PS7MY)IK4xiIIG;U+DIh9(5542RYsm=sPQ%#8maeCqX0bxEuTk(K%`sSNv zuM`XuA$(y5;kA9+ECl{-M0`i5rX^!Gpe79$To5av0y$ekzRP_p92Mw~ zrkXf$%F1a4@+yb)(-?#(bq4Gv@t9wgVhbx%yQZ0hX)5QapwVM^X?s&AC#M(_Xrhu$ zd~z0h1`Y(muG>{(&|9lYTpGzE;-p=W7n;N?IIL?t>#$o#vQRXtfXQm+i0D{zFG~lsb~Aa z#+&J^npw?bTkV!vr7FU4KmE}IyvkTndX&iO;f~(Ohj_l?Vbk0u%7*#QMMg0ni490p zYG&KT)?ll_owhT=&38K0IA-_Q?t@*0d_MVt@^#LKw{&1Q!Rnl8E^9kycdbFmVTHeb zZB#u!EVTgr9bNhxy7c#R>2K!>e>WF@WR@P?cmO?s?s!af`qS616ZhhA6<^BWPhOQN zQ-*T3BIQ6UM=?#mRxg?#+pY8G!?O_wM^xuvhmDTRj>=F;-@%XZ;FO-H3kxbNNOVDZ zWaB`z13hdn#C&(c&I*tAj$mC9&pgDx2*LPMKRi>zwl`#h$904MfDImrFdO=hInWb1 z;g4%z+gfb1Du(*7u27VC;Xem@p+I=80Ex0ll`UJA`Thx`LQ+mJaA3ZRo}h*js0r(m z^mJc%#Lpb)vApoI0k&n6O({GL#d>DBlC(ki&w<_=5Z)a?!u;t6ZJ~!k=nSDb^I=U* ziN+9|q^L=+Jn$1x6`&{NwSjs7^%R|d{tWm5&4D1GH4qN82Q+{VNC3J6NdWckKwu~^ z3K#=S0j2?SfJMM>z-nM4uo>73>;nz~M}P|e4Zi;?e|tmA+~;4x<>mKs@N(aGB5&^h zIdHVx^HH$n2xJAY5?BSS2G#&;fpx%oU<0rb*aU0_wgB{im=@>y3bqybZNPi%H3Z_e zBfkU4@=~yufV6*Wv27>#UBGA95{TQ4{2riyw}L4FdT>n3XKdRGJ`pLc+)fP@>U+w_3EJi(dk^UXv&l7#b$BBu?)S$Rr58Lp#j2@^6k89IW zc4T8*uJPxP9^alr;(QE;=zl0KJTY8{@={qhE-Id#{kY^)JRN+>W2X?ve`|EASv^Ke z>TyS3(;}}&8cWXDCXH2T+z=;?RjIH3ZH!8OxqoX^;cWGX0aAP?p+j>Wc}JSGCLIMI zQ0*{w?!oE%dG=YJPi?>TSsj%9$3FXUaiPz&C@;li)@MH~NioewIa;W#$^U=ovwy7T z(LdCaGyd=#{DXFgfc{{A01O|P9)fi~&Uy((IinA2Xuw^zVHv=xE4Kau|n z$bkJW;4Cm5kjhcpOLK-)PTn6BwWji#3AAOK8wJ2rbE6qbRb)0J%nSIMV^Z)nX>j?=x}k zkcn%OOk9{{;sPrZmsgp%h|0v3QzouaGI1f4SrWh{PA0BbGMxZi?`7gbDzhBm4B#3j z6YnQy{scgpPT3AX{{Zw4K>q;r4?zC_^bbJ)0Q3(){{Zw4K>q;rFF^kQ^bg<+8K=($ zP`&`l7eM&}Hz=N)#cb$ufXUmfi=RSxAKb5QWJEI;Z@juT!oktn1lIQ~QZ0l1V*Dc7 zhYI5b>5#})0bxOY_-d11OhiyCfu^)y>)>GD2xO6N)jA{~!Z)nFkPZkB_iY{!&Xmni z%?qs2=nIxRzJbj>UL=}5YArR!6=Iz`h8 zuA^xgT}INSAevVAb9!`*il!C*4jNq^qG^RoL?zZ0fl5GSpbAhGs0LIAY5+BXT0m`} z4&VaR1?mB=fC^9pZUDWY>;ZTJUH~1&e1Q5u1Aq<@booh-MH&N50AHXffL3Jw05xJW zpg9l-1OY98mOwDj3J3vO1ED}0APfixB7jIB3TO+o1L(501JDtO208(qff%3*@PDP> z7h3&*{=fiWAoHC+8H39;7(-#x^#4B;#Jdl%Xqq@c3+RA&AOYwKBm&)l?tmUh0t|o= zNCtWUDL^V<0@8q$%k@-t!SU6#-M$Y($siTnt~>d_5<2?C0i*? zw#3nXM*AtHTglS2Unv3NsgY@+H0_%?_P&D_IylDX=5uVQ9$HKt@N`pwc?GBi&~g!6 zZKUgP&IRkb0PbuuS3m`*0XM)MyUR<6eX+Jd$$tZ#FxkRRj(;m->2_<>Jp^_Cr)X-0 zna=|JQ~kA2K2N|enzjG8@FO48(9aXlrlZ3D7R>c=bNlrQ2ghfMh8Q{?3LJ6(8cw)z z#^|OMo%qs)0i87BLX+X5N>~bXR4`mLFr0u3_BgR*IO$_e0UYL;KR}Bs>;jO+fm*O@ zj&&dq1hfEJ0yM|ad_(h$4xokRD-A&N6U{>sUlr+p+C{NBkKHQw?nCuZ{Yq{hD@$u- z>F;;X@9UAu(v(08)oI!8@B4JMgX7oyCE6+&4qL1hK#k5%t3Bz>dcDpg9?$ko0jQKt zsXs^IGQT^FuuSIVLU_5>Scd{_fG{8&hyWr16k{-F?SS?G`dQNPh@*!>L3G|OozS}q zlyuETmux*zm~OdfsS+&oKlx4Tv3yN@4G2&y=x-sGXskN{oq-sj3!njF0j}m1XVmKA zdYXdb;#9bjNQxC6dB)H?>XJWdZX$UkUPjtMi+sA5hfhjugM_fm=03%Np!U@QIv^fM z0J;K+KsUhLC;!x3P6?XnsFN1@Uup-rW)U{%Phd zL2*9)7tIW=nTk3|6Gd1W&=cqdqyxQyK0q$b#JuC|LWAWW;(X6F`@)Pg`vLud0l+|D z5HJ`R0_4`rJI;&$plM!5uiS16{o_Of{0DyXI;8yzHx`nTrTr@!<)}Y%bo6@MZ4iFZ zLHpmJA8eN{t>=Hgo$p)1??D8=GV}0D+JCsFw;?SlnO>q?yE)I0e{dr@CpcNiV&9VMuYVBII?ls|Zy^;x z9KJ_)I5^(2Du8L1LRtb)NK1j=fMvjPUB_}wk=RnJQ z?mS!;dI)P;sOO&YH1X*?O6_ zn1?C$R$gIR+FKN6PH!!SKeU*K(S`H0RSIJlIN$fX9UNylUc>=%E4FO|D2(mE4qzv+ z3)l_p0rmp)*nsRak=_UF2Mz!SfkVJyfQRW#?<)P*JEBmDcoUcQwQ3;$~DPo(Dmkr z(coBDdcgesHfjD5+oT<|$ft%_oBNauPGsRX(&W=afP8ucJO=&%o&ZmQXTWpd1@IF1 zUiX_%D)Nam&;E;MmpD=L73w0*KY_o1*T5U#E$|L_4}1VV0(oin;_X11{;2bx;=IT; zKf#PNKLcNYzk#m+4QwlbewJ=RMYrgkZUb*^>+=R5ltrf4f?o#>)HchLds{CT?gU(7MzyZCKt`N&<| zl!uEY;FoXaadI(}yXeSWEP!>vTrU2%(+XXv39TqpB(>sPXj3b;!`i$Rw~>qYPLPY* zc(D}=aTg0?T_jHz|C8B88iwDw_^lP2LYrLtoQI3i*ycO(l!N1T`z-EaQSM?ftcwFB za@_RhZ|>ra7TM(DCb8eoFWb57Vyw+u<{~(e#r?Phv1v+j-BMVW2AuNJ70)i*EYKUFWroxn=j^N>6w6z^HiSFdD&4tT>+{~ zx}j`d7d@k(ZFE!Gd>i>sK1(;D$u2J&DMoDmE-uQ;W1+m<>?s; z`9yJ(E~UvYsa>f&wMQ)H^Rl6~m&(N0(5U!Y7e^kMT=xFX^;<6%%nwDZ^ zj_M;jy75nI>LY4PS|~0mOM1jnnr^I--;^dFXlV_Qk7PsR#e91R=jj2#kLvK}+o+x& z*~r@!W79)}x*9yHz4=C{~ZQ&thoo-?W4v80c@YxtC zk=X8lH9fSvq!oAc?O4;p%aT~P$NGate2A&SQ%fY-We4#AaWeMWYRI3&lhx{2KdX!r z5v=ixV_^WUts*}3Tvgmp(*Yk@7XgJK^=Q_CUTN8lwQ#GYg9ki51YV zi~Ri>;!Ylkdb%JVf_muTuoHrz$wiO63)WRpnAUwze8W31)Q6^Gj~j>&fLAER$)mQjI58du4_BBQ);?HQhdruh zN${5@k$T`&Shq$#8EYGCuZndf+JoXLihOOX6N-sXBj2JhJ?OT9pOvuIfv1T;jd;++ z>{s|p4}`7ZAFWHmUo;u3g?uNhr=z`S^6P?rfi#Op{a#q#Lce)py%F`+!@54|qjezs zP-0yfd7AjHpuZiku8+=f!`cIlOAnvhz<)K?*X_j#b|jwU(F5@#$oIthPl)xy`ZUVJ z6_y6R7uIX?iBD3mL%%ojkv8HJ)dbY%ikiDzUBtCmHtLt;oP$ z7)(vD?unMB^>%E(jdi}F!dv+4Ej)%f>kQ>VSW_cdVNJo&x*F`@kKhzlm_|K@4bmi{ zO3@|g(!c+v(sWD{^wpu$kI=!7Q3ux7{=lU032?gZY#4*EMLth)#d+m0jca34Dx zY^p!OO&IV8(MaRL(?XJ3;731=V8>@te+i4LtEFVX`?dpSPy()Z} z&`ss8@=$rIyj0#QAGIq!Vx(5Psom8cYEQM7+FR}8=IW+$Q@gpjxx0C|dAfPIdAs?z zySl5~)$VTY?(QD$p6*`m-tImgt{y56wTGLByN8E|r-zq^w}+3XtEb9S?dj&}?&;y_ z>FMR^?djv?>ZS5hd%1bJdwFEWYMxoRZ)OxV&(dc00GzA`2E?mGv_{-tD3w=m+;(>1Y)Jyj}CI;15g#n29rGgfx!-f_)XF>D3b|>xwi@nv`ycbUaT7B29A% z@exSVVnQ6$9(4ezJzS8k3)BN#0a~uYp6pbB+)jckw?vQ;&rEAKF8~gy`)0q zhdu15ZD{F&^fI(fAj$**X!36pA#JBVY6zQf6JEQ=m4PPJB*YRy<#@Z%kAG;9)_;rH zZ+W_-PK&ht-_}1WPyT4r6|4pPYzYJdt$+}qH4qB40m6U~l{%(*aOPFuTRTfM zy{Ww-aI6$x{BDSPr8YR5hems@A@xlMOEgrjt&G|wvn|&JYn0o8a#|g9 zV6WBN*{rFFb*hd15Xzfu6vOUf-BVF11E0Xuv|!iMbdAqt!JHdf5g%hsl_J+9Tl6qWA7 zKci7mp#E4y?#Y|r6eix4?w@9ARayJQ^BtRpPH&D(u?xwr#tAERP+z6 zO}YXK=lobF7O(v#_1vNVPCL*3HuQ=)%v z9j%#;&N3Z*<{~~ZU8ZwSrqeGEop>{y1dDW3p~h6xHzA5A7!sMLOQT zbY>8q7At;eL>AX3nO?+z-0j!ROs~5|dakX6Gh&%e71S-owJi@Fy_rsuB|2Uqx?VDk zu`&(iz}&GI%ruOaXsBHM@kJApPNwrxrjwC}PO_O!4@-2s{qV6LQG~`pJJc(+*ULOK zQp_|`EzwZ9;}aY>pP|np$>P~1(~2IHyWLD?T4@$(c|c2>NT;eASzI+xzZ6$y9$G!k zw0c>hg|4f>`y-aI*9$J0OwE9}4 z-qX9p4Z$y`lf1o{sC4 zfQA&`wmkGQ%=Cs?q~{hc{0uf{cnGm&$h4|tcI&>Cr`HOdk#wP$#5gQ=^|lo%(SP=;z!G)c14*l1`;?O9}4?ifcyXAB^n#*Vc} zS4F{nC+V+?quowu*NZaEk$Gs2gT^m1&0j6j#PyKjhq8ihAhe`d=}l4d%cJqonIO}h zXpydm6sNQnnphrhrcBqAhwdckOqS_Ru}D|-onELWuDe{*8#+>~xAV}P3Jv-B;xtP% zRUUqrvGEJ$@5k;cnO5M4-0eEuOlyWkTCTx(lUA#d9ao)Dw-nR5JalH7>CCc7M-_nA zZ@=yNv@Z^l={VyJV)Jn_+e~MUMLKTMH{68rA?*u~WLksr(3)$eHO~?)?`B55Hs|;q zfqJEOd!2{Id^3#&mT0KeLL4}gOQEp`HH|?y4-)tBZ8FVhyn$`rh6~L!7g?f->y;Gz zQiO*l?9+8nw-npaJaiVD=`68G$3xT!qZ?m2?KoMc@?J zM)%@`YeMm+oVX7hlxcMto4Xy?nQ5)JM9U|lYl>02N)vTlQMVM+$vkv6aGi}<(`~g) zmguP5+N9w#sQ7%OmY*&N?KfSf<%(ZUnD5t{xt4Uku*DKBZ-3l1%sCgbLA_Eui}TRf zYNoNx5)HLFXRwPODKw_gVT@l3bd_lq!7o9~ z*V=_O_1A8Tw0xTDjjTBgTu@X}onQ=%!2u1qbs zZLRha4i)%{W1i)Ob7Af;rMDsN3ZH4AwRyknY>^j#`ClkhC}x&aSk$D~C_BB*^zWd+11- z>+;Y%YNmP25>1twZrA7Rd}udn^L{cd=LxyvJI=LEU`^xmq-9#-E%X39GBOFDwGrok znN~&~TBo?yX|8p~A}!Ytd_VTv#6>Yhpl+%Cp5~!*mg`7k6`*mts1IwE4bq4Ry=U@vmE?rIxNM z@S)~ZI!zVg8ZXoGo|Ieb2G`2Mn#M%7C0c4%YP+_HrmlHvewJyj%0u%e*Oc1wmSvhU zE#ZsQ!U=*DXEJo8Hg%euJI>o?ns+SGRH*|D^tI=pcs`4WZF*0pH4<8PQCCagcc2w; z54aCV@jXEL-^Yrlbe)0wYet$zzV%@!G^E&G<`LUN)Gr?|k1Wyi@i&^n@mXQq-Iv-h zQ>GI=C3hP>Hq-gT5*?K~#3(+jr{l&qts1Cbis@_~T2IWho?4=%cJ=RVz(<|q0;IPC zzSEp6(`-0Z!JeT`>bK_r_1g>JB_Q?NE2RIu-_%mS@v{=QryQw@v6VrA2C|sXO zC&tu%BV}4uX5@}ZVWwqmk(R4mMrga&GM%x|p=ZywKrq^f#)2Kv`2cAw*dzU~G5H9W zWZ(5sH0qYx?laO3sE77lNhd$@jxwDBmguO=ud78#YQKXrz2up>+pi$%m-kg6OZ3$0 z0Q{*6{00^0I3$JHDPA@{+@T}Icopfws8b$e5#);kQd<_YL{o)ltHMiwIk7F1>G#@76fYFixj@cf<~q$^)6-~a8xGEHs<>^atOcX$(@ zIbjQ%-I~x?707(&Z_Dp^-zFgcTbD3A(LZqmKf3QVaaK6e?&a}{_TS^|B6#{tvvKPp zdAiAXw_;H|U1H`6|F%3GzwuspJD%=8zoK7zo-P_u&bb3mKbz6w_l`Wht3j2A(MV?? zjJ?YCBRlc5>HVO`oq5{u{)lZ1Pj7C2m8T6&hmTI=>7fII-*rR!Dg1Pv z-k@!Fo^BN}qqLr<``jDkoW#@DGgAIA@O0{pN$ZU~{o&N#Hpx8w>3XBjJ$QP4(Sny# zc)DKEOYc&7dd#bBpG-Wx{6yjKG@hO~<>I2AJRR=dd|)r6|Aue()63hZOX;Qay7lJi zMn(VJ)(7b!uu1egy}d6_Zyho1KtG<|a^||4>iH8k1^P~ZNcB*<-PA3csUAv)_5S>d z>gk8{ru;^4s)y3?<-$)x0{NSBy5OYJviP-gCTT7~ zUzx+T484+66=nBxpULjljN5%1w81AScv)=5M-ZNdxQF8$h_@ASHHTGLdI)XxTxO?m zpRjafG=4LK_oyHveE6}E-^!)xNBFc4%2~il-b=GzM-=n7o57z{UhCv;lHP-z@3+I zy^1CuQ8n2}DJ|er1z6}aD3&T%FoO8-vdGNV~ zKl*4h?<2A+*SS{57T|WvxN6Vub{PeqtIEpu{W*B~FVLtg(|9{6uG?tzZ#3^WsxNf^ z+QirJZy;|M;%>MvuBQiATxPdEd(Y3Q;L6Fk(qmH^eFir|R%yJ z7W)VHnYenZ1G65$mjLcFagEk5bl-vc@E2Q!c!}FsFmiNH=<2zD#0}g$bXEk~kIC#R zg#Vn-nZ_>n1-}Yo%VK|N8VtL;+-Ktc@O{7aPDgxfMP}Dy*e2a0aMxs9_s-MD-a~y? zWo6x#?jPS4Tz{FJZr`)@oe=9h9xrLUT+plIGsIT9oEQgjVJ{l3wMMKe9xrjjR-Iqx zfP4cPx2xKfsm0KK6=h}rwp|d{7WGe&Y1ox?y*H2cBi;s7U+E*K))atlyX+j@Y3kRp zgW>a28P{gfeXo(=-paTpJ)HWNK-pLscP=XH({yOK$TS>3w_jfL8pEIB6*X|W%pRON zZ|!ph$9UdWMZuMO5_QF^6HZXL9dT9(g{+DoR>gI(EO9T5MQX3ac&@;?V&HaG8~Xg> zWqg^6*C%j=+YUK^zMLxKo*Mf6+8AY5aIQGY-u@%&LJ)iz$GH;Vc12!Y6a-(gxG%&V zT=qewgfEU;3|&S6>_-K z6PpGshuxE(a=1%7&)x6<*Ou2;7G=|7&i?WOV<pt1&0C@XTm@h#K)xS!du{w?1QHVW;J7K-|efs`xpmZ(oNTyW{?+ z<~o6+FH|eBB0ED*zamEvZ#fVWcXL>)2KZ~b>=^fj>~w**UJk?<>U%@9D-Uksz3K-G zLN`&yWtC~<%ryguS8Z@By0eCRHg*AqeJ`N# zNyaTaJ;karH2QE~s6O|_nZG)t-)h|u%c9BHy#j4h8o;ihjLUjZcuNBIqXE1=vYR$M z@TW3}Z3qG&Ux+JKqII)YC>sSr;tsy8;uio7Yc#OL9qXU=Mv3}7dH)hWZSCyTZHTQ5 z_m8*%nqWf$+Tby7Q{oD@zGd^O49*F-e-*(E`K!i``-s;~#*NrEso+8MM=~E9WEcP2 zkoFtE{l?=U&TYxFYthgs!2KicYxxF8A3(!__Yraa`-Zf1#12r7_eUjgJ=cw^?udL8 zuaCG5*JcjPLfOA$+`LzpCp||S1oN_$VfQ?3`E!SBI9EnTD3K>F;)L6lW3Y1sA#oW4 zZNB^rt_zQ?3hX@YIuCn~whxhU+0IpFyI@>+@wOtnWkm<~>JDxkI)~~buG*!U$?eQ6uMi-aA<7THw=W~CRfeT)1)u0h;a_58N(sBbhcOWfSW zHA;L&ebGGLYT(XS9(nBzxCj}y@K1-z3ba8SZv(P>p=_J@3FD%pj4M+n>GM96wN{G0 zkeyTTq`v3C6_;@yop!znkHmEd*QgG=$<60CX$h_xA8W*2`MT<;E8=kC?Lyp4mp_NB z26v8+7vf_22k2@cwrf0I;x=w(Gw-AA-ISs)#9hr~<5pl?)#VyB!1caf&N~HVP23ma z`j&LF*$j!5g}7xIX&E=5QClf$5ZAfJ&btGkafkatT&m9`{S1uV z5UyJjT;n}%3%Xz*Y$oFhIZb_W9Db;HACcYQMarl9z}1v-&u@1sUk_zJa1FA1bFPMU zDm1M4zCc`f?b1#U(f0m4wp!qBlrFpaH8jI3h&~hd_`t8rw!`idkBzt`I;V+qLUFw0 zWov`GaHD;>WypU9uSA}>pT-TUGzs}yI1iCH+b-I}w^3h1UbYVG($?Q^_zb!&xh`=- zN8Vb#9(I3mUE&^nxwWT3B+emuySRX3yP8~ij<&DJ+km(lJ%R(3=(ktA4T$rz365Ea zwy(g;)&;j_#=Gj>V5jH45VtDoR=Fjp?-=i2;;wb<^HK@Up8GO?xh?}0iUa<#ptmi%x7ZNtH_+RbtK|-!Ubv{cg@pu#L zh@(6q^xmA1;usruP?pLO_d2S>q)lNWC)xe9W~a9w;ysPINU|H>VB*d9=nvu~yTiA8 zYdn#E4k%HV8xWZBsP=C7Jed1Ooc>7v(}j_Do5{Fe#^o#75@kooxHEvKwrB-76K{Jj*rm*EFy;c<;4#-FZh3S)Na_ucAIJ_l3BZo}KPJ z#XcCw>m#mtSdnJM&_BLB4&q8VD+5PBqk_zC*R;Yl2BKXSa9y&S-XO@Ye_4zd-beMp z<(o9OOL4^8h{r)(n5yDTf=?vC92t@VQHe z9B%9B%DWmtw=1vjXVkaR_g%m$*tOyH5f^;#MYK0G9`O1af$JZ5;K6Cc(T>+g-2MZ@ z+lHgQ9_2+1;tmIgtyzfr3_K3v>;vKp?nK#NWt`9B7F(M_qahy~WapKTof(MzXiEjL zzQ*9JMm}7;5AE`aYY-Q{uTNYce6#DEV>i3;hdx8WMf3W|uHeKaoqvMAqRqbTeYnWGgY`)-}J8WFr* zsI2w+TIVXzn1p|{ANd1G^)?mUgSH}$_7CDDJ1ex6WcRGvy!9{O3vrTN`7_#XA!z&c zvikftRGMW4Ux+ieTOhORpnBDL66zyPvYS=3%a)q(uc%Bn>&2TP?S#N zs(v&K#|oKUp>`8aRY1R;;QbbW*op->U)Y0luGav?)(mKU?8||5`9zL1i2J-`Y>Uz; zdw`d14(`e2iyN9Cwtl=#1Hrj&DiCOhKpR*U)d5c=&c9~&*eZ49gOqA~KLxCU|cS7sQtp}yi3#InS7 zzxB0HY1sV5eI~Bos^8xBMcFknJD00jQ=32|n8!hO1FB5EQ}8_YSwM+=OW^EVhbJla z*ne+`TrfDdR~0HuK%alTC~~d9O&&e9qBHEGc-atex(zPliXl%>BHtR={%*gG3+$A< zK6C+lI;eO@1#Adp*9Q3PG`?v*&qjK_ngD< zViBkE9qNesk~kLw?%JV0J5)k_&pFox-0Gx4Cx3x|(VWwOvpN>A$_;kMITs7At&i8F z$(PXgdW zg?$V_ap7BcbGv@r`Uw6h(dRVo`vXOPGAQo07daaD#0`A1*#0TnAOmH|ZUC@otY@3^ zVIoI%#D)4UyR-oH)#77lAUMs-O|Q~W_7|=@2weWRmj|DO-5B^s^$i9Fwstp`>m+hi zA8`pYp3mF}y9-=*2)NQEyN!E?$$~htBW`26=^cuoowjg|q2Ssnhn!i8_M64WO9r_5 z;~(RB5%!6;qV6zo9edyUFb(k%NA(dm&hyHOJFxTP{tXBB_>U1QMumwS*%4Rm-u@*) z@UH;MDv=)nOmaCA?u@cgC`;T(;QW;dzfS`{m|?&U0`R^Mzs3{+_aF(_GxH8;>eD;Lepof8(hGC2`G{O z6{uY?dwA6wxYq^{Hy&sflmAK~jAsII6M*+sLw@l@IYJ=v69JbM^Dp)PQ{=)pM=$Ht zhs})hV%bUH2NoQ+#{=ACa8!0OKriF;Ls{a&I9L0(t-4ugmm1f_vQxnK$)BZ|Q)~e?K0{7JK`;3h+x{F?<#80NSz4&{g=|A<@hHF(|`*tN_OeVGle*sNhb3(-y)N|Bob zZsh&ew-eEqOSs)!aM|k$KCK;zIgXFDdEmxIstrd_-*N13q&pvYx2er`YxFO1q)VLZ zvUBgcpgtdzCA$Sc$=kCk7B4GuWJesmurw3?_En0$EClCUFDua%Wwl&)5jc7Y=@xXG za{m^Cn^EiPWhS+m>J_r!E3eau7nLQ=~$A$AEw;J3D{S%M*&?J!E8h~DWT7vvb zXOUYAZpNB@cB4^NQC{TMfr}|rd3*}mwEi`bTMuqw)638EeZ>6@&TRl!@k!ZHUf`N? zZX>u~{UeQ~!S&?aCUDn+JL~R$!1)~KHiJtxdM}=fv7zPM7I39q@;B&@aaEho2V22~ zd$!(c1-n;hYbEmAfL4#MzOD+p=iF{PIEO#yq;EzX`?%c>aGqONJ@1A%GA@f{cY=#( z-r^Ix0)0S<{4Su|p3RYIsILJC;&ubeo>x7w67>b5FNxa&&`V)GP~RNhR(ru6fAnEQ z5ol&}-Ar)T%5AD(kNU@R|Mr3N9lgHm9K^Ab+wBKeaD-pG?U*By0VVPWfF5IipL7EG zew;f9Zl86Nto_LM}mr zZLLK93{dM~heIvE?dRNCaIc~-S6v5gJ?F4Xu)jL*%MJ&Z%{f%d&JSp5^&7b5oI{ei z*FN5|FcRB2cM+UR`JRQG!JXh7h6D@SGI8ezRC1AX7)q?K^8w=!*qz0EphO;B&Gy_} z=`b1GUCzOrCHA|LHU``^&S9vt9i}sMc>D~h_bWpdN3p?V-j<}4@HepMl zv5f292ekrgV~hD5OiC`=1g(iN59Eq~v8*kD8DneVcR zs1mB1uvRRB>PaLDk?LX~oqpF$1;`2;Ut?`c1@klCZIc`wE7UlKZ;v@_ElXF4;T`~C9$hgyp**4qnc z`<>sb)kshxL5L(uBp`tVh$KQJ2$7&h5+ITYkpze&Y9tXNL5YM)Bq+c4x_s8&I|o9@ z{Q5%=JnPwOt-aRgdDhx%U(PU@4YX4@At#M z0PE`RB`@G!wRcVY0z$WjY*|vj+Uj#m>W%$#}4+_|&n%$s@J zEwk?k#TEA(GiTlTgV}feaORv@Kbk#v-mEz@e|F0qKb(+UpY?bHwar4Z) zZT74?ei-_6ptjp)-*w9!v;Uu2!P=rK&!{d=+p4;0+kSBO-FJi%YTLCb?bf^I-SPFWhSC(D z>+!SizIEOmp|o+D@bfvd=gkVGUnWO7jhr*uR-H*T^pn0m&zYranEB&bx7=d_61(LGch8v@%2XM%(Bigvv+tZW^NvuKB4*5- zIq%1F?*94AS^xLeS@)>HF!SfL=lvL2Z@Kj+Gw02@<I4#PtDV7!vMdL9xs#JD}Of-WUBGE)76pO_^6Z)Mmha>T58gwWe z3V$UnlOvk_6OK}^`aeMtb)<{Lt%jh0;QwXOH2KYJK!~saVyoDh@@{qA}88QjyTd!tpfK6zUDB{l;SS zj|$m=+NVmW3TQ^0LMoMrsnUF6s?Y9EOppl#`=T}cp>&uw#OTZKMMCj-T3UoSh1GUu znW)(fdDLFapM>6&9!^hJK>bAxq|#&TQpF+`i-)LBH7*>1SJ$95s7D}rKe?PPR&FV3aB#VjfFD9nG{OTBu1Hr zx0}^J@pwElJu5w?3L%FIMp`H1mPB^iV7}I}#7&>7@w#c^0P68}S0V=Ru@ zvsF*JxX}g1}dX% zs)cGR69Anzn1H9>oTjox!qN0dRy-{$9>evaP;Qt>0zR4%iG40To^fqPI{#gpk+|W{ zGyWnYo)MoyF*fFgGs3aYWvD-i8~7_uM?zVuI%>;Gn|e*wHJ|!ITKd%A_^qt0NHl9| zh9*=JC3C_Nie&R&A}c2+?BU$(P_7bOHROv*=v>tY0uokfm7o*h-~9BAp|lMCPRmHk z&ZdKEx}#%EJUYUvkIJfPOb%$oK&A;6_Au=+LsW2;rue~;!No%pTiZ|NFJ`>3%a~d93g9KI7y!V+%!uTFBRVHGpN+TL- zsVOFu$zWuHiC|ql65>qA%(aQ^L?V%`I<4}vnR4INehV?or{F|oU?n#W)y+~FmCiIc zSI@9&qZ%nHXyj#&F+f@d2L;+j2&kB_>DFfvHC3VFm3<;iA2e5`L8^`rW7PYT7ENa; zsJV_msxI#jDRm%J1KIpBn^lr1rt=T;iQbWhE~8MkoElwf!a!|$n;FWQnmhe-f0>pZ zz9+miV`)Z=<3e5}FE5g#Oc9?Ezb~9D&pQxF@Nejnf2D7UO^=%;TqMLIi}l-`Gxh3A zt(WJ9u4jRD>pk~)Ymc;0{7x2Uci$RXnDObEGdVq&J%_V_nX-6hz5IhaW`#rX+itt# zr*nTCYDrJKZO*J&p@IxncC+Tpx$Ewk6uw2T>Fd)u?O=uUZ~t@8tbe%W&RL;n(%lMn z_Fc2*%{J!=>Kudx?A*|{bXuc!G^tVo){9Dt{^+jI zqKr7Jr#Y;%w&f<~vZq;h-t#ZB=G_$9lXH!)oLNe#U50k$d^%+VO`NGa(R7)OKe&aZ zZFA1Gmn=E!t{;YW=Va=A{Oc`0n-!|d&DM#3nKhRf&kAkLWzEN0E~&%%Oz!6{S?jxKv?q6btvcb8q?4tk9O+kFf@4lL_J-v+tZeZ*FLNZuSrV z=dM3j%lO-8-#$B3pF2g;Kbs9PJM^r_%vOJH5ADd!l{|*IJ=BmpH9*b2{r1q#+{`so z!=Yq2u_U7~ZClQs%(|TN==|vF=#pqj^pWVYXmRxMXjyb+bXD|;=qu5K(T-?m^icG0 z^hmTz<5#0cqutS-=xfn~;n$;YM0=xeMvq1NqW#ggq6ebKqbH&R(YK=~ql3{?dfPi} zdzWpe**3(s_t@4R&5t%^?~ArZ3)A*R7o0p+r#+Omh|hz3R`4lHTbZ^h z?TNJ2Y2|5aNFT`Fn)XcEwzTbO^=Z$N-jUXjwlnRywCB@aNNXhhV%n~>rnF|2lTUlv z!L(P>I?_7%dtdYre;-ae0#bW;HElGlF19uHOl({1LfVH8f0TBAO!)b+i;mBW;Z=#j4gDyAoh^Mi(-WiFODsBxG46p!%Je1IJ_)Y>~Kl!QHLLkEqAyy_PE0DW;0z1W%9Fx&RVeieH^b}lv&`yh6n z^eD`Q*uwa_`1<&Ucvbw#_{MlOp9`^i{(dpOE8Y}uj_;1|iSLcK#9xZ(7$KQze#@~z|i}%I*<8Q@}$4|ru;%~=K#s}jE;_dNQ z;s@g$@y__E_&f1)dLJY4Md=Tv7p5;xSMJ=BzCFD)y)FIa^!@3trT3*@OwY@h&lp;t zu_5EZv?nt*X4GW7#+Iitp3c~ku{GlvKHD>%&8W}Vk+DCcJ>x*eD;aNQ^k*E)cq^kX z<9No2jDbM8laxC}nRhNx?(xhOnZ=o9nM*R4WCBHoG!=eRgZ2EpagMMxrD)DY&DDht6we;b{ z*~Ep!hl#xG`?Kd~FUVe){ZZm#;(W$vMt=4K*#+6Ewfmx-i9?CQi6e=w#H)#;iEirZ zNxYVLJ+Uu3kQhk3op>Srh4hpBy)XK!#QUUGyw4>@*giJ>LE^mKKB~6|(`s)YW`2}; zQAa5+>;A0#EasuCN3xb@J)Tv@f2*=qXH{ga%h~|HDQipCwyf=0_5Am2){d;_vYyX+ z0e*K@YgT*KD_IA#I2?jy`J@E*0HR@wZ!(^(g?KFsNB@mc%yx-kzvW zJV?v8C!Xcsy|KNSd+^V~oQ?6KoJVq0pEfc+9?#hqEz8-IQ=Rh!=&78IIji}%CTBy= zTK=uz^E96=d^YDilhc&FH}e_(eI^GdMz`nmq^tk7Wz3)QVA_Hys?NQ!2d3K0En5$LD!IFYtMh&n`Yqe46>}=JOJtm-+1HbAV4f zpI7)Cdcd#od4o?cpJROb_#EeRg3kb-lY9pGoZ|Bi zpLhA3<})@yDxe_pZU2ezbQ2Y%Flf; zcVTWp?nAkY*jmVEajq(_>VKHjlH4V^OLL1rkMJqxQ)1aia~}gO=Tpk(@!S<$Zd#eU z3j740)qKkNtmUKXsK~7ZJ)XNRcRl}Z;8T_RWNx+owO1q3vfKv>rbVu~ zFLLkHT{+i>l2d;&BXoV*-%bx*AN$^%wC_w0O`V>Y9=ahE0VcC==dX<0r+y|Ulx%!? z%Jk5Uk?dq-UNY_WsS7h^M86&hO^<#zC#3ic&7^%t<+~ByX1zTbBA1ZSsh|CBPB@{G znrBbRskdLc0m&x^r+g(8`Yu&=9?YQ18PV$^<1{$gGB9OoRmO~PGVkpvUys~4Jv=?~ z^~m(;;bhH)4AoMW``-+Gm4EL0dgLb4x$xAy%=mZ6sk<6xCv;?5DD>&;)24^Mml6}5 zZEAaBdU)#kjL&3-RP(cMSA_0HM8z>;;}}tKjNA~qK6G6;S=l#b>fy}mLdlhVQ<5uB z>E?uzwHhSL;Z%@lNJw|$NT%9<_cPxpBb(dJ=CtIH*?jh`DT-H{SDu)XBuRIZ**{T#leqoH$hCS~pO2@x zx2t-mc4Vd&nA&v-(&ipdrx6{Qq936PM5_s&tCl*hW=sqgtm> z@&Y=&nt5F`c@|Ad-qp>CCaW|^j(9pnld2O&r%U-HDmvAloH9L<95^{;YG-D$90eez z9?DD(!KWq52Q}Yve2OA8k1`}ZWk_gcC_|e(p2Y2{LZwVf0i{d|DY-91r#_di23Iot z%@9@^)#=_PiR7QDk=hSXZk*a4)wsM>?Nx07CCLUv-RVD>amg?y8;TOiC>1B`01P;6 z4yeBA_d=m>ae}gi#8WphuGN;kl6NOy*OsWw^E|2MEm51PLo&Sp(8XE+jjJX1K2p0@ zOYS!$cdO(c6y}I9=Y;7K=CpwPM{Mg4!@RILY}?RD>bcEf+rC~>OG;(`$4C{G%KlH0 z+U;__OKPvHWvNs?3axumCd@*BW;O^@EX;W_w|yur86marLuttZGQH^b_8_Syx3?lv z73I>(Wu(@XODmrsRW*&y&CoktNpk%(dN(7iG^!)1C0q^A88!k29+T2lq>eu(HNPOa zt0ng~K#Q(DqEy~Wa*wV(P1W8i`L|2{U4YIts`eQ%RiKgd!8NM>8F5wOh?HoO68iz| zdJpNUKpV;ZdJh>Yf1l((Ao-61sDLyjsiM0(Xa-G?cv#KL7Zro&R=BS5F#L#`@tf#gBGhp8%m zvE;uf`4_=#dsX>h#xzx+fb`Z^l@n%sOqEzIB?Y7Z)V35i{*ewDXc@-COW zYXO_|D4OwcmA#yFjUHn&KA}o%ml73HViRDy;pJ{1Pr*`?WB&o+$SV=hva@8(CB8D9#YS{nP*sX zzahC#0(QFG1EhAi+!rPHpyYlZuvxo6wfiior?dxDy9^%B z(Cd`%B=x#eeo%5Bk=(}syIf3qNj18doRi#rlKWl2R;TJ7AgYh`DcUVDV97>0Jb?zR+8H4 zG^vx^t0nhFD$>Ke3ZTdL3zDZ=@@xZaaW!rwRqJYOmE7AU_bw{Zjco+zqsS4-(w09LKh_;*w~Idy7l_6)r?UGP}q=E6Mw%;$68H`MuOvUGpw z#!%?%p>*&g`$Jy}g}xC|JgTtbPcD`UN$XT{x~r~;>K<3sEzs3PRk8K&NA#ieTJRI^ zM|5>l!H-#-0bXLU-OZ=jO=(~^q?EsyF}=Tcokc~tL4Rh?(Ct@`6s zT^XpFlrJDvRJ~MHZ33cuu;2~TY88+VUpLrRmrHfEf$B*4s@oc@PPg=#_q^&hS?sHB zXP`P#zUmr-)#=t%`dYWjVqbMFf$B*4s%r~Yr(5^Zkk`6h7W=B}3{*$TS6x@II^DVw zU+W%DZC!7mI#Rys`h(T!)-{~*TDR3=U+YcO>sSe?U99o=k0BRiHXjzUpd%)#=tfV5a~TyS(6Z zpklW*P#q~>b@jpObnD7}tt(4yU1Oj+Qoib%gVpKQb)WTOci3WI?Aij=k@8j79;{Bc zZl|wx+f!TD6{wDsuezRKb-H!W+HtC4w>3CsRqXl$)sga5HxR5&w{C&2br(}d#ZaI+ zQoicW2CLJptG44*wQhZI%&OL12vkSPH__*nrXEigyyqQHF4)ehD$d#-)?GBcT*GC4JqGlYJI1tW<=f59;BItp`hC0U@$IJ5x0|-q-82VwL&~?C zmf&u5Z+4vZdb7n2dexha7OUQ@4NeBCH|>Glkn-)OGq@Ywn@-TY@h zyCLPb~Fx;I;fyxwf|jhnT;akCxCfp0f?sk=EF z*bOP)ZbpK;(Y;x8#_P>|JE3j|sE(Ac)kBwP^^osiJYYw)8tuKl(cYCh+D8JrA?0iJg-f*h3M-WbEBuoODPOA# zRs<#w9qYrsR`2(ituDVrt1tNGqO-oa z=#+0R>Q9}Essg(q7;6 zZoWjTuW-`S7O0MtFV^jsX!ZNP!^^wA!^?5s;pO$znX)Ue8&bYj_gtdYS2*+Q4^&6W z*Xn^ww7SRF>P}y)+kCBVPHpv2U^k?Etv-8+R$t-t_d=jLQodH_m8FixeZIrRF5lr| zhwpH)CG~JoQ05=>q?Q>IR__UbzBb+g(ATYpWmBIpg90uB)WZYGc0lPX z5qnqhAgL9vn8i#e*+c5RL;4ad4-dRS>a0moZh+K*y>b`(B&k>S${p^)mA3M;(7W{Q z$~>rMjh2Hl^!=}uiJSLS9$L|Svg66!AujkPOW33u&a#z`WXHe5MdDI8@2c)f%8b3- z`rbM3a_h-+-sRR~7TdMM$CFhQ?%cEdwUW7j*!JWm`Mo*bx_c zQvF9H^aG@Hyod!AC5XgXC}qSMVf84-2(1WS9S$e!o-s?$boIoP#rC18Tq;muyu6FU zxRagHI(>~?c~d>ZbV9UwTNoR#7HjbvlLKAvN6Mdm8d^E}n zjb~i$#U72%9F4&wH{NzM4iuWv;Aq@yX}Zk7(Ou3SzsuRC%M1#sk)h{mWE^=llK6V$ zb4I$)szIK&$`0}cs}eUqGUk54+sn;k8EP5%=5o)#uUc#kJS|y7;of~sk8Npq{ylBQ zidELYr2y~gn-!$Ir*En#Wer@VOVvWW`@x4#_O-ryUK34HO&LJ@w?RNX;K_Y5%y*Eg z-e-q7-DB`5V>Lr-XX<&Zh3XfNxw`$joi{S*;^9Mq8#&p@c8XUlcH@B5y2UaMPLMJK z380(S4ai>*{uV=XST?>U8wUWsVUwe$kh7596f#2d9`h8?%j3#!)1)ah?+J@lQy;U~ zD)31eMB&Sg3^f$gAX;S{l{3Dha_k^lCDuvOUFWDCkEYL#CR)~L+E`C;uU5?m3!X^a zyxi*+r#|8210%*vx!{l7%ot9-?`FoZis`44MHH@ic3|zc6X&e4o)BXJe8wW>GZv-J zYa3N=HO7MY@T1Q6)@@&wXJ*DGsizE}v<3bZBN7H$sD|~dRM;H3&JdeKUa|xc8N-(3VoADv^)mrT`mQNn=RnJ6V zt7i}}tLPZzjvu336C)-XuP9FWEH%I}jVhZDh|NzSZgBn#C%ySI?3+KsNpJqtHlLOp zp>V+Fg{!U2^8lXB=acemUbK3Q%}XJIHm{a?@&VfB6#~iuYup67mQ+P>0{s}CtAX|= z&|2#Et>v|W2kfM&?p*W*C(s<8^zl!iJ4ksG=mAn@ya9C6ngDhJ?Us$ZWn(+QH@c?k z3A6{&H@;}zuX_TeVcI)W$M?=uJHA$ncan71nZ4Pg>9eDWmUWtT)@nO}o}ycmcNT?% z&MFsY0esFP<#Sf~SZ6_uahBAR576>$2WUYngsB0TrDc%eADurDZ)SpTyJf zUo(^^a0{(?bj$==dfH5sIry*GVl{ylT5OMy*GzN*rKMWnY2yn#%}x&GB3Y8|J0=QVnOcMOh22B-L~#Bu~nc z(rtVKplezS@D>#1q`bw(c2Z_|N$w_LY5-=TQV;SCp^xiXvKi7hi0I?5dlf>T zzCk{22hkcaNRm!EN7E~DbhVErDwd}5WcwPi58ax)eJC8X4{-2z|9y zyWA|veBi2Qv`h6&9FAs!ur!k=nyV!woSgyd*IEnjM7T*G=vycpuy8k~&=zh7cosgW z?BgulOR0c`2Oxq6`cbK;1E3ANu)+(+43eai&NuYR*~v!}6-%obu)ad;v%GM}^n352b?k zff!>Ssiy;A>{DrF92VvRz^GR&+lHV#<;s83)zFLbw$ZujUWAB_Pd_jVtR=Y__M&QpvJp|93zmzx2Z z4_x((cB!6;!_iC-miA^qI6DKDS6T~KBHW~Bz*-6iEZl@Cw1w*do`rWP`#1}?P%2>I zc8H*b`=p)*fVS{yfd2kKw=i9RitRE39woJIyUc+7q&B!U;3-m@&xEvj__h}*-NttS zy6!Uo&+9{^ym7E_oeUkxT`bH67&C?npnSvQQ+ft0f%FZKb^kvMkacE&d}{mw@+mt& z)`>xqbkg~TUO7AY#tl)iw3-3S*NJ`T*4P=a@YV2_)YJLuQsV-PGr$+R3~z5kd@5N> z;h=p8nXwPRXCD<_&pwn2+6Q8ceWacSfUyriAIQ3e=?56~MrB(Uz*GJxDW5Ay`6RxU z8Sny>Cve{SU%$Y#RGawP@ddut2t4EoeA*{49T$Q7d^DXGy2(e^dvvvr#sHFgwU5U0 zLNiR9rx+hXU#-_+x%nku`-A4hwzzdMR0kR=* zzgAz$-2H~R7O%b@^ZXm$wfJoo%l%qLo2ux#E8T3NWqN>odi(+MX*)pHi$Rif()os7 zIXn4iqGD+^0~Tx$`_Qe)+lRtI`)m;V0DSf#<+Bf^g7$$JV;`xf0$}U|&@wg&(*`i= z^~ttIMLFenk@C4hrIgr=CMx<2n)E|?0uRs%-wpX+i@>y03#?w7aha)Mdi2Yo&lrKb zHi%@&BO5${>9`2o>Z9qr(A7S=+@p(qGzO5|3w<=67aB7%-`%jd3(@(4>bIS~HI)P1oTJVajRJ*+Y$Bj7B$ zPkIF8RgD<|#Z`6$6ac&tu!xj50!k?r7y;!F!4XhM0d4$R^=J(5xEP9F=G{2S2D0X_ z)VGoAq*ROApPt%kL8sg;=`Ez*b+@GVlG1~!L%?$YwOb}MHbnG1*a>%&ds?H5rdFy; z>JRd{k7q_$8hy}c=E3RU_ZrPScrEyCi>HF$v{)^rUbWaRrEZY z&D6suVu#PAvWC7KikRU;48&D*)VXS>M-w?m6DKhnZwaZwWvBFWPu~m;M%9ejTg7)_ z)$Qqi0ub~|#CP8=;=6Ab@!hwhP2UVnOAb*u@Z3ZGlh!XIMA`Gpc~YKV3Z5ME+(Qw> zA$4>5!TF>5eszUZGin7)Zidm?mI1VrDgkD~Y>;iGfCb0pBxD7t2an51NG+*0Jz;7u zsIR&1gz}uwNF$yav+|+*`>U56H4ku&KU3WXbOEqxT!vM-0xM#u+fW--7Rp+dIh z0T#Kp$jm3T*u6!jl$1GgY9pkfOC^+NgsP2+n>UUz!q#=#RUzJdm8@B39_CU;sI*ua zVWq{&2qhLPBP_Pq8sWDmIz7-EZ3JFaKb{fNj1lOTC{Bo+;si%%V(DlClxhS>F+%M| zYlN)?W75+@BZalP?|fjMUg;pv+7vASZ+h6LByp#dU6cwOPI@7XPgdBcSB9mYR)99a zMS!-&pfG0v#ukOucH02drV@F%&Ph_WCFTh)p8O<}&lWLMS`6jcqNqBNa-=9;6VYEN zS5_!oV{D+6w%-z<5@O87t5g(VVb2%?XIm#Lv+L zCDjU$VujLbYlW2rVA58oqHw?p4Fp$Pp%&m-VT+Q%S)q|q0V}jX1g+35_0$2h6;1%O z6*`3J0hp@`!?LX%FtALlaFEo=WnzT^Qa&rhQRys{UR#?-JZZ%;HAA>p7=)9{>dg$H zBwtkTNj~3VE4g~8M4voe=`cV`wdC>fC661)X|iZb_no$MTxjCtXgZ%NIiyIQS7Rk# zQ1ic#yokb&7j&Iz-+gMx9Mx;AM7V4P8!JzpR$tY0lZN@pOiPsi=Il{tcr{rEPF{yUJ9|VR9Rd6Oa z$+rWv1kp*ErDWBvSsMHMQP53ReV(pl9z@k-Vl&cAU z{wi<6KflsoHTut3tS0=E7TeK3W1?1|2igi5<69xaSb?sH=7hyrfq)22{2WbCQmp_f zR%n09j{Z&pFlj6FQaEsGFiddugg*fAtZ-7v;3oVLO4&!EYqb^fHYIKzRjbOLC(Nlq z@g`f%AO*D(R>No~6aq9;0x(XfmTd)qH}{JZ7Ln@PFHR^Yxe7V2pJ|`J?ind?Z==s5~eiNfucg;*F)Gz`0JH}dZnmx%7UlxL zxT09L4MBalNL+D-)Wt>OiUKnE=7%gqDuMD`QMx(R6(8>MP8dflR<0PbSh-@rV&#fn ziQWFtnpouWn4kGM1Df#^n6H7-Epj1~tiYv-DTUS&PjIplp9{;_< zWrSJ^2QIue5oqm-dVn`q>`;=pxuS(qfyH4vgg*9+$W!ipQcnXw+u}4pPZr(6^aIR! z!l-QP0#w{Dwm3>^-Th*VAyPhDsPF$=fbv!fd9{g~OUEn@-&yS)9^SH8N&cF}R&sS8 zYeEwNE!C3CcY!W*<%mA3YXme|w59t_TRJW@adI@BPn8@}BrmA7k}syCla{=c!bkS* zQs34x6G3&YmAo9_NxqhpCwVQU>_kwn4-fSa`hvllLVIf1D)m$VwB$zsTJk1g+5r3Y z<-|VO)(CiWw@AK=RNroqyo;1ia=!kS?1%DZf&p6bNQZbaqN-~N)i1FPnN z69%ej;0*)SEO5j?<%k0YT0?wkqK2R!dUx_osmmC`ep8ALiSh);DNk60CW?+GG^vJw z6hjP&AX=`rht;-{@43ILuV7LoD{QA(-6k)a%7!?AL;@-Rn+I;o}*p#AUy zK>MLun5_Ua1+>bxDnP$GKio*_xH~^=B<1r1-(^a+L3w^?rxEMM_~F4yGX?wxBHwSZ zvcU%x-qi4(#mWe8TWp>1g^46XO2INxZFO>`po)~w3F<3PTcJEB)YFKXF;3Xl8`T$$ z)YP!4*DRLQ+_2ta<%%aPRSUL6)XzhwFfai*%N)qRa0ZIktharghhgWWW zqO=DcKcA1$6ehZaXTC7}AVzF|?VvCh47FeuYaUpm<@w*ds1-;R(kS~H=#ufI9 zV0265Cqzzuf+IAsbTk1iiqK05h+7fObWnFsA^<75Q83wqB?+#j=VxM(S*_tRhB8`CP#lxRMJf z=Peuywx%u|cl$0RKWDL0{27bwJTT#fBQ4d6%h$IqqqzP07EKmu>AsVejtfnk98Kp_ z6^9hXi?&+DOX%pN6)&f7;6id8LDY&@0X)SwlJXRlBnX5e(6av3H-h*LwF9HrJX-K@I*5 z7OTO(+G1se%4A=o`-OFEUpc8>F6MfR=wRK+9hz%uawA@g1_Q7VvPf90#_L zT3Rf}ffiCe`PHTWPN>F^_w)hH*rE;u1$^!^PamAm*UylJZbI8L`Q~!Mjo_0OtAoNZ zi9_eHL3^`~iEP(77dD)4q@|w_U~;_RDSbQ4B!5oB@cG&;-`eL@U)7 zkm8HpXY3TwPhciJMGR3ma8StKW<4@O_`NCOywb-V6biPvgMzvASOgJ#DnY6lrJ%OR zW*BXeGJs|(0cM71kZq-a!|tH4f>f6~DAbbjS%mMaC3ix3Gejee*q|KZdp_m7y`lVh zR35fiIbqOZ<%B+ql@q!xwodrsM4dnnv=ii8Y?pC@{T3Tt5y=UQlbnDEUE!k%N~#ke z#R)CjtP|P@z@(kfMd4?5zWs9Zi;d)>aASIiYHM z>gC1*_L8Bx2))l@H9zdKSh-?{#mW_1ELN`AXt8z0gfBwV8|@1D>f2>pVZZuDw?uwI zJuqoQibU-F_WqB&u4niCMAiJzkhN~#qg#R{eM)(R^Lz@)8EMd5NYLl`SG5L|7AT7YMT zEu=gvG*T*Hg%${2JH_))BljCCbW1&T0Bwa60Bwa1VR`_@3d6Fk9k5`zEGG_xNB?dvR*XN3`3G4^7^D~H4GV#7;^&1yo;5HDJ+W{77kR{r9+mgrB2oc;tyXkzJT0+ebCNU=rUv(^?1p8a3gqKLwQiwzae zT3eI?yyM0SQr>Z+ic*2o%328ZaN9c{d}!b2B-NAwv?~q(v@05fX$BZqbj!ASz@~+A zTDgN%?Ls-NY$xS&1>bf`_CR^A=%o>3FGjxjyqOf##mJo&D<^EVSUI7_V&#NNi>(tT zd@+(9XeY>bpf2MC`yD8{B9appCpiHTy2(cqlvF1`iW3IJ38x6aq$h|G3ft>NW(85W z!#W`k;5lJFDbEQ-JI0)DmO`9TZ>AeMe^H-+R7*Aa0PTeB0PTbdVQK*8Hbs+cD+g4( zEKXQUYTe7?gnCjwC#Y)z%}|~bT4+SYn6>1=0&}*h){?CS-l3w&V&#MeiC; z+X?_%+*!pUQd`|wML8*-6Zrm5vIfe#)Kp6&Rx2m?9$;JYlu`dvsJzf(rT)bl!z=aA zS!~t+{6y8K)mnY|CeUTnx8DS!`64r+a557Fp^2HJ2}G*;kfMHlgH?Ygou0J%Effx% zQ+5+jt$sVeQ~#g}y;HxJQh_sx0f@&IKGpyJg^$b;VN|N=0BEfj?zHL;3v&TrjtIrF zZ3yZE_c+TLQlsv1mI5;Q9%oTs4Jv{1=7G|ksb>-kUok4HGl}^YPY0iG_vVB%7Aser zv{<>~n8nr=6F!rmH`*2Q^`XnS!hU^-Zi)Pa$jMJ|geI1bCP1mKfD~7h@3gL{Bp72| zG2zEqYAGCWMH7M6uBZoi%f}t0yyasHr2?*KhX}Z$PpWAEXjhyD=sBTVn0|nn6GmlQ z7vMqn*!xjZ1@5u;AyU3M;j_5n0+i>9yysF~@p8BKI7^Gg$`y?kt2INt#mW`67Asd& zS$wswpf}nT>h+xCeE;FI_Spu{6@CX(b44ws0;|V*h|`se7w}|^nJZeQnhJn+#SwsZMUyaX0Q+cz zY-?1MTRrX~)$Uf0U8H=j_#Ce2hw@x8KqJOJ`quNJ=ZYg1D_0z_Sh-@a#mW^gSgc&J z-QuftMc;GA73!sf?L zh5()|&L~OT!XoblXAAS{-~tGqkzKTD=>zs@hZk%$!xYr6*Z`wlQ4G+`N`RRx>SS9H zpx`Yz!B|FW(OYtYQANtPu=q_}u@%a5MLmre>x%82o-4LktX#3tV&#gp7Ase*uvocb znZ;M@3VNem@tfnj;x~;e=$6P&h@AWcN9ZyiO@LBe0V%F%e8IY+nP7}{#e^3Y?G!ez zG9NmrCyPD;tzFRt@P0t}C@Js9g$F3bcPRDa4Z742gn1r+(Ie)%RDPqar<;=61WRGG zEk=b|0Ap-XCfi2Xw#OYq&Xa0!$B-g2`D~$13RXgSwkU5*wM9*w zTdZuc)M90eg%)3}E$EH5#plPj#pjJJ=$7bDh@345j?l!?(F7>f7La0#szz&z8iFxt zThvoHV2f4)t!>c=@NBV*lxK@}N(F4u1!1mSKV)q&DD^Y}v@Om7v@QCCIR!Asko*_z zwqB@LkI0qlW2Cx|$d&66QoduzbZoJJa-J;;UQE3lv8K(t9I>L!JM~y*v9iJ+_Ty2FafOp*3NXk2I)Ke;OIie9_McwhX$LrSH2WUH_o@#)$!W#f>g;rrY0p^T! zP`0%Ie&z0M?IU&0-P`IV<+H+dSm6|ucRgZ=Rs>(!$a~T4+enn;@4L5=gp=>Ow~>TZ z^W2-kuk?jFTB;?#ZhXnFGm_I}(U$HzZRxns#L3ZgK2>r^k$glXzd%PPEqTGNF=v}) zyR76z08jE|q&&&XDHS-csDjY9L?2yfmI@70O))?#z89bsuM=h`z#J1gWLquZp*&eC zY#~*cCrgDEQa;7i9i>jF-jMg`1FdLRm!Q-y65MAVeHeZqoNNzGZBCz|zb^7ml+qU$ z^^0aMb#)-3-s;bb6m}VDXN)iH3?nUV6AkI7(~uqtO+Xw?FH@z36lr^R*;mi>)1jcW zSMdV$Aqoe+0g>Nir5zz`yQbMU=AKt!ou+NfFIYE?8Oucw_GeV=Sgw#-Mk%P3-3+6Z zEdyw#5@5!1gKR4We7H=MT|w&NGEugcluubTfUm^qq2q>2wI z;L1;dyr`<0Im6Gzwe*-F2LN$5=yQ-NJ8l}JQ znWiE8YYtyQ=Ru2a1ov62R({v4f~UELKifYO!*{LW`{vZkVVO=z(^^7shwO7mO3~c8j)2!r~++ zAmRk#=V*eG>I6t}Lg{Yngp~wf(oU$NaNyo_1Hsi!s0DaV*rH@`PH3c5zzHo7feQxR zQcWE|JK+RCJE23E9)NMeuxx7w?0rd20S=OS=_NS@7$D_y!fzqcSt!p5BQ#>H6XyGz zaNZs(loQVQjvFT}R!%r(@zpwk9%v{0*7#2NE#m~bB9appCpiHTn)o@IprkqhQk;;t z$2wubp8tgtiYOd#Ld72Igi?U#gcYPbCsa`?;DlO;fD@XenlgZP!U2GGLW3~P0ON#i z*;Wtuz`b2%2dPo_c9nKgJ|}z;C-gw|dWVf(T5*`8hJQUcR2WVk_SS>{A%px%>p_~N zrTyag(tgoMOWQ<4`sp;Jhe8t&N7KtxX(2`00i@M02{}cFf`dGq^sfK#C2;pW>9Fs6 z()yf+AH<<>V7f2dYo*NtcsG{jlk#pX743D>nyZ4P5F7PZpca^=ezjDS575$X2WV+4 zgsA}-X`5tQIiTPXSrD!zwdfI95Z06ONqZwAHA4+~(zeiw6G~e3q_9? zG*M}3l9u+y@uj`dNK4y9L;C47q=!Ni5J%I?RB0ha+V;Ix+DG^vA;EmdoDz0w+9-&lV)aJFgQEOLw#Vxj;K}u?ESHoy+3jvxb0T^woWm^HD z=3&ux5vffNi?-#YeA=q7qt-zAw5_EXW3??kI5}-;lGgT1<7@jRqb+R{5$UHBksb<7 zKpagkQ?-Q@ZR=aCwma$2q_u6Ka6sE`qNTNM2YA{ZRB?6M_EIXK?Er+Gk*&6)Qcnj! zE4lC`tL?Bb7XU`vV%atXHRN7-bB5Fz_sW|BGWoRqZL}?c;{02F$+Gk%Uc;is?ILg7 z*6a!;_j%*?Zzei!X_D6Vx5wA^w~e;6O+=)hPDFYrGy!omy-d{>QnW39$!c3khbFCU zErkQxHW4kYZ9Tx#c87|q)3$|D0d3nMg4*^;Jq-Y@?P-7>x81_@1B|w#vaJj7s|RJ= z9wl||K^eD0qU~z*a)77pT2h|2wUi2ITMrS`wpHq>0BCKG0JOGE z!n6U*8F-&;YXpq0m&bs2k@|4Ge5pKH)SZ1CB{st@N zt;@_UxtqW>7OS)IN{iLm_)3e_%Dcp3bq==JVzu&KV6k0!e@o_qD_yano7yj59^Wrt zHh!VMVhm#Ej6u|dCdiH^a;biS6u%7N7yaJTvji#Vm#es9lh^8$H;;`Mw_3jx06f1e zBIWs|lv4H`nLYaUTsee!@73E&%;-&c%Ql$v`l>aoybi^6VkMtj*RlOi68p4KUgY#Q@E$1lSw+vaJYkagUsj zFC%royLeYc%4Y@jJ@Ktjo)zk8Ma38^Jbl(&nNe2Qc-Ffzv({o|g%uVnD=f3vTH$(j zGIb)~N3Cl!R`}iVt?;|X3Uoy@CoE2L0wOf=b2LFowF0DAp|QkBGi@g*^%Reg20vNL@D3fg? zYV(+| zFb9YZ*;WhK?r!dFA@!_VAGDD2J;|kB8PEyk9U!`B#n=b@PWG5Jf%@jaTNW!@yk@bo z#UYE8Enc=**3)X3(%ncS9#zK&-yQ!44;xpgcO&0#u~Pg4 z_Y>**O7}H#+_=&?BQ4d6|Ka$G|DjQwCX2Lm-$_fyg(gmprt_(aLyF=p?N;$NIyz~^ zyC@t`e2^gO<3=yQQ~a0;w_6enQ7UlU7=Z{VUigZwrjLSJ-{mk`@qB=076Xjp6|yZ4 zQ0LxTGoREm?!7geNoA<_rj!D-^vN2KG0!WBoA;JJd~!>{!L?nXZ$#8@t5BDU6^JZ@ z(PS-|J$r1WL@;U$eEX=mnh>6|za^pU@r?Uj340@?k-~wfbx^mCS_|OJW3s;9N9ycj zvcB%3RABn-g*bQNqfUNg#4MzSrJ7cN?$||uj@qCwX94DDTX@iJ8-RMnooJsV)!|OG z^T^~ICtt{K@gsV7^R#7-`qTN7n zwG(Oq-uT&~WN_oBkx~ICv_P0Mtq1IZv|H+_186Ip0B9?82-5>FRv4CT?SN{xranmO zDYvE`Amy{d*HGy!lxKwzS~2!O+GyYSs1BqJ7OMkkoyF=vT5Yi!Hx(AEaZ_gT)gDOc zjkd+t#<#`Sj4kMv=ue28{sc#8V(DlClxhn|u|-~owZ(#t|Aj4zC>)p|Dmtt!N&%iN zR*>>+QAMf1rQ2GFJ*W1cKCt3-GeI;-HDv(piUR=ciUwht0cLsCE!*k=+jh&D)(%qj zyX8!)os@5R^>tj)1Le7*mqwJ2nII0o?p<=(Z?RH;kHt#;=PkDCPoLYt+1lb#etC>*$OU)X8Y&jWZTWAjOQCu2pO zV(4!PIHt|fJ3nH-erN%TBi|U`Bi}F{p^st);^oXhq=Y80jwV{E9)T2(w0GJWqLaW(+9SOb4jed! ziMl>;3;?_t;-u2Y9XLiP6__FN4vqcknc_pXo0NH6HmRbpGg7;}PYT_bpa_dDmj)m*W;I zzr1d-^2=e1m0$K-Z2j`b6ZH$-)PDJ+@%{2g#xL|&j6v+2F^HPb1liFdux{fzQT5N4G;S2rrM%&_>nDwI0?JdvTYQ zya3?M1dB*{GeIe(?D4_;*kw6{In2EIkiGdY^%MfMO!UqU?qiyjgs5Fwc9?@MA@shnqdlRS8RaMt|$g* zW+lK(1a-2l2(ZWf^w}~}E$*k!sz~`<@u#?AE0pJodKxkIr_ZX(^|NOBrIHop=2)Se zP-d}mLb1haf+)1u9uw4804Fp-&;#v+KONr*e`=gSS448c;+#N0geHEDCMc;+fD|V* zzG|J&OaLbBgmwxCE=lweT^LK8nn6O>dZK#CKpj#?+w5P(TL zp`OBlZ)mgRSs4@xyn0PTcx0PTc6VNL;z6Y{(5 zwqB?W?s4E_q@Hw-1CNmMU7Y$hPFO%WZ*fr2ow_)9&W>@lIN0VJ`v7>IkA%yb9nczLAut zcs->8i-Sgp;NqY|>Zt~3$=?8I$yRacyhPB%|l%(Snf8@2$?;9T%bfSY*+F9=YpOwXIEuCHf%)z zFKo+5d0{K3RN(BY3gRW+w)$kB{2W+=)Kd)5J=+V=VXG5nC%}ZQL$=idwz>PETS(Qr z`=KqQd~@b^7%81lzK5&3XvS%E*6sVk%Li|TlBc}~X6}~5;guekp-Fm3d}sV2@f|ZH zXq$MSemd{dL!k+Xqv>VpkbsmS(c5DmnCYiOlh$^K!htjA{MW3uBZSS<_PmO#n*4LzL{Qrbsb`duTHDPqTH7*!W-0+j+XmTI3Ygz7Lt+J~1^qH4YDxLDO`_6HD9`1M zwBiXRt?yoU!As^C_(^8L`4+2V;Q1EAt7G69i|sK`y*p__t07vg0pm zBM|n!w|Q@B;p?`VJ_>5Bm&0iF^8uP!3^3|f$hJJdo9=Sjd{TYxa#|@VpZYf=QYDn9 ze%0%#?>4AkVJ@eswQ%hUqqtJP%3`H{xy4p}^=^Zy6L}_NjrufSWF{0& zW`ZCzF>^G5NL3$F)USQrs=t*^k9{U~mAy}|exqf%yJxT8+A$^BNCEqtyZMcl4uYr^ zZvm{Ams#v1Q6(?4=%S4NmET31_UhA~UI_i$;rllin$zQ9sihU5<-G{df)5IF7GMM~ ze8X-VfO^lpnC2v@VfSL1JTmzN|8sO%4CO6iAfBvt5stY?6fZ~glhsB{*}v%(0i7<_1pC|PctV}^ja&F0=B*?r>84OZF^NtPpc>u_}!*j2=lv5+w82+B=wX5 zv=t5jv=thJX$F{!X5F%_94BF2yW`9MT_ZnT5uFK(lb?VHP5c~9P*UZG z6!`~4{!;|tstySw6bSrmSK*sh{yc#9vt9E^c|Y4#^d|Q@%@6PF)(3@B2=l9LXBL@* zLbcSB576>&2Wa^#gsB0TnV?Cwl>^@C6w|FGb-GhbS5L|}6Z|F0G(&l-fEHRY_A>e5 zr_JQA&V&zGtVa1>i|r^^XTlSbnU-pq|8jhp|I)}zlSNOu@ARbOLK7!P)A>}HAw}l) zH|;3zq@!bH9(R=YQotOvPY-Irh6$XW@CN|iw_#3_^1cl-LaBhvdB?`eTzt&dGe}7- z^J*9^b0I)8B>;P?UA7efo_C{s5vfKu%F9XlM)_Z%ObwJb%4=!GrZJ%D=R!;v9-d4f2Fhfn6biNjc#vF+;36ayE;0R4D9Zi5z zZ2>8^DDShjs3aJZwnZ(41GZ=)(ApOD0M8aXlqAj;EtCq_q8%b=i$1BR0ibPh8lY#3 zZejWX=AbYt+qwXooGp%$s&%#)BIUEi_prqUDDR+<*U!~@HCy;D3~YbSTqsxaZ+^}@ zJJ?{cl7F?uR(|zs4HG&$pw;>S@xAfo|DKVb=8MjR!s$#9geGQ=CJ?FeLyG(b{Z{_P zbb8YAmr^)zc2M1KlJP<;@BMv|{YpLACu|40U#}-eNT?JYli2#bXw$ zSz(FA$`%h=Y;7^&Co1TTw#DC!Z;QV%wxC<0KOu7Z6C9z5rK1T@sx2VJ7DHl-vjk(T zEhhX#Mc!Lut``-*Wo=Oa@E+-0M9O=lvy@VSS)m-l{`|YOMV-`B2++280ibPBEzDMc zy}d5mssPWr3q~7BHMk2#jih|D!rx+xHYjgaXr~opmx>=f?kyG1S*#>KZLyVn!Z%G? z-!hW_?f8=at&yB2i?(#%X-mh2CQgo~^Qn?UisW5y*_oh+juv~5GR zf*%_(KkAzSUShHRQQwaz2PpjV%$K7J{ zfG$-4p_;&-0&{jycHGu8Oi3;I1{f`QF+ejb0Y>sV*;WMTaNm(zM(U9Jj$9Qf{Z$%n zgHX}mA^BD)Px5+NQL5VDI}mL1y}o*r@AcK|gRifi@XvVDQa#H5ZhXoA&PYy^MO(V> zw58)h6DLR0`BcdvMe@euR`O;#I(C##_#v8h3I~2otB)XR$-4mFaz&TL))f<863`p% zihmg275`vdLAOMHLgeHpI6@OkM-!k_S3rs@iUzDJN(jbSS4?DBq;QHzx=4qB{ivCm>pj)CpA#(Z?9HEJ&qX|%|Eg;1fBVvmS1Y@i%CVUJjc-swoGg*|qZEaBm zcz%m48;-6B)Csc_U}lRB*;Wgvb+*_-YKyZ) z3n`y1)T`|~p}b{77p?F`LO*-Epu$WxO7aV9&CH=BKWnj-d>WNa=$w(3YRUg;e98aG zNKTVQTe|PGrQ<>qCr8uyRLLPl^4_=YOwb?fs9q^fSn?qX2QC@ppR|&X5KZs+aGsQR zd?+|MW+o_tFxQcn*^`3`sb`duTJp^>TJkc0W-0+@CTNgtrHXo84iGCyHNP$gh+0xU z$^RLZc0y^%^?M~6X+@D*Hn^2yBsu70jwJh>%=*UaRFU~gkBrbdE%QH*FY`YenQ5lz zNtd0TbXI6$<7hgZDl??W+;Y-BGSWupe11met9Tr!i^BGYlg)%bNZ|B@-wW_$K1Rxu zd5BVh34a8FH)gc&KDETkTsUa!>7%3;bvcZdIUk^z#Q-C7g>1_MEL|cp&nNZB5|O!- zly7zTFQ`-r)fjT`N2nU)nJ}eu0iXNKPhISP#au}K8ew_K;+w!PT6`n;S&P+?;AxB1 zk>E*-)wHn2Vl^#1Zn2#f)MLF9nilA$_RGJF@0Wiuexbi&3}WYuLDYmM$c`p*seXYJ zztj%eX<;it3i{2MTDvv;aK6>{D8~BS9CX0)FX**rMOdCDX#N)YA&k z?zjlhei;RKc)>*9NUuCh9|51yr{1bk}h*oR)|8;!%|JBG(^F?Pu;dCYlLK8Db6Nps#Aw~Yu zQ&#?!bb8YAS5Y`1e**#4^49`9`M0RhJNX+a6_CFLVwlNd|LLW6y6BdA>Hu2)696rL zhcG<=Bmb~$YX^Mbem~_PsZsa)DFdW@^8Xw1pM~<)ha5|pEkw{3O;S%8K-=N~K-;20m}Y=^ z6tl(lfybg#!;8 z7QSmG&jWap&nM+cUi9u5$x9*Z;|g{rsFr&20b26y04;fiFf{;kO3)U3|}sVC)IAF5wBXom7;f)-ja_MXB6eMV+=0U^&~H4}^+^Jan}i`7gpV6mDBdM&oL znD7MzdZTUeALHBNKa4HtmgrB2oc;tyXkzJT0+ebCNU=rxyLKk%Bp73DG2sgcy%Y}2 z1j7VcA0P$*o-Iz2@@z3esla8WywhW^HWr_@^$b!{+hR40wnZU8GbI3Hi)z_c0O;wE znP3sA*E?h;C@1Bc3H}pX)IfPNK`pIVt(KGSw1LsT%gFyJWPZnDCI4F%EBRlu*vhYd zr*rB=9zvznTK@kWU;h6z^3#0LnNT>L34+kX%+UlQReng3zy7q9e}hy*q`tvgIWp)zKz#JaJ3QY0p8f(p=5B2!xl=}v2R|*+75Au*N5>4qxlY2 zpH$NT&`vlF&_lmln0|n9!l-QP0=%`C5K4)obca>bOEX{uP zRSg5*spQ&Y=IgpQA@ho3=Ctxg@G^_l;bD=*$|CbERu(z`rpd1?a>in75%vDE30Z`$ zX^Z^#_!jwZV-fl&ULao13q(q20_$j^m1+@4u}Hyt)*_1u%%m++O5woaq53^*k#c}% zk+q~ei_}souu!arC^o;VYgY}eQcndyd*lc}d!$L2Hh}R+pKNOcY;)h;-9@V2eRsEu zl+Ppo2bKDvyu-r)tyrZj;yXON-)LrwYmoUpi7-ryF}c$-}6nKbe`w?$&*=GnOXm@i=WNcoGFFRnIfo7&Ad$^lJR3|{B@0g zgF$y3f9ht_Nn_tli9d}9@$aP-;?L467Jm*S{)*NyT~80f#(xT7;~!CH9O2FmW^`E| z@xGrTj?%i~r-%}*Nc=xfO0!tuU{PT!awh)Bcae*qy1m@&{qv$t{IjA>{L`W({(IVu zpRKm>|NPzK|9KZbo3A-j3ZFAYP@9^0n?fYx$JF?%H)Zc%WY8VQze4BO-oHsf?E#{W z2;VNw^JQ`S+^{ms=#(xCI#@~mq&LG0YKc>qvi1&Q_`)Mus`17

cCT9^2z8Fa_-SLhsze~E(H_^XHz|7BVs{uO$~_Wn9X zJpQf?S6nosonz;aGgRF&QbL3y#A%a{ zKZmT)EB5)ZiV-`9T-DV~AuJ-d5EhXob=DB>{GjU#Sysb3@R*)MUZwTKV|otRpcO&n zmk6nweqn}4f02A!^U+~-a~@$a>pI9qBH|E0Sp{!1=#Hd&)(_&!<& zt~Pb@HiJ(lj;V=fzL3QG8EA9jZC^3S(K$9Nj8R0JcpecFKT0bkUZhuSRw!Y_zi6D( z^^72FpJ5pGsk)n#SGXa3&gbF}LI-sBpsNaVjvN^4l*oS@ED9BVo!cn_7CC z0wuA)R4f{b#TLbA#-i;Hlj$%0ErvJkJ%JaV#cuJ$(p^ z#aV>KVoaS$gqsQGbXfs0@89imoYuSk-7aNX5iEX%l;*L*Oi*Pj1`HOFPYSo+beELP zg{1Y!v+S#)P5euuCH{ZgZv1SujsI8f9{;bn_}P5TnNs+iDT3P6%-a+q89%1RU;9#K zg=Gfaar|{U$KL1CbxY!JP}vawZBu%G97x~t#{qXOA%h`rm~__?hIBQXbhPOo!?EcP zAgnWtaOqFzvMl0|zq)*o*3(p&=oUGtiEA>k^&akFS;7?Iv>+ z(FR^dgx&g_DYxIPtMrPU-qkSV=2iKT0bR`u!sdGiVH00fX9M99@A*oWtzbRmFBV^? z)#EP~r}(2t;=fMfy;vdf%vZ_hkY)z$x#A9UOrIKb$9;25pAc;(^)b=1i?{t85?gK4 z|Mk14|LZP&HeX|=6h3B(p!RyirVz>WF*W_{SCal9gYG!}Je^~wdJ`1Xre8pW^pBg; z`}9lniXGF-7#o{&XAZpoklsC@>ls7X_^%;s{B!CoB3%6Ix~zgYQq{Bji?p7r>e>AY ztw{X8LHrw7W-|W1y{D|fRzxN{z9#F>m9ZvJ9PLF%R9An6row^Fdl6 z<~+S(F&8l6r*2cao&ki7`8>kLJfY4s!o|Fx%Zi9Y_iM~2X+3?v#$2HliTO84X%Q=& z(bw3Dqvq5ta+PoWl-tYiWp7@Udx7pjFNrpL|AJ_<_s@wod;g4R+57*qV$tenMHr36 z;y3S(#cw(+7?$Qwi98k*M{R29Z3>jc0#mVA0Sn9g8pY^%?{CmK_8>~nreKjm1T1#b z3Rq+|o3O}YxHlE(J4!}$JzWTk#R-JPVo04)gu`M=m*o&|`p3-<)0***n-ytAu=p)f zn#Kx~f0?aleh9TcGWqvLCjaipHXy2pjT{GNNsV|-JU|+FOz@Y zmaJ!$o;LnNI5z$sgmwB6F8&c+mPUN)-&VAj)(!u*q8zPA{J%~7qgWyS0$Z`)%nFeY zbYD-oS;6e_Urf1}%^v@$Xo>t^w!6o(r8e^4zI)`q?ILHBHCu-7vt{6FQzvgT_+;dm z8hLR`BA;ZS9YXhm`uU!hs_nv~6>YG1NVLJ? ze$j$O+vfy~#$xficgNy)9Tp5r^QS}}3yPyQwe&UxN@9VjSfsxZEP5$M$5>?P9K&Md z8^I!n2v{7Z6|gAKD~3f8BaX$4u4f2gvABe=SWKxii*OfzmvmVPam)Xd^l4gO`Ja-m z(u!d5dtkAQ6|h)gE1K^jJeqeXn7as{5pA$|QnbP1G0_H#heaDK9uO^9w0##Lqp?{0 z-rceIJ%?Dep$@|9W4XU86{oqs@=HCXnHKU26(>xe&7$nZxID*g~E2C?kt1p9$G zcmK}BgNNy9xAU79bfiSf&foTfhisiq`48`&@*ldC*-VX-A^SKPtlHGZ+YC6FGNz`S zzklaF_VKAv1{Y6x8#{lI&as_;hQisDONfy2X;WgKa)n;8DZYvk|2Vj+>zP8>m~SC$ z%uDL5AzaK|yJcAo>ro%`Ra$*M<_4`u%zs48-Si7Fr*|h~UiKdWzrAbGe+1m#^QCN^ zjrou69`hf$nAuFtlOg*&8LZmW#@h@y88fEFoY^fg_cOSTW6sez7V{W|voYrpA?BmB zLd->a#bPdD#E#^1x|$J$P5BDKraYt0Ji?{Cs>{lVJN|ypbF}XF_jA-}MN&5JjbFnG zQ+%C`7&ae5BbNdnzv8~fGt>GbSHjJI4~jO^`Ztju5dAX#1ET+df5aZ`TV4KR1eS#V zc6So~nnw!#rJIeNuT_463<9ezUB(}%DqoJCj^#?+ZaI27h|Spjj$|9>I>csun~*^0*v3X$tSpUMkJf1Jp#MP5vLCH`X4f6dCw+2K#NikvOAk^k}CBmZL; zIh(B6GJKyc16P|md7Hr}BgfRpYh4ogG6RjAy|#WDq)vy}>xa9#CFTYd^sgkpO~b#E zJl(xB{xnDiBmR}{kgjEujyB|DI5y+~gms1y?v!pqmt_%;pVlir2We$b>lL2@tw_j! zLN1e7A>b9(gQd)HWT@@Kcw?wQGZDPmf0}#j8|I|Ia_T5|I@n%{--W*HeZva6h2vspmtBh zrVz=%F*WeQ0}}W+gYI}DFVQ)6Rd#Mk{_gk$8B1Qd>&7(5Ckdc{yEV?5{X>CrFrbvPM;vW<(@wa^-V5@EXe{uKt|H8%3 z=4;NB!pBb$)Simi6e1ZvrpCXb@vkxHj`#ison!I$q$U0oBE-L&R){~7Zi+vP5s!aF z*VBct@t;80_=nUPMYxl_DP5LB9P&5oAEx!R|8Q5N6^Z{ZiGLa^9074hsFE%|W48v|#bS@ej6je!yrf7JqqnEdJ7A!LT%cO60Mi zIBHW%Z&RQo7MO}fB`veUJjLi3iyEC{*YDOTv^^-SAOaTGO(g!H(4bfBBY*0lo%ek_ zYu{DtuHW@NB&%7aqov{yj-{dpVV!=2n-oTLSsHQOU)b48Yt3KS$Z0+SJn96evjrrc#mHD^v_qjE<=&&^dMjIYpr@6-7j#;-rbh zQ&FZ@>VpEq@5g+);;xet8pDgOMB3S$lSZrYh zEK)r?6SoS^kB3_YXXTDigT=IHgT9P`{&!1VGruCRVv#8RFVDY!4w2T$7 zSYazhnr4gQv^%pfv&D<@9gxA|Inf4-r$rkqo)B%YcvQ4t@xQi<1*5T8{O#Sb_*;hs z!_xdIklG~0h=9djS^Tg#RjA4lF~|3Ums_V=_KKU;0%|GT@#|938aHeYk56h3E)pf)x0 zHibyWkE!ujdu3KwWYEp=xBaB(3Y}vYo;E3{Jy_Hc;ra2Kw8Hb_sfU~5Ph-TtK^S;g z*0WAe8~+g;8-E|dI)ex|D~#!~4B|$3_c5){{UIt(D>5tmJt>W2h4_nXMf3dvn+xvc z)aHJHFGZVK;WN<&i;qQ{S>XfGW>$Dtw9E=^-z>yvEEa!%cP#$iVZpF8e@f)@r#Na; zOK(%4Bo>&8Md@L|Vwz$!W6}1Lq7^#Fuvntd7K3iH-$0e&k0Mz716T}V1uSxp{CBW; zH-d#|i-l;5g=mX~Xp4pD?P9@bEEfN8cP#$FVZpF8e@f)@r#Na;OK(%4Bo>&8Mg9@N zVw7TZj75>ou~W+#3T?3{Ap#bsO(Y(R3cX@jR59!?qQ2EFSgh)LrVtj3TL_EAk~(V$ zheg*uSysau^*51SrS*cpiL5~@g2g|AMK}Ed7U_LSET*afi`PUOEM69Euy{eV!Qxrb z28*XeZx;(jW3l+hyJPW>4hx2*`BNgFKgCg-T6&uTC9%L%EHe89i++mHF%~&G$FLZq z&=!k4B4BZpR=}c2uNW33jPmK#p%1@!RIr%S^^71a7FQ4!iy3w15$+sfRhN|!Z|&2E zlg`mPzfT`ds_CD*bBKQei#4q8`g;rOY{kRo9KyY;&pv~8x#%ub{SVw;^p0q`z39hS zfxQUT>b>S{osIdQ?jG|$xtQ5Z&66SfJQ=Lo)W+KkI2kjh#@rxg`yKlhgNw)ftzDN6 zxS7=Od|rMH+wgqW|1!4yHtr{Or87-24`d|f3?jt5pH_%DN3U4Sd5n0>6S|&0gpK(u z!p1zN&LqNJo1D{S1;j~zPalm10xWm=KFKlLqQn#T*ff0fN>K3O<$G3@^PMVsA! zuV}OT?-p&!b^C(*dsD8PqPM&IGaSoB>RWdQBSi}T&p-RWcQG3TNlX~{T-W62mmSZ5gFjtdjIEQ>hq$v8-B+>=qD6(Qq(L&hXtAfv=)G(VpBK`C5w zcvs#vXUKS4v?1e+XhX(pq74}@ixx84zUIJiEE)H=Ame@^gOMo$RLLVieblC$-lj%L zGBA~l@}ok=Eam8!j4GXDCz7j_+8!Eeh(N|wlZq#!POsRU(ZF!`H9Rh4^z4`QEYZ_) zZ~(`W(S@*1FTx!fhICm9QSH)0!){uayY$eIr4@NS*=|F|FkT=dzdw1|VR0s0c6etd ze4+7{XhX&uq750ZiZ*1tBwEO5`?3SWv1IISLB?(&gOMo$RLLVieblC$-lj%LGBA~l z!hRuRoN_di(e@|L5}n;);DY=8n>k8t$tWX=hxBCs9Icaw^klzEFZ(;}rpj~ z3+Ao&=l4G9u1BrwdS(!ogF6UI#;Q6S2sdZ+^vSXntZ$Z-jO(;g%SuLyKZ?v5U51Qa zyzotDrf+BB+10CKZq6_STpn{|7y>SeHUyj#Ed;dx;(|U$KvxR_x`Y5mpixr|A2oGQ zo3eSES|ka;R06VnLck!yZYH4Z51Dy7$9@=Vf|6PS3WzW_95>bXb3=(wKPP8E)D_RI>``v|Xww(jITM*DK1TX@Pnrir{se{^-&D+!>NdTr2km?r# zy8C|w0y1=toi_~i3jtX~AmAXaKtP^ev9C1?7)@_A(De);ECJ^cmVgO$rV;LpazU3B z5tsc}6(?ye`mZV~v?2sNUm3k1~IjAjB3y%q>K@LC{XpJ+qC9?{z+fX%i9JkWxG z2ZR7dpixr|A2oGQdn#g6izESGjDHqlJkQRT~8On5^w@x2^dmm6yeSfrgT{jG3IY~IZW#%f4fVOR)l~D4FS`5 z;ryV?W<1+;{rOC3$4~Fr@xvYeo}^2n&3sT4ZH@>9(T0Y+XrbXh@sHTgm#uDXW(bys z2V2napwPf*GL7=7bf~1 zm-VdD(=u@g$1>4_uueb1F)^ac(um^wdc*TxS|{Jv8=gm4)fOk9lKbUDH)1CS^dtgB7YoakV$&Pi}$U2Y}LMXk1f}??y+?u z!Jpgl6T8a%b*xSctjyM_f;gjZ`npJ?tZ(|N(I-}=6^!_gg>33t<`8xudk#pI*45cU zxVf`Wm({V>!;1iDeGy&+z#m2SoIPgG>BkFuPWHgg`<`yvbH)$3qwhWJ6{CmT+-dfl zVbNyK85C{yoPN===lo>5dk#aed(NH~d(Ix&bJ7QNU)V)u{4PRGbkCuL-li_eJqJ_w zoZJD~bA~BFJp65Z0x!^6&WqRWdGQqGwJa17;d`8uw8Hl|WqP@1yf2q+uL_2{6J+Tj zcQ(DG>zP1U8g3x$KC__CGQ!cYsmrQ}xBX8GUZz#?KP_0N6`>(*XxPFl?JyVN>~*SC zcISPs85|-n0^Tb>75cM8-7WeD=&eWGMVNch8=?&|YoZM@%c2c3i=quO^P&Zr|EpbO z7^g)h-2$1kAj6QA4a(=)pm1taXKz!yBr=$aOgbyb^irmdk;&5eQ$9Bx{9wa<02|2) zGC4#*<}j^*Oo3jpldmGidr#WS`QKQEW^^?}2usW*ge7K5omqq1uiqmXcElOUZ~j;|TW|ZAO>n5g+(#14n7q{I!7+ ztq3K14JEU9;V4sKE1IwQKK!A(-OzkNoEB}sNQpLJG-~c|3>bCM28=iH=nG!&iJOR{4ZOZ9wYLo;6Q^BY{A=Aeq<>(lU6*|Y>Cc8^og6qQt68U`1>*>g1)~pPok4^HV@#K25a|PY(P%%d zz4E=rj$L_L5ioiT7~^;Wj3Qgn493V*_%h&G(FTmCL>n+37j3|JM6?0pLDAaAmsU`$hvj=`wVId-q|5~a3aR1pD;%O({M z#tOY;#&BTNF|OS@@-R2J%DV;zWHk$Pv>5Eev0!Yf(~aZ67|>-6mObe|(cPwX$bX{C z@JA6adJPzZcma&uKoX4ea{-KVq74|QMH?_qiZ);z7j3{eDtfzMFdPd;ZwoMb1q?=} z1W+YU0QFJ3D`HclBp8?qMt(rR7^NH?gHfb&42&5{ZNVrZ0vM-FDjtjqy<%WgG2~F< zW{g!`%@o3daSLI=SW;&V;lSt`lw~zzP3yIh4H)M| zZx;-PW5L+h0*rkE1|w4fsFEju`lwAgy-kghU|=d3wI^l9Sf(5ugHfk*?6Ps!QvybV zng=j$n^gRvB>hwq7#R$?8YY(rhjcxg^t5Cg!?9!xAgnWta35YLbXgX$&)>{`kk+IA zX7&QD$k)mlL&hXtxa?PAGn${0-F@0k8RjY3t=GdB2OFXd0c)a#fVQ8KWwR{-nHB_O zgaAgMQBw^cHFZ#%vU!_YBniM&0?JPb0kaIdV*;vlj(v5sN=fZ8qlO5dORv%jpG)iX zlBvNx&d>;k5YTf-*0V%UoA&`6OF$RGI=u)tHw@{r6yl`+>S#BuN&nSRmR4kLc+?Ou zj2GsH{GsF{^Y1?6zB)3G%%6WIT>d;O+RO*1L>n4Th!z^!eq^2@SQ;K}LBpd$1EbN{ zsf>@Eny5_)y-i(`G+-(Xg+oHaI3?(qh7z4)G|W+6OG6nE=7V!42|piH=@q*eUc*Nzjtsb)3GOB7Lj#TmbEG&R+8inNi8f^H5pBr0bI|?0kkR%HNDRl4vA+cw`-Kcf zrU+0aj{x;in{s-a8YRiVR5G$TA!CqoG?UTxZ6#+*8f2sclx>#_=>=MlZkd6Cw`kLYF26Yk+!~IWC)gqz7{m}2@Q-! zW2Z7cc50$FCG<9RNz#C+G^Cyu8oHlO($MxTCmA}&zA_tnT4=~30u2Xg1sd}7ik(mv zFczQM%R{qD!<4RP0AXo3kFYdMs56alG%V<{B4T=8KWdz$b!J{aYE;a!@ENq<(6ERX zXsEFn%{MAuJ{{(Xi*gQO=81En4H>6J8!}FcHe?(Zz1?|&;aD>ITaeK&WH2&CfGT+e zsE^u|)7#W2Nd~5pv7%(GQI6($qHQu7bdHhHb6ChoAp#k@X$3Mehnwb!EXE-N#-%+n zPmJh#x)7F(69`MjkUFCXN5+&c%OO_%6EBBped?chDbk9N@t7fF8ZYv7NSW<;vFYoO zOILT;n0`Ri=jCU#&Ee#%XoJZq(FT(fq75d;L>o+wh!#x#k9H>z#%BNh$68?Wm|(&% zl?O`Zd7xNoQ(JFSFtPQ^b^aeyF{vDu31ptqbc{)j&ao4Xb?R;pCo716$#oNvKb$n^ z6+4`yhITgn*mmELtY?*;7L!9b7Ly)?b@~x|wThQT8!}!HZOC|5v?1du(T0r2MGF~ie;+b3Z3O0^fon0l7XpY6o-V2Ny^bN8D%=hz7JWT)Rv42B77jZNGp6GsnIKT z5o-nGfP3!VUESQ&)yyF*2787DjCFOk5bg}LPnXrPPWxNnZ_=9fx4@_QqsaVmz<|+@ z7r@94CvRkWQa){(8<`G>HZbfHZD80V+Q4upe%pK7H!?81LZ}Dx%uG6%~&Y3gN?|<9e)pmon#kPvD7qNDIZ0cZ^EhB8F zYb-PWB!?N+XX=H*;P$pUi^6rT4YoS+qn+Fk$06o12a{IWGHv81uqD{HZh?a7-edJ|0cAt8p#Xj|f>{EHg%-woGgto@!Bc#)3$QzK5#_V zvrbP-#t|G#MjygDg9t~)m@dm8PWbmA?WgsMe-BcgR)ma$hKzB%Kt_?xXr66H7u}6a zX0{z(bd(q}21Oe(`b8TudPN&Dx2}fagRD0BwIuz-C(j23i0xAOJ7|O`2->q^X12l+D}JA_)Md0+7!O0HX}MV*rYD zj{O$W3?;Pyln?=c)28|!fC{~0AJ?iF@!vvP)%8pvECII=mVhO7)(~!L=z30;)v#Xj zZ@0Nh>x6&1O@mhCd!j)@KsO!3)R2BIIW=7C4JTq(dc%p>CDCSTI4|0eaaOb;;7<9G%}VKV5v;pH`(FTkML>n-^?(nN+hGW5a zvIQ7V3K)z`37|@z0P3SQ<@7c+N`ir@U^EnrEy~d`80n);XA=WQ1&j9PXinRoRP@o`#5-qlOQWm=Ib<0(VN zJYFE9%4Rf^F|*{R33G+#jA%o~YoZMqFN-#0ydc_;@vLZ>GTJ`RWH^?Lr&^Hll#s#5 z6alK_5uiS5Q%-MFqa+!aN=EIdOc~3RqnV7hze=jpId+M-YedLsQ1ftw=Qgcyg(p4I zL`DX~zHD>oL-)GPAzjTT9W5Bga4Z-D2gDLNEOtr1jhhJ)0=dihyy* zfH8>|z$md5&0t)5D1dQMv;pIsXamM+(FTl@q74|wMQ;}jhGW4v)B=n{0tO>f0;rNF zfcmISIlWDdl3-ve808TGW0rC>gVFYP2UR-9PBT|2wLO;95CM#^-J#U{pQt*OP6-oQ%(cMf@lNAoM;2ajA#SKlxP8?{dXLUIxuoAz{m+0j7$lj zN}d4fqc-LAHZ@9ufvI2=Mg@#<%F!_xB|68xEtsR!7K}0?981p83dfQvy<*3b8bCG_-w_3PZ5d#M3Qkcv@&+G#WdV@v&1AwJD*u zsY{XuOr;_FywEU637TnW`}mQkbBu-w%4=yTAi^|poK~17O7x1+P{xRV`MjX(8ADha zt|2T9bLuQ291ZKbtb(}V?~K1l>vMl+{0glI4TlX48+d_+2AeU|bXEAPLZIPhA<%GL zw4vduXhXwg(GeQH+s@B8F$7D);TAL;78)3h#!h8??9@bUO6YCslB5AsX-K^wG<3g^ z{EeR{<*ixfXGjnDH)z?PsQd9<89K<@{a5X$g`pROfGpyiKCyd{#;iWEo2QRl!8~jG z6foR}(UU#y3g(oqWdLFGKaa5aPpC7EaQQFjvLa%msd8K8<883u8EeM|7TX#R?cjy&3ULr&O?$jTdjdo0Us!1SDR9K zoAD=e#?+iwH0L#j+WcEicg?v$hgi-%$0X+z!soo3hR->3tSRR##%cQj^<~LFnRNn>m|pGaqh|`LJZp2sB)(;lrg4YEw3EQ;THgn3{RznC#p040~Id z*XR(-e4R4d*?k4!Grvy5XWpPsY~M~5^bm1EGVd$MT2|?3Ge3l5Gw(rIryt?Y0Y`LM z8nL{r9}f1?`q;nCC`T)j`77{Gr_1VCU->8P zZ_?WIPui#Xqe#-vnxy;jLekk6lW)6xNYXWLyX=l9{bQ`aObtKT>TQ>7o=y7M7D+!V zNwcLIDWmq0GG4VQkGC0fGHFarI`^U^J- zcv+wk+SHG=$Z|`!)YxCBbaAx-X@Yb0h-<73PZ2lfOE@|fwe*Qj8!_VIZ z`o!k%B1Zg}J)>(GLfEV?A#B!D>dYcs)=RpqggEbifbTS|3;qZAZqTytoT(yg=)2ZX zcIC@#z?tE94o+X6d+rT+=M3vIB?@24^T&1uu&>(Kphvt|_GL5w{GRB`W`2BEYRtdj zf6bnT_Kit-(uh(2Nd8`0FZf6Dv-FZ{9PR}pIgBauir)(rIlztSdU_Cc45tvbKqKmm zBV2)IbXgwJ@29<^v>x}^F6%&56vH zqUGeZ?cbVZQ|-=>Z?QAvWoKZkm3k`Rsb}nJQz~yW{^ZVpsXIe;Om>Dvh8oZJ+q-TZ za^DS@UEy=ldMw|yLWkFl&uM}!+KZqf=jTBOEz-uKGN;g@-2`wh!S z8pFMm?dD$hF=b#}*0WAeoAePJn{*$-I)eyzDl?|bGKly6EspzXUGcX#=4nNee$FI4 zju#GaMK&Wc{O_1yZoU*wWxf!t!)FC;9pKnJo9=Th(tS?SWlJ?iM(tx{ylPV(Z!_j( zx|o`7X;%^rL##_5#fTwWm@5a#0tG)2e>*${8XmvC0Wk`J#DW0 zaBR|>>U86{eR@EbHCVRtke;;Orgi-xy`r7rk0MDQHAxTRg`{&YB~NA6BwceVb1j~9 z+ov*Yo=y5_i=>ZA(rl?l%BX#$j8|>S<88*AOd3;@&c7r{k21WDlP=OZmh=pzvq_f_ zA?ee!Ledp_#geXK$Q5cim08vGOd)L2w-7ezC3V&iF6pk9WmygDu>TF|tF(swZ%8+2 zMUoydNq5sR%--pjlb0SYO@>Pk=O^9%ZD#MYq9d0c?Ec;Ab$V>7O?{+A>LZdmTdna@ z0Us}8SDR9KoAD=8$JEp_FU#!R&rsv3Z{ww4IXcH~Ngkt&HuXFrq<)lENWDm}*!L18 z40Bf$zbh=y)$3|T5H|EH2pjs0I`aq@`l>D~BVK-6uQ#2eReW2oH`QoG&R<7O=xcaC z@UH}`vlY$vMU9tT==T!zXxW8+4|-U%xe`4n+FYOL7j3}k6)j-2eP0yAv0#k00Ap0Z zU}Q=FRq_N-AGPNqHZ@9ufvI3L6pSs((J>h56HQ-O4V(}#GKlcWW-!P6Kwz(5p4h%5-k9<{Uft%wguq%763di0F+N?q`Rnw2Y@;# z0F=$!)FKH0rUFnqAv41=!|oV>I-TQRWfuj22DJ?U+&0zsA8pgcrsF{dBYt1hkgjKw zo|b@PIF^6`gms1yj(`bWmPL&EFQyLCdcl7&RiG6i-~~g#Bwiq(#AXaMeY8FDl$#n1 z0lB9f4TgZMXhT3ov=H!bS#ev(1~%Ig@Ing$UJwEpfksU=eALuIZOZ0tYLO%WQwb;+ zg@9Rx-7x`GI>*ikRw=1HHq;P-fUBnZo`5>NVrK*mjQE#PJ+H`mmgs5oK7eBh=t5Yh z7vTsP(q$>clz)T5Zdz~nHz;IjMF==%2pGl-2Z#JC$>&v0yx>wd&#SyB+8hv`6K!aC zTC}0z3DH7B+s~^o1WUuQ7Bn0a8W@enPGx-T)I@Dc=xyqfqybZDD7+#xj8lS+X(-V- zM#CKCwKS9wfrfJ?2~R_nUNIVK7;zfbbv-i(oBbVxrD0W_4TL*Y=s79NRS;*vM-dtdhK63eKttwa@+s*@MjQ?1Dd~qq8yfBxZD{!FsQVj3!{?%fhPI!QW(bys zLJJxSLIb1G*r|+C=qUQ0s(5okDWlJGQ? z=oO=(j1hk=`+}}#3}I=whOjiusk4Z1bHlnWs~|pqTR#_Gq_zIGelA?06`|opL&FAM zI65@gi~~(ahmXfy(&nj?E22&6mqbhI|EAp|0-I`6f3ZdCFG}icwZ=;Ye7uZZZA#^B z#-B_bQ&Ue(Nb21aKSJsmI>%BUnvm49h>-e0S|Rm3y<({sFwWW^0?o>2#3^0R0K%qz z9${0TP-hz9=70rVRzw{49~Vy28uuR;DzqZ0A2+El;)OY&#%AP9>XF}*9(dNJZua{= z(PqEz5p4+Q5-kL@{ZpW9wk6Yz4d^ES0e5`d`$tSA9%47=m~ zzCmaCpy$5Y>X{S*QiwpnZd!qW%w*HYf-J`8x9!{b-96DGx|%M81>gk20x+b`D8lXb zQ@SjN_{8t_hiR?)-M&aG0>GF7U>Yy%_GPxBdAC0)_oA8Iek^j2+DQB!wYGPAHr0kc z)*|#V37xIhbg6((m$9o&sl3hjlc8g3=#@#??dKV4$D!Bg9D90doif_VegzRiziuk- zC;JAyV!M6n)x;C+ugZE>>1k6xgkw|hL0G3B;Zh&bWobm+f6KL()=mE{SB_RB^>LH> zC|*dtz-Bam6!>T`d=&U#&`kkmw|`f(+3nvJExUc&9|hQKOTc&w0>*^^Mxaqs4Iedi zP`fW;Q;Q@4m`XtLRUu%KVRuYGna(i+7AUDDpn?blTr}191k~siBVYxi&;2yGext4H znM2sT_q-+qtgEwya1(!@E~{f5^%MV1TBCmAPxD6+0$wr%^y38rvajvD@3E%C{VVc8 z@5e}bJn{i>H2wkbd#uc?=qFoU9Ar~%>MylO{Uu4At=4#{fKQ#VtGyXXo$)7A$JEqw zuSx2|47KCb3v`a%v^+%_ZR$ltNd2U#xKF)Iuh_-G3Wj`b>aGDT>1rkrHuM_^yW20Q zvy5<|Z|brtV%hKZmuY?Mcl$c6Na!z{(6{iy(LQx5c{lqTksos`MSje&82K^BLgdFB z^PzU{D{mDW|uoQ4$PH1tWb*!04qM9fOgj za}11;QvyZ~5x_W1D}Yg;SM1_o5hM1{airzUDsLT^)-Bn+4eLtSCmpadPmkSh7-+uSK(UrAs{BLWP2 zX$2Uv^okuDav1Rog=4y&9)zXg6vEOlqRu$Nz3*m5m*o)`{5j!KT66xKutY2J#Zl4F zFpC#xsIVE$550V}KRk6`6MYY?rjk)D$uzM@IXWg|h0gL_pnHIFlTzE`M;-CnaeevWOj+|ueJa+|>GvYvH%S~8B{STgz$))_>&d16eLWe`LDlF@!z z&-hD5d0LTq;uS;2I9?#5$Y$i5=81LrC}?O{6>Vr(5^ZQ$5N&9f6D>5{%RkcA*#twd zG`!M+hF63JMx(J)86P_}QF|a_Qw5(@=o;Le^IF^P@b-Hof>BN98Yp`snS1%deru9s(UNXw? zM-duM8X5-i>^Y>p|221d=Y5&jIpnu@z45d=QkWktdsVdDH1b_dy478gY@SW}WQ(Lv zO44kpM#`vt(u`Ma%HwUuoJ<;1lg^*kTL~CmJn3!R|5~JT>@v{|rL#$w5FzQ)rpi9) z3cX@US25x*%3Ia-Od)L2w-7ezC3V&iZoluEl4Uil=j|(O%nNL;(mG~eU}IiU)1Vbe zdcq{#O~Bzp{Wo&FH~amUqRoE)nP{`$e=OSU_aBJf?tae@EDaMaXqXTh7>&kG zWqj<^L~TmwZR(Pw0aIznOv!%VPYL2QZ08mOI>%nHFh+ST4S7VM;V7*@Ly=xF8cG=P z^Mg5E&j`ZOa0Ov$m{DgQ;b>UZWo5+TRo(B;(fZ)3?)NoX5gH~94QqH|zpt|y&HMfJ zT-figir(&i&*s^rCtD;vDM_=X8Y!dpkuqMjDUY`qb24d6O}atS_Eyg=h8ItI8~c5F zx@o^3n3kk7h>-MtS|RBiy<$n{G2HRKM`rj5T~8mvCVduRlO9uN65*1b(`5xjk3ZfY zr}eNu-j``bl77`BJ&$LTwxy`D8O=8hTz|lw37W5rmqgoRyl8uj7cKjG`!@|tI|5#9 zLBOj*03*<-sfLf5I;c(AyiF~V1YjxwwQ1Scml<}PfNkvSbvnmp{;oHKfCjY<1l%^& z_cMR`jV1yz81rZBHv~e!kgjKwo|b@PIF^6`gms1yj(`bWmPH&N)AP)Ow8qEuCEEpB zkFn;_u3xuj@2iy5&h|A#AmA#k zKtP>dvEOWOV7Lo~56N$~_neXSEYZ{EeE`Q2(1oy0FT$PW4e7EJ;!}U?`EFV_!ma1D zB6GkgL%=XzARvDx`9#E1=fd^j$3>ge9}z97nb0B(HwVC z0Us}8*VHMMw;6vjbxcjYa7I!eXQ&;gUZS&H;&ayk<|w00y^IK{pEDKr`+b#Ov6;Vy zF=uWf9C<|c`*mH<48mr72VqlRRc8a?_WPc*vTOzG34aaXI;{bJ4IsrIMfUrWNxc^@ zq@Fp;sYcU&f9jmOB4qaa6A=QAMF=<&C!p=$X=k%70i_lMl!O3Apixr|A2oGQo3eSE zS|ka;R06VRg@8eZ-7x`qI>$ciPf$`zKmidx>mR2TKI@n075l7T#)yB`U(of8AuIvc z5SD;BbrunhfOTC~L5$q5XL%QCJ%7KR<*m?)?Dwx50ygjh0Sz{z`5S_+lWxB^-w=HB zik|Ut{x4eg`|q{8-?OPU_19aZ{<@^jR%^Uez{ktj)uvS5X8g(2F*Ws6SyJyV{|KpP z=p5Vchsu(A77_OQgS5hapQl%Bzb{~XW-jo|eCFPFGo`B;K-kdFBW&ms>P#ctWWS)x ziio}bYoU|0di~cz6X?hq(2o-Y9;U z)>m)pjp9XGkqLgvBt4B6KGK)jj3XxL$ekb8dfdsJx#V9HZ6^DwXmgTR5p53lWzn+R z|5UrXJwvcGOtqk4N@!p-8atKou~QSZDWSKiOOggmrJ?es?Dq4NAWp+JPV;MYj(z{L zPI>KQzk&!fT&ERiXwWP6#bD~(&imZ+U=O>e2Kvs)YF6oJVK{_iVdz0vryt?w`Vn20 zMm$|s81~W{Dk}^*T9Ms;+Q2Z1XXkqNBs*Kt{E7Y>e^meWt}p#j-M*ru?JId~o(+1s zMbOg{G+U~PGHRbF<5ipTc$+aNgT~aLi|1swpJaIPptrHxm+2ha?H4GW4Z4B|L0>dg z_UCmqdd24V6^t*;fq}SEiLb#;+bXgs1%s=yblh#ZAnb$Ob z6iNCGlXO2`*zL13JMVkCX}5o1#+?=1!!G@`ByD#4FGQQ&{!>rGw|0HxX&|&kGWqj<^L~TmwZR(Pw0aIzn&B$&)ObOyNY-6`C&^boK6y>!v z6cK@jlO_pILz!MN8Y&oaLC_uTmvl7~2n)jvgx&2I)LBNz{Q$bGisc>t!xmnEAvK%4`)@G1rWF7v&?^Q&5#y7$rp>EWWjdJA^$Z~_ z0hbV#fGKrm5srW*T~4`)ExAf7Lcm!=z%pJq$zNeJntxMqQ-1l%ye;{Q z$gg948u@jskK(_M)%M$x*=#!noNYnCSs{QCXw+20M@=2nrflA(7D)mym4Lbuu)(l9 zCLr~ezr5qV((QXo2uLFW0efi$0RM?8=nvMr^Mc4mc0GKJdPkH9p zFeTa?8zw}XW5bweb4oZOT22Xny4_;~!?9qLTYym(Fc_H1}G11OrpS zsJpG{`UXhX)GCml&bM%z!4G8{|Bn=QzAQ^;UsiU3ve z2v8rj2O>5#N|J%8WR%_(GNvg<$7EFK9RJ>*Qd=^rh(N|=lZq!}gkxX;h>Q_ANzrl z@0dhSKj*FuntR44o(oro#zaf%|Ek^jfK9cjpKFo&IZ2(Z)_AFaPo1%=O{u)i_>-w) zYU=s(lKLn^?Kt%!ons#nXDFjhy@UvpvGc|f#=3p$%sx49oYVD;AS?}65SE4+b>d~q$ zDJ)H}*41Zq3aHVF&@gLgSi=i6)Y**YTLjZ3O0^fon0l7XpYG?a`j%F!_y=?gpWJLb*+ z+!sd!7le!qB9O74Rv;rsuNWD53j$`YlPCE!9XFwU3nXs!e&k&6tx( zV`|d13vwxGnc>Bg-o~Y*I-TRU23(Y+8`Ll)ecM#o9}v;=q`kH zdJ!(@AzhY2Jby-m-c9S+84Ws1D-!g16Z9}%IN!_9@r{KEI`R(V&yU-+?JyJhC&$D2 z-iM-PBL9~fdaGxJ*i;+(`4*v{m(ba2O_vJzbQ!zal*-$TKN&ivhF+MHL;N^HjfcLC zYl9^^#}4sxl+lJ>MugDMnTq?+tMrOZ2wEYVQ49AjDX+cIs$Y5lO09En`P#?7^r?;t5k_=2GBRel-3{sAc$;i_= zHt|nTYD-1|5y&`hQt@Pz=oKTQj1m9sy#-y*7{Zcq4PnWcQ)dz3$XM596~wFl%D_ch zr~H+H6RG^7xLhTXIR4VibFXvku? zYmC!!nm?lJ=|Wf{57D%v~KxpKt);+8s-cQ(|DyF=Iqbj zN>OGz#taT={%7wL;Syif{Q%C-5Ot%v!@ei>UUXfw!DL0W!K5bIU{V!rFsXjW9mhK#gmLqAGIl`x2aK*3``}XcuB~Zq#PZSQKqx`Zh-?konIg>} zMZkE+fYFZ^&LOhZo*PZqG*7JzqJ0Pv0gzz8&H zs^OES4r)_2Z&QmT0GJ9ut||ZwGwhB5D9|}JHB3=b3qTPO061x??*S;&D>gM$Fyc=Z zEa`eC5SD-&2skRX(o1PN#w1H;Q&#@FX}?e$c~3COAp$0cX$4FQ^on6p z#E8F_Y)02Jgs_-gLRd_u)R{%d9SXXvgm~9KesG#r)jxhvr4_;ClEGvdFM`Pm+wrm) zOyopk&$7ehe<$kuMH@`MT5`U@3Vt)7L!v5i^+&O;|Pbzj4sO~ru{RCM`@k$&m@*;MQ&%U8cb&K!ih$O&1n9%`pUAq zT4Bhzv>dKhoEL4#I4jzaaZ0oymclx8`X@CXn|G8RK|?j3S%SOvd@o z+y@my#@WxpoN-FDA>)K-L&h=DhKwVkw@U`Yv1Gj0f{gcs3`V91P$iE5^--I0dYc+0 z$-q=HN((~9H05X}qwSw?t(aQ6->-0|pi7k6l2Jv3IpeZP#h-z!&?`1))G^{OK|{BJX6_@f9Jmkk+%c#%U(ZZUai*?q&| zU=A%?61Bl(L$o=xtcf<5EQ>anEQ&Um%!}Ucp@p$oOfI*;N=6Rr4YExTp zQ?Mi^n2Je$Q7{>$G#z77q;m|D8R~8^DIo$Tr%gm2lM20Jm{c+1n5^o0rVtjBTL_EE zk~(V$he_A_vaE)6%b%!TrS+BnR~xhjH!QpXdYgi9U!Oco6$Yk1)kZJo_%zA8Q-_q>^_;*W_osXrXQ7q0EA z;%ur-eX&LAi;_B9t?^O;A1`B9n^Jk3@h4Nq)YKcA`W8d&IQ8@gO=lMaA4uvML`Z!< zt&n<-Ua{2k81bv(6S|&0giZY{!lpi^&LqN}ch2du0^*Fnj&Yn;*pe1XD4oeIS#=GNtJllRBMa z-=KG05lk8c5HPuIBJ#6&`ij5WmA9XLGZ^2Phbo7A-OY1Dx|&ToT1t-LSV{&E))_{) z+odLSSr+lw9=+Oikk)}cdbO)SD?-T!hLTCVa1L5xD~=gRBHx|VUUx?X`(3JN1I7i> z28=gF8!%oMZNPX%w1Dw5?SjE@EEpfO0OJDzgOMo#RLK)SeblC$-lj%LFfbL2@)ZGN zmU46qMwQMnFjgtGJ!;et0gS6A6%R(8Uh!KiFk&xW?5W9Wmgs0PIDlip=t5Yh7vT;X zL%J-5Soh}^yJ>yl|IsY12pCrk7{hqsppma7FN034Ixx&-&`Hq-fN{|VfKkx`K--r= z*=!5Il@)7tW^)dby}bLe>BA( zMF6N70DAEP0GSVyZ(=?->aJTD0H#LWbqfQ)glGf6m}mi@?Kd&A*%p9W3jk^Y03*<( zsfJIQI;c(AyiF~V0AMNr*$)MPL5AHi0C_scu1`!*QVT!<5db)Ds_(NX(JOWaQN~Ey zpK#PSZ7k?|#t@c(YY0ogoH~mLN5Hx+s~|pqP>&54X{|q~$A%SJ5duCm1Z?1iV?%?@ zXnqiTNPb|!JcvCg+8hu1MH?D=MH?ErMGFl-)$Z|tAy^tdY(c|^LIb1G*r|+`VTD%h9F@f%T%fVzq-}9E6 z4ov8GW}TMMf1=&c*;E_))fS;&mC!3!HO5_3z^BXDHT0>7&G?g{V`}It8v0s%sP^ZF z+rALh2x-a96iX6%3K2rzO)G?+S!xPBiy=?n>&+Cpo-Tw<{RG0MKBUel!lgc?%W{ZM z!_5@5ZiJgDXhl+AGO17Fg(;xSW;B0GULAJn{zsCY6MYYQMzom@rbOF=gJ^qj5G`c1 z{Vh4ev1BZ@AY)0$C@yK%yQq>UgZd~LBN3Y#CCR{4GAc_l9n4dXjt>qsI>$~A*D19< zIIJK78P`oJ{@~D{SM2mKwXD~kF1c^X`<7)jt8}zr9Kx|+^dPL$k8og&=(04T=FblH z(z@#Z(HyM^7|RBXQM>>~fvsr1c75m3Z{53N$ItG#7XWTO>TZoNVB8RGz_=#bfN@2% z0ppTr0i*42H5iTsW4Q$w%K`=?Qv#@x2ZQ>kO*y?yjgnwsDj3CO0b`PKbPPtB&Y!-0 z9RW31^@ibO8ivouEKsh5p8!)Cs8!#qB z8!*O18!$#h3m9$RoXc=57$3C&<0AosktqRG$rC_*)TW%?rbbCHFcpm4M*_w$<>(lU z0-a-EOi^kJMiCLfI7usjQKnZ6j0#2!j3r&o1j2%G17T;31$CAY4vbA*Rz+NYS|7~1 zOl$3FeK4y|D>7qzY{1yU3t*%^PRFEV=%IGjvY!yJ{B-?h;S%5 zOe-8p3iOH{N{Se3_BjT_v0z+l0md}}gOMo# zRLK)SeblC$-lj%LFfbL2x`MGmIXVU-bESjGLkj8P`P{GOmi=E*T8RlCjc)j1?h+ktqUH$s<60)TW%? zrbbCJFqMqzHJLINDM!a-tk79LR>~_ND78J7)DhuWa+6j#mZVlZ8AbOB2#lBQ8~$(a zmRCTm$a>c4X~{T(W69`4SZ5I7PCv(VSq5>fU&+`{>yv&ZBTp-Gmhp)pV;nD#QDiel znl4-SzYrb)dRTr7){yalXhX)=&%1++A>#|thKx@|3mI*nWiT8|#wRVv_(aHHWQqV) z@(55LwFe?LHA<3!sbrK^gp6s*(J>hnI>*j3mMFC)qlyS*T&5MsSfN*J&ZuL=&N8|_ zk<~2F(PFR<$AYn`PB)GNV?dWRShl%e!MIK9>-`EwhChl-8P^RMgLnaq+$YIvR-efg zNpsEWnrH*V710KUOQH=7=S2$)KgB=N)|Xoh!NPF81q{~(21cW)QyC8fHBp-qdYif= zVZc-v@}CF{qm-ay7>aa`!7xL4Ees_@IDnisN%+r;6?(qxJDSdIhsaD{{H>g)5kKHlz7Ah|{MW4dyn8Nzo?tanX```?oT4}hUz60?YK@l)_;?w++LX%Mj6az=rl#J|)VCOF$El}Ro6aEzRweZeBBZ{bR!BWZ zuh?blJVw)P5W1c|giZY{!lpi^&LqO6KBvnHh}uK?CB|`DS0BYz4d^ES0e5`d`$l-GoS zS%%#)0aZH32w0`0cDAn}0s&WP1p?~yitYCejQD$idOnr)EYZ{EeE`Q2(1oy0FT$M& z4(YNKVkE8m{cc*%r**&2(uxpp!w@ix7YN9Inw;%Ft?#f;ewx|-nrM^y715E|{=4RV zAgvw+XH#wJH(I2ALsDm}HC`&<<7Mn>Qz~yW{$%QyntI_=NqwB5K4PZ0-Td#LerUh1 zx^?I~cBucH*PVPWT3(I*DOqQ)+UG%pwU8gngZ(&ODN0FrKCh1Bdct>+*5UW`gl~mb1dPuO7#nzD3TUtu&A$`z zqTJtVekWoya^LH4{Jz)ku`;uwmQw(mYD53LMd+VP=xnv7O9gzoj9qO?{NL zPu-BvyKnpmp=anEdppd~4GBGq2%#UO6++L`D>m^Lf+2_gDP7M1!lr&6VN;(_XBy!q z{smoDMD+UmUQg0`#NYQ?p%qE}rb&GfFQi^$GnxbFWT((dqr>e z(9dRD0&cb-;HD732sCP{;iIMwYEw3EQ;Q@4m`cEk60pXwJKpUZbdLQBU{75LNFf3N zyJ-aiGW8|`vKa9L!icV?3t&b{dN1ws2|Zs_}5*0V}aOU5A_OGXdEI{gSYH;m}AG~#3b=BT~2R{Wcz zaVAI>(ZpqI5RtA|fPxl2%B%Os`nd6^suy%nyz1 zl{sKZ*E4~zN#8)&IbcDZWrRz5QpSlo zZaO-={id4(%n{*?ByBGWi#GfH%c9K@;RR0vvHjeR|DZIq`oPE#EDc|_py5lQfzfE} zRK~|nP1L4@-li@|8ZecH^t$Z#y_6tM!#3U}n5A><9_NvDp&^F|G#sWCXeiJtMne%J z{;rQ1UC$80(r^i3X_!)H7U5`E(q$#Yf`8KXG_CjjleSe_5gKk88kX?_4J&NMvrRPY z$+)kQ|2;|HFWS)X)jsDN8a@|oX!u05oFDwBc4=S;mWEp`Xt*UbFdB`W%J|r+iQ1IV z+tejV1E$hYR~j}bLB}+tHkv*#_H76aX+)r5FRegBmR_;%i*gty1^#o7JdEjTdJq%Y|b8Md2q}KMRQ8z{Rw+r2*705_^(KJt_G2-*Yz!$Qfb$VJf zj^J1{`ViI`M7T4@F z5&D}m;mq+%(T0rAL>n?b7H!D*K(vt2_DxC*$CB|?3o^bEG8ma6K$ScK)JJW~>1}G1 zBm+~)D19MhOjC}I$*9m-eudcGin2thEg4lr__TT1q~b3!tiuWet`+;eVj+Hmw2w19chxC<4Z91I8d;03-Kh@&NLp z91zR_WJI)qVMw%rVL-Hjp-=R74hT+UEl3quJJU^s1(@Gw;96@#IQ5x?}Xs_U6TSQ>62EDcNQtRWl? zUAJUe4ePq6;VP{)PeX%NgoaH+LpL1*4e47u6R#rOnzWP74s+1hm~_*Gp?!9ua6bN-NM%q*v_ZvV`H@NBEe0)R@!tj36uxR}hwl8Fl6n@>>+Ttc-Z)4LxX_ zqjl*GJ!sVQ&+pk`R#nbaj0QCibH;6xia&y+ zzw$>Ac^?DDnz>=Ee%pO#HKeQAq@xAn7>)&F0AZbBggbyt=&~&0`UU+6a*)>A1^oz8 zpcMh*8w189UikK+#8wQLPau)oRUR(6s}ts_>jz8j0Ac|6CUV2lm+>2x+J5Sq&9(r1 z(*l5R1OP^$NmC7}^ju}I`EQNTurpJukwD#5Xn31Iw z0pN}SU>GmV4Efv17jn!z;${Z({M58)Gc!zzHZ#MxXamNmXfrbmiGx za4Z;iT7Yrq|0C^vpQF0cJWsV(+Z`Lb)3Y_Pv5jM2 zOh@e7**{`m&Oguzk|B)*B$6-*5+*@1q>*gW2p3sMw$qYq(nz+`NQMMqlOWlo5jFzJ zMn(embIy65bMDQ%(V5C}1QFl!y*k(TJl{{A`y+4OD_}4(C4ee<0;rGLl+)YPCC%ZV4R~IjrTUZ-XHF5I3`-J%Wf~xA$9~YM|mv_WyGhyFpt0aqmJ#DXjFb-N7%8w zN}t&ALk&aNkmH9{UCRu@CjSg!Sy)zQ4dGbm-jHQ=tiD5fGxJ?q2M_7Z%qjjT!b0jf zqUpg4EMzv4EDT7VhJ}97hJ_x{hJ`NChK0?&jvd3on&_>vz;JA(QqTR9j-UV8uYb0! zjqS{4e3@BQym&eB>5ze}N4?3kg9aq*D3t1X>z z#|#U)o-u@_;SR#mFsIH9gga(f)nygLkN%Cgmuap0H{#Z5MQGSzXjsDwG_123jbC0Z z?FnCA-PjW@LClLbG|Y-NG)#*&G)#yV8e0DHis4uqb~K@3htR;tGXz1EZ?lM|_kZ6X^@mn4?g^VmB>@tqf3cHLvy<+o30mHplb+615Q@Wl3 zgeBuMge7BKooR$SXjsr?MZ^#OS@subJ@U`8uh5E+vD1)o122$KV>23$CQp4CjwVlt zHuJ<0(T0p((T0pYq74~4MGF}%pJy-}OUBM7Wb70&7?~nKl{^B}M{UaKZEBPx15?SU zD;f7FN8`an%Vez6*-aTTXLLUiGE#^zXY8aE=8VjfhB+gP5uYlL#ZiIFE z5pL2L(Pe4Gl)JdZ5zQW2A5JJ5Ia-k~JGu-Sqj+J`D6kogyOYtY;Rz1I@=bl?Qd=@Ah(N|=T7isO0KuJt)-fha2Y0`@^rO50Lsv70uo&!qCSa_pvx#tE z^y#t{tkRcy3i{Ce!Iydpn&yupbH>XCjDEZTM)ui%lemU?tsJgleqIjOFh3S;VE90^ zf#LU}1%_YoKWXW9N`_!zc)1A-FAEHeMpLIUK6PrM_C^E->XL*3Q(?$G6BvdmLEA7C z=p36SrYNt4p@;}DTrf%aX`)Q8*fdeWh@XQj>UzczmWKNXJ54O8vxIOoZ0NEoqR-zL zbDh>fe`CxFtq2Xf3=NxjfreD-g~T***OwtxgjR$C9zD2^qVD3`V91P$f?W^--I0dYc+0$-q=H(y14=J@+4;>)75yIoc*8 zOXt`$F_L=0k�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�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≷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�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

&kR=wrW)t|JEfjbE`c*d}85)Ala zOt}u)=&y2U0P_hm)RrG{FFbn0192mY=%B6cxK}G!Q_pi>K<30ikRyqEav3urOB`a% zR=Tkeb|je1v4v8VV@M*nQ9~O54i`Z#)6!H!^Z^bCVXbmcw-qY2o-dT$3R=sx@^d?# zjY-`wH#JrMPPNwEYV~ckL*$6j%;$S`TYskA#?DlJ|122w4sj#;pGC=q2n4b$Vbf8>(62$>k`Qb!B5%mECHK-XeZ9Ed_rMfd5IZfz zN{Bw0pKND}>|BQ}v79pIyk;;40~og!z1`Q;>8YH;X!n10CK)+0vQWb@l-H1&I@c9x znMynR(%XWH5{-|2?Olk3$9Y|dW~t&3l;_fxc%aKi8iu<^!7YnEGoqo-c_+)|S@Xv_ ztMWHxCmp(>L($_MD0%b_p|0QhlA`sFtgHM$1a|5fbroYMJ27U)JY#&3Q5`I;vuKXu zB2?753>QZRy8al&g+$0UQ&8T+u(I47B*l`i^Agv%NP_|~r{jLabYXjQ7jucZmaX@m zH;J9Eh$7e$AL+PfGffeI`0PR^t-i+JO|Yi6WVA$um+Zp9&TlI`r-Wg_&U8J^S37gw zGC6zDv=tge!-4`0Ts6-J!L`G`|GoR6Zd}6mmNgC;u@{ec|KrlmFP}fVGTV zn5!t;Aa&K*mfN_SrP>Q4v0!d{8C1kvzU9>R0O zS6>|X3fow|QeVnn_4~Coe0Ar*S8OBsN?6Fh8pOtv!&hG#_zEQ#UkQKuYBmmEz*oF5 zJpNhnC9M1B%(gL*6h^)jKlf)XPFn?t`Xkt`f*VERtKlFJOD3Ww;-~z?vi{ z9Dy{Xv-4h|TC5ejpi!J>Tr3kfS}VmZFfQhqSKpqhy2n>@Be(y|BQ4x z&@4^|+T3{$N>?#OYT0}A-r*^2AB|`6

;#;?m}fU_9gPW93s#1>?Rhoe_*@lb4tY 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%0Dmwgo6IH-|N|DU{Yv(Ob5 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 z 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

kuEGZv?s!fK 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 !u!9hNCB=4wYIB?S(8WDwMnIBrO~ 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 LkSzvW$?^XHl?|>V From a2c41b3f1fa0b65d14b9156123e9faf8a1b5a06b Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Sat, 22 Jun 2024 10:23:04 +0100 Subject: [PATCH 13/24] Update file extension check for Firefox Modified the browser check condition for Firefox to include both 'cif' and 'mmcif' file extensions. This is to prevent potential issues since these types of files are currently unsupported on the Firefox browser. --- webapp/src/routes/Home/Home.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webapp/src/routes/Home/Home.tsx b/webapp/src/routes/Home/Home.tsx index 9fe65edcd..257d9e2c2 100644 --- a/webapp/src/routes/Home/Home.tsx +++ b/webapp/src/routes/Home/Home.tsx @@ -56,8 +56,9 @@ export default function Home(): Element { const newFileName = '/coordinates.' + fileExtension; Module.FS.writeFile(newFileName, fileContent); + const disallowedExtensions = ["cif", "mmcif"] const browser = detect(); // FireFox doesn't work with CIF files, get the PDB. - if (browser.name === 'firefox' && fileExtension === 'cif') { + if (browser.name === 'firefox' && disallowedExtensions.includes(fileExtension)) { setFailureText( 'CIF files are currently unsupported on FireFox. Please consider an alternate browser.' ); From dc501834e0870de70f1dab79a809c9f2c7572ec7 Mon Sep 17 00:00:00 2001 From: Dialpuri Date: Mon, 24 Jun 2024 10:49:22 +0100 Subject: [PATCH 14/24] Reverted CMakeLists.txt --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 277ec48a4..656c594d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,8 @@ add_compile_options(--preload-file data/linkage_torsions@/) set(CLIBDENV $ENV{CLIBD}) +if (MODE STREQUAL "TESTING") +else() add_subdirectory(gemmi) add_subdirectory(ccp4) add_subdirectory(rfftw) @@ -35,6 +37,7 @@ set(CLIBDENV $ENV{CLIBD}) add_subdirectory(clipper/cif) add_subdirectory(clipper/phs) add_subdirectory(clipper/gemmi) +endif() set(PRIVATEER_SOURCE ${PRIVATEER_SOURCE_DIR}/cpp/privateer.cpp) From d1c758c04e9baf9fb22803b04a6eff016a65058a Mon Sep 17 00:00:00 2001 From: Dialpuri Date: Mon, 24 Jun 2024 11:00:14 +0100 Subject: [PATCH 15/24] Fixed sajson conflict --- CMakeLists.txt | 2 +- gemmi/CMakeLists.txt | 14 ++++++-------- src/privateer/cpp/privateer-json.h | 4 ++-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 656c594d4..5a92357f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,7 +47,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} checkout/libccp4/ccp4 checkout/clipper checkout/gemmi/include - dependencies/gemmi +# dependencies/gemmi checkout/zlib ${PRIVATEER_SOURCE_DIR}/cpp ${PRIVATEER_SOURCE_DIR}/cpp/pybind11 diff --git a/gemmi/CMakeLists.txt b/gemmi/CMakeLists.txt index 248b0b374..2473a78e0 100644 --- a/gemmi/CMakeLists.txt +++ b/gemmi/CMakeLists.txt @@ -17,15 +17,13 @@ endif() include_directories("${gemmi_src}/include" "${gemmi_src}/third_party") + +file(GLOB CPP_FILES ${gemmi_src}/src/*.cpp) + add_library(gemmi_cpp - ${gemmi_src}/src/align.cpp ${gemmi_src}/src/assembly.cpp ${gemmi_src}/src/calculate.cpp ${gemmi_src}/src/crd.cpp - ${gemmi_src}/src/ddl.cpp ${gemmi_src}/src/eig3.cpp ${gemmi_src}/src/gz.cpp ${gemmi_src}/src/intensit.cpp ${gemmi_src}/src/json.cpp - ${gemmi_src}/src/mmcif.cpp ${gemmi_src}/src/mmread_gz.cpp ${gemmi_src}/src/mtz.cpp ${gemmi_src}/src/mtz2cif.cpp - ${gemmi_src}/src/polyheur.cpp ${gemmi_src}/src/read_cif.cpp ${gemmi_src}/src/resinfo.cpp - ${gemmi_src}/src/riding_h.cpp ${gemmi_src}/src/sprintf.cpp ${gemmi_src}/src/to_mmcif.cpp - ${gemmi_src}/src/to_pdb.cpp ${gemmi_src}/src/monlib.cpp ${gemmi_src}/src/topo.cpp ${gemmi_src}/src/xds_ascii.cpp) - -#set_target_properties(gemmi_cpp PROPERTIES COMPILE_FLAGS "-fexceptions -pthread -s USE_ZLIB=1 -s USE_PTHREADS=1" ) + ${CPP_FILES}) + +#set_target_properties(gemmi_cpp PROPERTIES COMPILE_FLAGS "-fexceptions -pthread -s USE_ZLIB=1 -s USE_PTHREADS=1" ) ${gemmi_src}/src/gz.cpp file(GLOB HEADER_FILES ${gemmi_src}/include/gemmi/*.hpp) diff --git a/src/privateer/cpp/privateer-json.h b/src/privateer/cpp/privateer-json.h index cde837936..3ad594558 100644 --- a/src/privateer/cpp/privateer-json.h +++ b/src/privateer/cpp/privateer-json.h @@ -11,8 +11,8 @@ #include #include "privateer-error.h" -#include "third-party/sajson.h" // Have to include it straight from gemmi, as otherwise it leads to "error: multiple definition of ‘enum sajson::type’" errors. -// #include "gemmi/third_party/sajson.h" +// #include "third-party/sajson.h" // Have to include it straight from gemmi, as otherwise it leads to "error: multiple definition of ‘enum sajson::type’" errors. +#include "gemmi/third_party/sajson.h" #include #include #include // for FILE, fopen, fclose From f43858f796fcd8822945692c95fb219c43c67d1c Mon Sep 17 00:00:00 2001 From: Dialpuri Date: Mon, 24 Jun 2024 11:08:11 +0100 Subject: [PATCH 16/24] Updated cmake version in workflow --- .github/workflows/backend.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 3ede30291..42628319f 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -38,7 +38,7 @@ jobs: ls - name: Setup cmake - uses: jwlawson/actions-setup-cmake@v1.13 + uses: jwlawson/actions-setup-cmake@v2 - name: Build run : | From c61710d491ebcfc503f4747318d013752d9073d7 Mon Sep 17 00:00:00 2001 From: Dialpuri Date: Mon, 24 Jun 2024 11:13:46 +0100 Subject: [PATCH 17/24] Added base class definitions --- src/privateer/cpp/third-party/simdjson/simdjson.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/privateer/cpp/third-party/simdjson/simdjson.h b/src/privateer/cpp/third-party/simdjson/simdjson.h index 8f8141275..80e8efd57 100644 --- a/src/privateer/cpp/third-party/simdjson/simdjson.h +++ b/src/privateer/cpp/third-party/simdjson/simdjson.h @@ -6172,6 +6172,12 @@ class base_formatter { **/ simdjson_inline std::string_view str() const; + simdjson_inline void print_newline() {return; }; + + simdjson_inline void print_indents(size_t depth) {return; }; + + simdjson_inline void print_space() {return; }; + /** Prints one character **/ simdjson_inline void one_char(char c); From cac8d9816d9423cd3d0abbe0b655717da498ac79 Mon Sep 17 00:00:00 2001 From: Dialpuri Date: Mon, 24 Jun 2024 11:45:47 +0100 Subject: [PATCH 18/24] Removed testing parameter to cmake --- .github/workflows/backend.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 42628319f..6e82d42de 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -43,7 +43,7 @@ jobs: - name: Build run : | source ./emsdk/emsdk_env.sh - emcmake cmake . -D MODE=TESTING + emcmake cmake . emmake make -j \ No newline at end of file From 989cd8a50e50d3da381cdd364a03df2fadb8c701 Mon Sep 17 00:00:00 2001 From: Dialpuri Date: Mon, 24 Jun 2024 11:48:26 +0100 Subject: [PATCH 19/24] Download sources --- .github/workflows/backend.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 6e82d42de..811b05d42 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -36,6 +36,7 @@ jobs: cp -r * ../ cd .. ls + ./get_sources - name: Setup cmake uses: jwlawson/actions-setup-cmake@v2 From 67add2e47914c651260c70c32378e7fba03c573d Mon Sep 17 00:00:00 2001 From: Dialpuri Date: Mon, 24 Jun 2024 11:51:08 +0100 Subject: [PATCH 20/24] Removed download from gh --- .github/workflows/backend.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 811b05d42..b42a2539a 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -31,13 +31,8 @@ jobs: - name: Check out libraries run : | - git clone https://github.com/Dialpuri/privateer_webserver_dependencies.git - cd privateer_webserver_dependencies - cp -r * ../ - cd .. - ls ./get_sources - + - name: Setup cmake uses: jwlawson/actions-setup-cmake@v2 From 89e5eb1f051a31ea13e3435e04da48a2f5663d1e Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Mon, 1 Jul 2024 11:13:45 +0100 Subject: [PATCH 21/24] Update checkout source and improve zlib usage Updated source for checking out libccp4 and mmdb2 packages, replacing lightweight bzr checkout with tarball downloads to improve reliability and performance. Refactored CMakeLists.txt to better handle zlib inclusion, providing a fallback to a third-party source when not found in the system. --- CMakeLists.txt | 3 ++- gemmi/CMakeLists.txt | 6 ++++-- get_sources | 33 +++++++++++++++++++++------------ 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a92357f3..f52fa7122 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,7 +47,8 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} checkout/libccp4/ccp4 checkout/clipper checkout/gemmi/include -# dependencies/gemmi + checkout/gemmi + dependencies/gemmi checkout/zlib ${PRIVATEER_SOURCE_DIR}/cpp ${PRIVATEER_SOURCE_DIR}/cpp/pybind11 diff --git a/gemmi/CMakeLists.txt b/gemmi/CMakeLists.txt index 2473a78e0..66aef94d7 100644 --- a/gemmi/CMakeLists.txt +++ b/gemmi/CMakeLists.txt @@ -10,8 +10,10 @@ set(gemmi_src ../checkout/gemmi) find_package(ZLIB) if (ZLIB_FOUND) - include_directories("${ZLIB_INCLUDE_DIR}") - message(STATUS "The build will use zlib code from emscripten") + include_directories("${ZLIB_INCLUDE_DIR}") +else() + message(STATUS "The build will use zlib code from third_party/zlib.") + include_directories("${gemmi_src}/third_party/zlib") endif() include_directories("${gemmi_src}/include" diff --git a/get_sources b/get_sources index 19b8d8497..c48ca76a0 100755 --- a/get_sources +++ b/get_sources @@ -3,11 +3,17 @@ mkdir -p checkout cd checkout +libccp4_release="8.0.0" +mmdb_release="2.0.22" + + if [ -d "libccp4" ]; then echo "Found libccp4" else echo "Checking out libccp4" - bzr checkout --lightweight http://fg.oisin.rc-harwell.ac.uk/anonscm/bzr/libccp4/trunk/ libccp4 + curl -L http://ftp.ccp4.ac.uk/opensource/libccp4-$libccp4_release.tar.gz -o libccp4-$libccp4_release.tar.gz + tar xf libccp4-$libccp4_release.tar.gz + ln -s libccp4-$libccp4_release libccp4 echo fi @@ -16,8 +22,7 @@ if [ -d "clipper" ]; then echo "Found clipper" else echo "Checking out clipper" - curl -L http://www.ysbl.york.ac.uk/jsd523/clipper-gemmi-wrapper-20240603.tar.gz -o clipper-gemmi-wrapper.tar.gz - + curl -L http://www.ysbl.york.ac.uk/jsd523/clipper-gemmi-wrapper-20240603.tar.gz -o clipper-gemmi-wrapper.tar.gz tar xf clipper-gemmi-wrapper.tar.gz mv clipper-gemmi-wrapper clipper echo @@ -27,17 +32,21 @@ if [ -d "mmdb2" ]; then echo "Found mmdb2" else echo "Checking out mmdb2" -bzr checkout --lightweight http://fg.oisin.rc-harwell.ac.uk/anonscm/bzr/mmdb2/trunk/ mmdb2 -echo + curl -L http://ftp.ccp4.ac.uk/opensource/mmdb2-$mmdb_release.tar.gz -o mmdb2-$mmdb_release.tar.gz + echo + echo "Unpacking mmdb2 source" + tar xf mmdb2-$mmdb_release.tar.gz + rm -f mmdb2 + ln -s mmdb2-$mmdb_release mmdb2 fi -if [ -d "ccp4srs" ]; then - echo "Found ccp4srs" -else - echo "Checking out ccp4srs" - bzr checkout --lightweight http://fg.oisin.rc-harwell.ac.uk/anonscm/bzr/ccp4srs/trunk/ ccp4srs - echo -fi +#if [ -d "ccp4srs" ]; then +# echo "Found ccp4srs" +#else +# echo "Checking out ccp4srs" +# bzr checkout --lightweight http://fg.oisin.rc-harwell.ac.uk/anonscm/bzr/ccp4srs/trunk/ ccp4srs +# echo +#fi if [ -d "gemmi" ]; then echo "Found gemmi" From 6f2efb02a7c68f00f2ac3cc42dac223dbf4f058f Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Mon, 1 Jul 2024 11:13:53 +0100 Subject: [PATCH 22/24] Update sajson.h inclusion method in privateer-json.h The method of including the sajson.h header file has been changed from directly calling it from gemmi to calling it from a third-party location. --- src/privateer/cpp/privateer-json.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/privateer/cpp/privateer-json.h b/src/privateer/cpp/privateer-json.h index 3ad594558..cde837936 100644 --- a/src/privateer/cpp/privateer-json.h +++ b/src/privateer/cpp/privateer-json.h @@ -11,8 +11,8 @@ #include #include "privateer-error.h" -// #include "third-party/sajson.h" // Have to include it straight from gemmi, as otherwise it leads to "error: multiple definition of ‘enum sajson::type’" errors. -#include "gemmi/third_party/sajson.h" +#include "third-party/sajson.h" // Have to include it straight from gemmi, as otherwise it leads to "error: multiple definition of ‘enum sajson::type’" errors. +// #include "gemmi/third_party/sajson.h" #include #include #include // for FILE, fopen, fclose From 564433ff3398ff33c7829c3dc8447d810f099126 Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Mon, 1 Jul 2024 11:14:03 +0100 Subject: [PATCH 23/24] Update puppeteer to version 22.12.1 This update includes changes in webapp/package-lock.json that reflect the updated puppeteer version and related dependencies. It --- webapp/package-lock.json | 401 ++++++++++++++++++++++++--------------- webapp/package.json | 2 +- 2 files changed, 250 insertions(+), 153 deletions(-) diff --git a/webapp/package-lock.json b/webapp/package-lock.json index d330dcd20..08ddae380 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -17,7 +17,7 @@ "moorhen": "file:moorhen-0.6.7.tgz", "pako": "^2.1.0", "plotly.js": "^2.26.0", - "puppeteer": "^21.6.1", + "puppeteer": "^22.12.1", "react": "^18.2.0", "react-collapsed": "^4.1.2", "react-dom": "^18.2.0", @@ -3115,15 +3115,16 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.9.0.tgz", - "integrity": "sha512-QwguOLy44YBGC8vuPP2nmpX4MUN2FzWbsnvZJtiCzecU3lHmVZkaC1tq6rToi9a200m8RzlVtDyxCS0UIDrxUg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.3.tgz", + "integrity": "sha512-bJ0UBsk0ESOs6RFcLXOt99a3yTDcOKlzfjad+rhFwdaG1Lu/Wzq58GHYCDTlZ9z6mldf4g+NTb+TXEfe0PpnsQ==", "dependencies": { "debug": "4.3.4", "extract-zip": "2.0.1", "progress": "2.0.3", - "proxy-agent": "6.3.1", - "tar-fs": "3.0.4", + "proxy-agent": "6.4.0", + "semver": "7.6.0", + "tar-fs": "3.0.5", "unbzip2-stream": "1.4.3", "yargs": "17.7.2" }, @@ -3131,9 +3132,39 @@ "browsers": "lib/cjs/main-cli.js" }, "engines": { - "node": ">=16.3.0" + "node": ">=18" + } + }, + "node_modules/@puppeteer/browsers/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@puppeteer/browsers/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, + "node_modules/@puppeteer/browsers/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/@remix-run/router": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.13.0.tgz", @@ -3998,9 +4029,9 @@ } }, "node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dependencies": { "debug": "^4.3.4" }, @@ -4390,9 +4421,9 @@ } }, "node_modules/b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" }, "node_modules/babel-jest": { "version": "29.7.0", @@ -4561,6 +4592,47 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/bare-events": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.1.tgz", + "integrity": "sha512-W/Hfxc/6VehXlsgFtbB5B4xFcsCl+pAh30cYhoFyXErf6oGrwjh8SwiPAdHgpmWonKuYpZgGywN0SXt7dgsADA==", + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.0.0" + } + }, + "node_modules/bare-os": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.0.tgz", + "integrity": "sha512-v8DTT08AS/G0F9xrhyLtepoo9EJBJ85FRSMbu1pQUlAf6A8T0tEEQGMVObWeqpjhSPXsE0VGlluFBJu2fdoTNg==", + "optional": true + }, + "node_modules/bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "node_modules/bare-stream": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.1.3.tgz", + "integrity": "sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ==", + "optional": true, + "dependencies": { + "streamx": "^2.18.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -4581,9 +4653,9 @@ ] }, "node_modules/basic-ftp": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.4.tgz", - "integrity": "sha512-8PzkB0arJFV4jJWSGOYR+OEic6aeKMu/osRhBULN6RY0ykby6LKhbmuQ5ublvaas5BOwboah5D87nrHyuh8PPA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", "engines": { "node": ">=10.0.0" } @@ -4982,12 +5054,13 @@ } }, "node_modules/chromium-bidi": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.1.tgz", - "integrity": "sha512-dcCqOgq9fHKExc2R4JZs/oKbOghWpUNFAJODS8WKRtLhp3avtIH5UDCBrutdqZdh3pARogH8y1ObXm87emwb3g==", + "version": "0.5.24", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.24.tgz", + "integrity": "sha512-5xQNN2SVBdZv4TxeMLaI+PelrnZsHDhn8h2JtyriLr+0qHcZS8BMuo93qN6J1VmtmrgYP+rmcLHcbpnA8QJh+w==", "dependencies": { "mitt": "3.0.1", - "urlpattern-polyfill": "9.0.0" + "urlpattern-polyfill": "10.0.0", + "zod": "3.23.8" }, "peerDependencies": { "devtools-protocol": "*" @@ -5353,14 +5426,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", - "dependencies": { - "node-fetch": "^2.6.12" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -5620,9 +5685,9 @@ "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==" }, "node_modules/data-uri-to-buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", - "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", "engines": { "node": ">= 14" } @@ -5776,9 +5841,9 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.1203626", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1203626.tgz", - "integrity": "sha512-nEzHZteIUZfGCZtTiS1fRpC8UZmsfD1SiyPvaUNvS13dvKf666OAm8YTi0+Ca3n1nLEyu49Cy4+dPWpaHFJk9g==" + "version": "0.0.1299070", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1299070.tgz", + "integrity": "sha512-+qtL3eX50qsJ7c+qVyagqi7AWMoQCBGNfoyJZMwm/NSXVqLYbuitrWEEIzxfUmTNy7//Xe8yhMmQ+elj3uAqSg==" }, "node_modules/didyoumean": { "version": "1.2.2", @@ -5909,6 +5974,14 @@ "once": "^1.4.0" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -7178,16 +7251,16 @@ } }, "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dependencies": { "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=6 <7 || >=8" + "node": ">=14.14" } }, "node_modules/fs-readdir-recursive": { @@ -7337,14 +7410,14 @@ } }, "node_modules/get-uri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.2.tgz", - "integrity": "sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", "dependencies": { "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.0", + "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4", - "fs-extra": "^8.1.0" + "fs-extra": "^11.2.0" }, "engines": { "node": ">= 14" @@ -7895,9 +7968,9 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" }, "node_modules/http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -7907,9 +7980,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -9442,9 +9515,12 @@ } }, "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -9723,11 +9799,6 @@ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" - }, "node_modules/moorhen": { "version": "0.6.7", "resolved": "file:moorhen-0.6.7.tgz", @@ -9864,25 +9935,6 @@ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -10156,18 +10208,18 @@ } }, "node_modules/pac-proxy-agent": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", - "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", + "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.0.2", "debug": "^4.3.4", "get-uri": "^6.0.1", "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", - "pac-resolver": "^7.0.0", - "socks-proxy-agent": "^8.0.2" + "https-proxy-agent": "^7.0.5", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.4" }, "engines": { "node": ">= 14" @@ -10735,14 +10787,14 @@ "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" }, "node_modules/proxy-agent": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz", - "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", "lru-cache": "^7.14.1", "pac-proxy-agent": "^7.0.1", "proxy-from-env": "^1.1.0", @@ -10783,36 +10835,77 @@ } }, "node_modules/puppeteer": { - "version": "21.6.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-21.6.1.tgz", - "integrity": "sha512-O+pbc61oj8ln6m8EJKncrsQFmytgRyFYERtk190PeLbJn5JKpmmynn2p1PiFrlhCitAQXLJ0MOy7F0TeyCRqBg==", + "version": "22.12.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.12.1.tgz", + "integrity": "sha512-1GxY8dnEnHr1SLzdSDr0FCjM6JQfAh2E2I/EqzeF8a58DbGVk9oVjj4lFdqNoVbpgFSpAbz7VER9St7S1wDpNg==", "hasInstallScript": true, "dependencies": { - "@puppeteer/browsers": "1.9.0", - "cosmiconfig": "8.3.6", - "puppeteer-core": "21.6.1" + "@puppeteer/browsers": "2.2.3", + "cosmiconfig": "^9.0.0", + "devtools-protocol": "0.0.1299070", + "puppeteer-core": "22.12.1" }, "bin": { "puppeteer": "lib/esm/puppeteer/node/cli.js" }, "engines": { - "node": ">=16.13.2" + "node": ">=18" } }, "node_modules/puppeteer-core": { - "version": "21.6.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.6.1.tgz", - "integrity": "sha512-0chaaK/RL9S1U3bsyR4fUeUfoj51vNnjWvXgG6DcsyMjwYNpLcAThv187i1rZCo7QhJP0wZN8plQkjNyrq2h+A==", + "version": "22.12.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.12.1.tgz", + "integrity": "sha512-XmqeDPVdC5/3nGJys1jbgeoZ02wP0WV1GBlPtr/ULRbGXJFuqgXMcKQ3eeNtFpBzGRbpeoCGWHge1ZWKWl0Exw==", "dependencies": { - "@puppeteer/browsers": "1.9.0", - "chromium-bidi": "0.5.1", - "cross-fetch": "4.0.0", - "debug": "4.3.4", - "devtools-protocol": "0.0.1203626", - "ws": "8.15.1" + "@puppeteer/browsers": "2.2.3", + "chromium-bidi": "0.5.24", + "debug": "^4.3.5", + "devtools-protocol": "0.0.1299070", + "ws": "^8.17.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/puppeteer-core/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/puppeteer/node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" }, "engines": { - "node": ">=16.13.2" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/pure-rand": { @@ -11872,13 +11965,13 @@ } }, "node_modules/socks-proxy-agent": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz", - "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", + "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.1", "debug": "^4.3.4", - "socks": "^2.7.1" + "socks": "^2.8.3" }, "engines": { "node": ">= 14" @@ -11999,12 +12092,16 @@ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" }, "node_modules/streamx": { - "version": "2.15.6", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz", - "integrity": "sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", + "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", "dependencies": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" } }, "node_modules/string_decoder": { @@ -12405,19 +12502,22 @@ } }, "node_modules/tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.5.tgz", + "integrity": "sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==", "dependencies": { - "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" } }, "node_modules/tar-stream": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", - "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", @@ -12437,6 +12537,14 @@ "node": ">=8" } }, + "node_modules/text-decoder": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", + "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", + "dependencies": { + "b4a": "^1.6.4" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -12548,11 +12656,6 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -12803,11 +12906,11 @@ } }, "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "engines": { - "node": ">= 4.0.0" + "node": ">= 10.0.0" } }, "node_modules/unquote": { @@ -12867,9 +12970,9 @@ } }, "node_modules/urlpattern-polyfill": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", - "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==" + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==" }, "node_modules/use-sync-external-store": { "version": "1.2.0", @@ -13062,20 +13165,6 @@ "get-canvas-context": "^1.0.1" } }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -13266,9 +13355,9 @@ } }, "node_modules/ws": { - "version": "8.15.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", - "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "engines": { "node": ">=10.0.0" }, @@ -13386,6 +13475,14 @@ "engines": { "node": ">=0.2.0" } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/webapp/package.json b/webapp/package.json index 823f1ee68..112be7c68 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -22,7 +22,7 @@ "moorhen": "file:moorhen-0.6.7.tgz", "pako": "^2.1.0", "plotly.js": "^2.26.0", - "puppeteer": "^21.6.1", + "puppeteer": "^22.12.1", "react": "^18.2.0", "react-collapsed": "^4.1.2", "react-dom": "^18.2.0", From 3cff51cd972188a678ed512a4affdcddbff53d8f Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Mon, 1 Jul 2024 11:14:18 +0100 Subject: [PATCH 24/24] Updated JS and WASM blobs --- webapp/src/wasm/privateer.js | 8368 +------------------------------- webapp/src/wasm/privateer.wasm | Bin 1978727 -> 1994616 bytes 2 files changed, 11 insertions(+), 8357 deletions(-) diff --git a/webapp/src/wasm/privateer.js b/webapp/src/wasm/privateer.js index 301dc9e90..aabaf3066 100644 --- a/webapp/src/wasm/privateer.js +++ b/webapp/src/wasm/privateer.js @@ -1,8362 +1,16 @@ + var privateer_module = (() => { - var _scriptDir = import.meta.url; + var _scriptName = import.meta.url; + + return ( +async function(moduleArg = {}) { + var moduleRtn; + +var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;var readyPromise=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject});["getExceptionMessage","incrementExceptionRefcount","decrementExceptionRefcount","_memory","___indirect_function_table","___set_stack_limits","onRuntimeInitialized"].forEach(prop=>{if(!Object.getOwnPropertyDescriptor(readyPromise,prop)){Object.defineProperty(readyPromise,prop,{get:()=>abort("You are getting "+prop+" on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js"),set:()=>abort("You are setting "+prop+" on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")})}});var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";var ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(Module["ENVIRONMENT"]){throw new Error("Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)")}if(ENVIRONMENT_IS_NODE){const{createRequire:createRequire}=await import("module");var require=createRequire(import.meta.url)}if(!Module.expectedDataFileDownloads){Module.expectedDataFileDownloads=0}Module.expectedDataFileDownloads++;(()=>{var isPthread=typeof ENVIRONMENT_IS_PTHREAD!="undefined"&&ENVIRONMENT_IS_PTHREAD;var isWasmWorker=typeof ENVIRONMENT_IS_WASM_WORKER!="undefined"&&ENVIRONMENT_IS_WASM_WORKER;if(isPthread||isWasmWorker)return;function loadPackage(metadata){var PACKAGE_PATH="";if(typeof window==="object"){PACKAGE_PATH=window["encodeURIComponent"](window.location.pathname.toString().substring(0,window.location.pathname.toString().lastIndexOf("/"))+"/")}else if(typeof process==="undefined"&&typeof location!=="undefined"){PACKAGE_PATH=encodeURIComponent(location.pathname.toString().substring(0,location.pathname.toString().lastIndexOf("/"))+"/")}var PACKAGE_NAME="privateer.data";var REMOTE_PACKAGE_BASE="privateer.data";if(typeof Module["locateFilePackage"]==="function"&&!Module["locateFile"]){Module["locateFile"]=Module["locateFilePackage"];err("warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)")}var REMOTE_PACKAGE_NAME=Module["locateFile"]?Module["locateFile"](REMOTE_PACKAGE_BASE,""):REMOTE_PACKAGE_BASE;var REMOTE_PACKAGE_SIZE=metadata["remote_package_size"];function fetchRemotePackage(packageName,packageSize,callback,errback){if(typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string"){require("fs").readFile(packageName,function(err,contents){if(err){errback(err)}else{callback(contents.buffer)}});return}var xhr=new XMLHttpRequest;xhr.open("GET",packageName,true);xhr.responseType="arraybuffer";xhr.onprogress=function(event){var url=packageName;var size=packageSize;if(event.total)size=event.total;if(event.loaded){if(!xhr.addedTotal){xhr.addedTotal=true;if(!Module.dataFileDownloads)Module.dataFileDownloads={};Module.dataFileDownloads[url]={loaded:event.loaded,total:size}}else{Module.dataFileDownloads[url].loaded=event.loaded}var total=0;var loaded=0;var num=0;for(var download in Module.dataFileDownloads){var data=Module.dataFileDownloads[download];total+=data.total;loaded+=data.loaded;num++}total=Math.ceil(total*Module.expectedDataFileDownloads/num);if(Module["setStatus"])Module["setStatus"](`Downloading data... (${loaded}/${total})`)}else if(!Module.dataFileDownloads){if(Module["setStatus"])Module["setStatus"]("Downloading data...")}};xhr.onerror=function(event){throw new Error("NetworkError for: "+packageName)};xhr.onload=function(event){if(xhr.status==200||xhr.status==304||xhr.status==206||xhr.status==0&&xhr.response){var packageData=xhr.response;callback(packageData)}else{throw new Error(xhr.statusText+" : "+xhr.responseURL)}};xhr.send(null)}function handleError(error){console.error("package error:",error)}var fetchedCallback=null;var fetched=Module["getPreloadedPackage"]?Module["getPreloadedPackage"](REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE):null;if(!fetched)fetchRemotePackage(REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE,function(data){if(fetchedCallback){fetchedCallback(data);fetchedCallback=null}else{fetched=data}},handleError);function runWithFS(){function assert(check,msg){if(!check)throw msg+(new Error).stack}Module["FS_createPath"]("/","unprocessed_files",true,true);function DataRequest(start,end,audio){this.start=start;this.end=end;this.audio=audio}DataRequest.prototype={requests:{},open:function(mode,name){this.name=name;this.requests[name]=this;Module["addRunDependency"](`fp ${this.name}`)},send:function(){},onload:function(){var byteArray=this.byteArray.subarray(this.start,this.end);this.finish(byteArray)},finish:function(byteArray){var that=this;Module["FS_createDataFile"](this.name,null,byteArray,true,true,true);Module["removeRunDependency"](`fp ${that.name}`);this.requests[this.name]=null}};var files=metadata["files"];for(var i=0;i{if(Module["preRun"].indexOf(task)<0)throw"All preRun tasks that exist before user pre-js code should remain after; did you replace Module or modify Module.preRun?"});var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary;if(ENVIRONMENT_IS_NODE){if(typeof process=="undefined"||!process.release||process.release.name!=="node")throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");var nodeVersion=process.versions.node;var numericVersion=nodeVersion.split(".").slice(0,3);numericVersion=numericVersion[0]*1e4+numericVersion[1]*100+numericVersion[2].split("-")[0]*1;if(numericVersion<16e4){throw new Error("This emscripten-generated code requires node v16.0.0 (detected v"+nodeVersion+")")}var fs=require("fs");var nodePath=require("path");scriptDirectory=require("url").fileURLToPath(new URL("./",import.meta.url));read_=(filename,binary)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);return fs.readFileSync(filename,binary?undefined:"utf8")};readBinary=filename=>{var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};readAsync=(filename,onload,onerror,binary=true)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);fs.readFile(filename,binary?undefined:"utf8",(err,data)=>{if(err)onerror(err);else onload(binary?data.buffer:data)})};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_SHELL){if(typeof process=="object"&&typeof require==="function"||typeof window=="object"||typeof importScripts=="function")throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)")}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptName){scriptDirectory=_scriptName}if(scriptDirectory.startsWith("blob:")){scriptDirectory=""}else{scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}if(!(typeof window=="object"||typeof importScripts=="function"))throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{if(isFileURI(url)){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null);return}fetch(url,{credentials:"same-origin"}).then(response=>{if(response.ok){return response.arrayBuffer()}return Promise.reject(new Error(response.status+" : "+response.url))}).then(onload,onerror)}}}else{throw new Error("environment detection error")}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;checkIncomingModuleAPI();if(Module["arguments"])arguments_=Module["arguments"];legacyModuleProp("arguments","arguments_");if(Module["thisProgram"])thisProgram=Module["thisProgram"];legacyModuleProp("thisProgram","thisProgram");if(Module["quit"])quit_=Module["quit"];legacyModuleProp("quit","quit_");assert(typeof Module["memoryInitializerPrefixURL"]=="undefined","Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["pthreadMainPrefixURL"]=="undefined","Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["cdInitializerPrefixURL"]=="undefined","Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["filePackagePrefixURL"]=="undefined","Module.filePackagePrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["read"]=="undefined","Module.read option was removed (modify read_ in JS)");assert(typeof Module["readAsync"]=="undefined","Module.readAsync option was removed (modify readAsync in JS)");assert(typeof Module["readBinary"]=="undefined","Module.readBinary option was removed (modify readBinary in JS)");assert(typeof Module["setWindowTitle"]=="undefined","Module.setWindowTitle option was removed (modify emscripten_set_window_title in JS)");assert(typeof Module["TOTAL_MEMORY"]=="undefined","Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY");legacyModuleProp("asm","wasmExports");legacyModuleProp("read","read_");legacyModuleProp("readAsync","readAsync");legacyModuleProp("readBinary","readBinary");legacyModuleProp("setWindowTitle","setWindowTitle");assert(!ENVIRONMENT_IS_SHELL,"shell environment detected but not enabled at build time. Add `shell` to `-sENVIRONMENT` to enable.");var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];legacyModuleProp("wasmBinary","wasmBinary");if(typeof WebAssembly!="object"){err("no native wasm support detected")}function intArrayFromBase64(s){if(typeof ENVIRONMENT_IS_NODE!="undefined"&&ENVIRONMENT_IS_NODE){var buf=Buffer.from(s,"base64");return new Uint8Array(buf.buffer,buf.byteOffset,buf.length)}var decoded=atob(s);var bytes=new Uint8Array(decoded.length);for(var i=0;i>2]=34821223;checkInt32(34821223);HEAPU32[max+4>>2]=2310721022;checkInt32(2310721022);HEAPU32[0>>2]=1668509029;checkInt32(1668509029)}function checkStackCookie(){if(ABORT)return;var max=_emscripten_stack_get_end();if(max==0){max+=4}var cookie1=HEAPU32[max>>2];var cookie2=HEAPU32[max+4>>2];if(cookie1!=34821223||cookie2!=2310721022){abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString(cookie2)} ${ptrToString(cookie1)}`)}if(HEAPU32[0>>2]!=1668509029){abort("Runtime error: The application has corrupted its heap memory area (address zero)!")}}(function(){var h16=new Int16Array(1);var h8=new Int8Array(h16.buffer);h16[0]=25459;if(h8[0]!==115||h8[1]!==99)throw"Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)"})();var __ATPRERUN__=[];var __ATINIT__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){assert(!runtimeInitialized);runtimeInitialized=true;checkStackCookie();setStackLimits();if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();FS.ignorePermissions=false;TTY.init();callRuntimeCallbacks(__ATINIT__)}function postRun(){checkStackCookie();if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}assert(Math.imul,"This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.fround,"This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.clz32,"This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.trunc,"This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;var runDependencyTracking={};function getUniqueRunDependency(id){var orig=id;while(1){if(!runDependencyTracking[id])return id;id=orig+Math.random()}}function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies);if(id){assert(!runDependencyTracking[id]);runDependencyTracking[id]=1;if(runDependencyWatcher===null&&typeof setInterval!="undefined"){runDependencyWatcher=setInterval(()=>{if(ABORT){clearInterval(runDependencyWatcher);runDependencyWatcher=null;return}var shown=false;for(var dep in runDependencyTracking){if(!shown){shown=true;err("still waiting on run dependencies:")}err(`dependency: ${dep}`)}if(shown){err("(end of list)")}},1e4)}}else{err("warning: run dependency added without ID")}}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(id){assert(runDependencyTracking[id]);delete runDependencyTracking[id]}else{err("warning: run dependency removed without ID")}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;if(runtimeInitialized){___trap()}var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";var isDataURI=filename=>filename.startsWith(dataURIPrefix);var isFileURI=filename=>filename.startsWith("file://");function createExportWrapper(name,nargs){return(...args)=>{assert(runtimeInitialized,`native function \`${name}\` called before runtime initialization`);assert(!runtimeExited,`native function \`${name}\` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)`);var f=wasmExports[name];assert(f,`exported native function \`${name}\` not found`);assert(args.length<=nargs,`native function \`${name}\` called with ${args.length} args but expects ${nargs}`);return f(...args)}}function findWasmBinary(){if(Module["locateFile"]){var f="privateer.wasm";if(!isDataURI(f)){return locateFile(f)}return f}return new URL("privateer.wasm",import.meta.url).href}var wasmBinaryFile;function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}function getBinaryPromise(binaryFile){if(!wasmBinary){return new Promise((resolve,reject)=>{readAsync(binaryFile,response=>resolve(new Uint8Array(response)),error=>{try{resolve(getBinarySync(binaryFile))}catch(e){reject(e)}})})}return Promise.resolve().then(()=>getBinarySync(binaryFile))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then(binary=>WebAssembly.instantiate(binary,imports)).then(receiver,reason=>{err(`failed to asynchronously prepare wasm: ${reason}`);if(isFileURI(wasmBinaryFile)){err(`warning: Loading from a file URI (${wasmBinaryFile}) is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing`)}abort(reason)})}function instantiateAsync(binary,binaryFile,imports,callback){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then(response=>{var result=WebAssembly.instantiateStreaming(response,imports);return result.then(callback,function(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(binaryFile,imports,callback)})})}return instantiateArrayBuffer(binaryFile,imports,callback)}function getWasmImports(){return{env:wasmImports,wasi_snapshot_preview1:wasmImports}}function createWasm(){var info=getWasmImports();function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["memory"];assert(wasmMemory,"memory not found in wasm exports");updateMemoryViews();wasmTable=wasmExports["__indirect_function_table"];assert(wasmTable,"table not found in wasm exports");addOnInit(wasmExports["__wasm_call_ctors"]);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");var trueModule=Module;function receiveInstantiationResult(result){assert(Module===trueModule,"the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?");trueModule=null;receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err(`Module.instantiateWasm callback failed with error: ${e}`);readyPromiseReject(e)}}if(!wasmBinaryFile)wasmBinaryFile=findWasmBinary();instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult).catch(readyPromiseReject);return{}}var tempDouble;var tempI64;function legacyModuleProp(prop,newName,incoming=true){if(!Object.getOwnPropertyDescriptor(Module,prop)){Object.defineProperty(Module,prop,{configurable:true,get(){let extra=incoming?" (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)":"";abort(`\`Module.${prop}\` has been replaced by \`${newName}\``+extra)}})}}function ignoredModuleProp(prop){if(Object.getOwnPropertyDescriptor(Module,prop)){abort(`\`Module.${prop}\` was supplied but \`${prop}\` not included in INCOMING_MODULE_JS_API`)}}function isExportedByForceFilesystem(name){return name==="FS_createPath"||name==="FS_createDataFile"||name==="FS_createPreloadedFile"||name==="FS_unlink"||name==="addRunDependency"||name==="FS_createLazyFile"||name==="FS_createDevice"||name==="removeRunDependency"}function missingGlobal(sym,msg){if(typeof globalThis!="undefined"){Object.defineProperty(globalThis,sym,{configurable:true,get(){warnOnce(`\`${sym}\` is not longer defined by emscripten. ${msg}`);return undefined}})}}missingGlobal("buffer","Please use HEAP8.buffer or wasmMemory.buffer");missingGlobal("asm","Please use wasmExports instead");function missingLibrarySymbol(sym){if(typeof globalThis!="undefined"&&!Object.getOwnPropertyDescriptor(globalThis,sym)){Object.defineProperty(globalThis,sym,{configurable:true,get(){var msg=`\`${sym}\` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line`;var librarySymbol=sym;if(!librarySymbol.startsWith("_")){librarySymbol="$"+sym}msg+=` (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='${librarySymbol}')`;if(isExportedByForceFilesystem(sym)){msg+=". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"}warnOnce(msg);return undefined}})}unexportedRuntimeSymbol(sym)}function unexportedRuntimeSymbol(sym){if(!Object.getOwnPropertyDescriptor(Module,sym)){Object.defineProperty(Module,sym,{configurable:true,get(){var msg=`'${sym}' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)`;if(isExportedByForceFilesystem(sym)){msg+=". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"}abort(msg)}})}}var MAX_UINT8=2**8-1;var MAX_UINT16=2**16-1;var MAX_UINT32=2**32-1;var MAX_UINT53=2**53-1;var MAX_UINT64=2**64-1;var MIN_INT8=-(2**(8-1))+1;var MIN_INT16=-(2**(16-1))+1;var MIN_INT32=-(2**(32-1))+1;var MIN_INT53=-(2**(53-1))+1;var MIN_INT64=-(2**(64-1))+1;function checkInt(value,bits,min,max){assert(Number.isInteger(Number(value)),`attempt to write non-integer (${value}) into integer heap`);assert(value<=max,`value (${value}) too large to write as ${bits}-bit value`);assert(value>=min,`value (${value}) too small to write as ${bits}-bit value`)}var checkInt8=value=>checkInt(value,8,MIN_INT8,MAX_UINT8);var checkInt16=value=>checkInt(value,16,MIN_INT16,MAX_UINT16);var checkInt32=value=>checkInt(value,32,MIN_INT32,MAX_UINT32);var checkInt64=value=>checkInt(value,64,MIN_INT64,MAX_UINT64);function dbg(...args){console.warn(...args)}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var noExitRuntime=Module["noExitRuntime"]||false;var ptrToString=ptr=>{assert(typeof ptr==="number");ptr>>>=0;return"0x"+ptr.toString(16).padStart(8,"0")};var setStackLimits=()=>{var stackLow=_emscripten_stack_get_base();var stackHigh=_emscripten_stack_get_end();___set_stack_limits(stackLow,stackHigh)};var warnOnce=text=>{warnOnce.shown||={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;if(ENVIRONMENT_IS_NODE)text="warning: "+text;err(text)}};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):undefined;var UTF8ArrayToString=(heapOrArray,idx,maxBytesToRead)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>{assert(typeof ptr=="number",`UTF8ToString expects a number (got ${typeof ptr})`);return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""};var ___assert_fail=(condition,filename,line,func)=>{abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"])};var ___handle_stack_overflow=requested=>{var base=_emscripten_stack_get_base();var end=_emscripten_stack_get_end();abort(`stack overflow (Attempt to set SP to ${ptrToString(requested)}`+`, with stack limits [${ptrToString(end)} - ${ptrToString(base)}`+"]). If you require more stack space build with -sSTACK_SIZE=")};function syscallGetVarargI(){assert(SYSCALLS.varargs!=undefined);var ret=HEAP32[+SYSCALLS.varargs>>2];SYSCALLS.varargs+=4;return ret}var syscallGetVarargP=syscallGetVarargI;var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:path=>{if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},join:(...paths)=>PATH.normalize(paths.join("/")),join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>{if(typeof crypto=="object"&&typeof crypto["getRandomValues"]=="function"){return view=>crypto.getRandomValues(view)}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");var randomFillSync=crypto_module["randomFillSync"];if(randomFillSync){return view=>crypto_module["randomFillSync"](view)}var randomBytes=crypto_module["randomBytes"];return view=>(view.set(randomBytes(view.byteLength)),view)}catch(e){}}abort("no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: (array) => { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };")};var randomFill=view=>(randomFill=initRandomFill())(view);var PATH_FS={resolve:(...args)=>{var resolvedPath="",resolvedAbsolute=false;for(var i=args.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?args[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{assert(typeof str==="string",`stringToUTF8Array expects a string (got ${typeof str})`);if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;if(u>1114111)warnOnce("Invalid Unicode code point "+ptrToString(u)+" encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).");heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx};function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc(BUFSIZE);var bytesRead=0;var fd=process.stdin.fd;try{bytesRead=fs.readSync(fd,buf,0,BUFSIZE)}catch(e){if(e.toString().includes("EOF"))bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else{}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init(){},shutdown(){},register(dev,ops){TTY.ttys[dev]={input:[],output:[],ops:ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close(stream){stream.tty.ops.fsync(stream.tty)},fsync(stream){stream.tty.ops.fsync(stream.tty)},read(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}},ioctl_tcgets(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets(tty,optional_actions,data){return 0},ioctl_tiocgwinsz(tty){return[24,80]}},default_tty1_ops:{put_char(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};var zeroMemory=(address,size)=>{HEAPU8.fill(0,address,address+size);return address};var alignMemory=(size,alignment)=>{assert(alignment,"alignment argument is required");return Math.ceil(size/alignment)*alignment};var mmapAlloc=size=>{size=alignMemory(size,65536);var ptr=_emscripten_builtin_memalign(65536,size);if(!ptr)return 0;return zeroMemory(ptr,size)};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}MEMFS.ops_table||={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}};var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){throw FS.genericErrors[44]},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp},unlink(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir(node){var entries=[".",".."];for(var key of Object.keys(node.contents)){entries.push(key)}return entries},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);assert(size>=0);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var dep=!noRunDep?getUniqueRunDependency(`al ${url}`):"";readAsync(url,arrayBuffer=>{assert(arrayBuffer,`Loading data file "${url}" failed (no arrayBuffer).`);onload(new Uint8Array(arrayBuffer));if(dep)removeRunDependency(dep)},event=>{if(onerror){onerror()}else{throw`Loading data file "${url}" failed.`}});if(dep)addRunDependency(dep)};var FS_createDataFile=(parent,name,fileData,canRead,canWrite,canOwn)=>{FS.createDataFile(parent,name,fileData,canRead,canWrite,canOwn)};var preloadPlugins=Module["preloadPlugins"]||[];var FS_handledByPreloadPlugin=(byteArray,fullname,finish,onerror)=>{if(typeof Browser!="undefined")Browser.init();var handled=false;preloadPlugins.forEach(plugin=>{if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,onerror);handled=true}});return handled};var FS_createPreloadedFile=(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);function processData(byteArray){function finish(byteArray){preFinish?.();if(!dontCreateFile){FS_createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}onload?.();removeRunDependency(dep)}if(FS_handledByPreloadPlugin(byteArray,fullname,finish,()=>{onerror?.();removeRunDependency(dep)})){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url,processData,onerror)}else{processData(url)}};var FS_modeStringToFlags=str=>{var flagModes={r:0,"r+":2,w:512|64|1,"w+":512|64|2,a:1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags};var FS_getMode=(canRead,canWrite)=>{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode};var ERRNO_CODES={EPERM:63,ENOENT:44,ESRCH:71,EINTR:27,EIO:29,ENXIO:60,E2BIG:1,ENOEXEC:45,EBADF:8,ECHILD:12,EAGAIN:6,EWOULDBLOCK:6,ENOMEM:48,EACCES:2,EFAULT:21,ENOTBLK:105,EBUSY:10,EEXIST:20,EXDEV:75,ENODEV:43,ENOTDIR:54,EISDIR:31,EINVAL:28,ENFILE:41,EMFILE:33,ENOTTY:59,ETXTBSY:74,EFBIG:22,ENOSPC:51,ESPIPE:70,EROFS:69,EMLINK:34,EPIPE:64,EDOM:18,ERANGE:68,ENOMSG:49,EIDRM:24,ECHRNG:106,EL2NSYNC:156,EL3HLT:107,EL3RST:108,ELNRNG:109,EUNATCH:110,ENOCSI:111,EL2HLT:112,EDEADLK:16,ENOLCK:46,EBADE:113,EBADR:114,EXFULL:115,ENOANO:104,EBADRQC:103,EBADSLT:102,EDEADLOCK:16,EBFONT:101,ENOSTR:100,ENODATA:116,ETIME:117,ENOSR:118,ENONET:119,ENOPKG:120,EREMOTE:121,ENOLINK:47,EADV:122,ESRMNT:123,ECOMM:124,EPROTO:65,EMULTIHOP:36,EDOTDOT:125,EBADMSG:9,ENOTUNIQ:126,EBADFD:127,EREMCHG:128,ELIBACC:129,ELIBBAD:130,ELIBSCN:131,ELIBMAX:132,ELIBEXEC:133,ENOSYS:52,ENOTEMPTY:55,ENAMETOOLONG:37,ELOOP:32,EOPNOTSUPP:138,EPFNOSUPPORT:139,ECONNRESET:15,ENOBUFS:42,EAFNOSUPPORT:5,EPROTOTYPE:67,ENOTSOCK:57,ENOPROTOOPT:50,ESHUTDOWN:140,ECONNREFUSED:14,EADDRINUSE:3,ECONNABORTED:13,ENETUNREACH:40,ENETDOWN:38,ETIMEDOUT:73,EHOSTDOWN:142,EHOSTUNREACH:23,EINPROGRESS:26,EALREADY:7,EDESTADDRREQ:17,EMSGSIZE:35,EPROTONOSUPPORT:66,ESOCKTNOSUPPORT:137,EADDRNOTAVAIL:4,ENETRESET:39,EISCONN:30,ENOTCONN:53,ETOOMANYREFS:141,EUSERS:136,EDQUOT:19,ESTALE:72,ENOTSUP:138,ENOMEDIUM:148,EILSEQ:25,EOVERFLOW:61,ECANCELED:11,ENOTRECOVERABLE:56,EOWNERDEAD:62,ESTRPIPE:135};var NODEFS={isWindows:false,staticInit(){NODEFS.isWindows=!!process.platform.match(/^win/);var flags=process.binding("constants");if(flags["fs"]){flags=flags["fs"]}NODEFS.flagsForNodeMap={1024:flags["O_APPEND"],64:flags["O_CREAT"],128:flags["O_EXCL"],256:flags["O_NOCTTY"],0:flags["O_RDONLY"],2:flags["O_RDWR"],4096:flags["O_SYNC"],512:flags["O_TRUNC"],1:flags["O_WRONLY"],131072:flags["O_NOFOLLOW"]};assert(NODEFS.flagsForNodeMap["0"]===0)},convertNodeCode(e){var code=e.code;assert(code in ERRNO_CODES,`unexpected node error code: ${code} (${e})`);return ERRNO_CODES[code]},tryFSOperation(f){try{return f()}catch(e){if(!e.code)throw e;if(e.code==="UNKNOWN")throw new FS.ErrnoError(28);throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},mount(mount){assert(ENVIRONMENT_IS_NODE);return NODEFS.createNode(null,"/",NODEFS.getMode(mount.opts.root),0)},createNode(parent,name,mode,dev){if(!FS.isDir(mode)&&!FS.isFile(mode)&&!FS.isLink(mode)){throw new FS.ErrnoError(28)}var node=FS.createNode(parent,name,mode);node.node_ops=NODEFS.node_ops;node.stream_ops=NODEFS.stream_ops;return node},getMode(path){var stat;return NODEFS.tryFSOperation(()=>{stat=fs.lstatSync(path);if(NODEFS.isWindows){stat.mode|=(stat.mode&292)>>2}return stat.mode})},realPath(node){var parts=[];while(node.parent!==node){parts.push(node.name);node=node.parent}parts.push(node.mount.opts.root);parts.reverse();return PATH.join(...parts)},flagsForNode(flags){flags&=~2097152;flags&=~2048;flags&=~32768;flags&=~524288;flags&=~65536;var newFlags=0;for(var k in NODEFS.flagsForNodeMap){if(flags&k){newFlags|=NODEFS.flagsForNodeMap[k];flags^=k}}if(flags){throw new FS.ErrnoError(28)}return newFlags},node_ops:{getattr(node){var path=NODEFS.realPath(node);var stat;NODEFS.tryFSOperation(()=>stat=fs.lstatSync(path));if(NODEFS.isWindows){if(!stat.blksize){stat.blksize=4096}if(!stat.blocks){stat.blocks=(stat.size+stat.blksize-1)/stat.blksize|0}stat.mode|=(stat.mode&292)>>2}return{dev:stat.dev,ino:stat.ino,mode:stat.mode,nlink:stat.nlink,uid:stat.uid,gid:stat.gid,rdev:stat.rdev,size:stat.size,atime:stat.atime,mtime:stat.mtime,ctime:stat.ctime,blksize:stat.blksize,blocks:stat.blocks}},setattr(node,attr){var path=NODEFS.realPath(node);NODEFS.tryFSOperation(()=>{if(attr.mode!==undefined){fs.chmodSync(path,attr.mode);node.mode=attr.mode}if(attr.timestamp!==undefined){var date=new Date(attr.timestamp);fs.utimesSync(path,date,date)}if(attr.size!==undefined){fs.truncateSync(path,attr.size)}})},lookup(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);var mode=NODEFS.getMode(path);return NODEFS.createNode(parent,name,mode)},mknod(parent,name,mode,dev){var node=NODEFS.createNode(parent,name,mode,dev);var path=NODEFS.realPath(node);NODEFS.tryFSOperation(()=>{if(FS.isDir(node.mode)){fs.mkdirSync(path,node.mode)}else{fs.writeFileSync(path,"",{mode:node.mode})}});return node},rename(oldNode,newDir,newName){var oldPath=NODEFS.realPath(oldNode);var newPath=PATH.join2(NODEFS.realPath(newDir),newName);NODEFS.tryFSOperation(()=>fs.renameSync(oldPath,newPath));oldNode.name=newName},unlink(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);NODEFS.tryFSOperation(()=>fs.unlinkSync(path))},rmdir(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);NODEFS.tryFSOperation(()=>fs.rmdirSync(path))},readdir(node){var path=NODEFS.realPath(node);return NODEFS.tryFSOperation(()=>fs.readdirSync(path))},symlink(parent,newName,oldPath){var newPath=PATH.join2(NODEFS.realPath(parent),newName);NODEFS.tryFSOperation(()=>fs.symlinkSync(oldPath,newPath))},readlink(node){var path=NODEFS.realPath(node);return NODEFS.tryFSOperation(()=>fs.readlinkSync(path))}},stream_ops:{open(stream){var path=NODEFS.realPath(stream.node);NODEFS.tryFSOperation(()=>{if(FS.isFile(stream.node.mode)){stream.shared.refcount=1;stream.nfd=fs.openSync(path,NODEFS.flagsForNode(stream.flags))}})},close(stream){NODEFS.tryFSOperation(()=>{if(FS.isFile(stream.node.mode)&&stream.nfd&&--stream.shared.refcount===0){fs.closeSync(stream.nfd)}})},dup(stream){stream.shared.refcount++},read(stream,buffer,offset,length,position){if(length===0)return 0;return NODEFS.tryFSOperation(()=>fs.readSync(stream.nfd,new Int8Array(buffer.buffer,offset,length),0,length,position))},write(stream,buffer,offset,length,position){return NODEFS.tryFSOperation(()=>fs.writeSync(stream.nfd,new Int8Array(buffer.buffer,offset,length),0,length,position))},llseek(stream,offset,whence){var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){NODEFS.tryFSOperation(()=>{var stat=fs.fstatSync(stream.nfd);position+=stat.size})}}if(position<0){throw new FS.ErrnoError(28)}return position},mmap(stream,length,position,prot,flags){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}var ptr=mmapAlloc(length);NODEFS.stream_ops.read(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}},msync(stream,buffer,offset,length,mmapFlags){NODEFS.stream_ops.write(stream,buffer,0,length,offset,false);return 0}}};var ERRNO_MESSAGES={0:"Success",1:"Arg list too long",2:"Permission denied",3:"Address already in use",4:"Address not available",5:"Address family not supported by protocol family",6:"No more processes",7:"Socket already connected",8:"Bad file number",9:"Trying to read unreadable message",10:"Mount device busy",11:"Operation canceled",12:"No children",13:"Connection aborted",14:"Connection refused",15:"Connection reset by peer",16:"File locking deadlock error",17:"Destination address required",18:"Math arg out of domain of func",19:"Quota exceeded",20:"File exists",21:"Bad address",22:"File too large",23:"Host is unreachable",24:"Identifier removed",25:"Illegal byte sequence",26:"Connection already in progress",27:"Interrupted system call",28:"Invalid argument",29:"I/O error",30:"Socket is already connected",31:"Is a directory",32:"Too many symbolic links",33:"Too many open files",34:"Too many links",35:"Message too long",36:"Multihop attempted",37:"File or path name too long",38:"Network interface is not configured",39:"Connection reset by network",40:"Network is unreachable",41:"Too many open files in system",42:"No buffer space available",43:"No such device",44:"No such file or directory",45:"Exec format error",46:"No record locks available",47:"The link has been severed",48:"Not enough core",49:"No message of desired type",50:"Protocol not available",51:"No space left on device",52:"Function not implemented",53:"Socket is not connected",54:"Not a directory",55:"Directory not empty",56:"State not recoverable",57:"Socket operation on non-socket",59:"Not a typewriter",60:"No such device or address",61:"Value too large for defined data type",62:"Previous owner died",63:"Not super-user",64:"Broken pipe",65:"Protocol error",66:"Unknown protocol",67:"Protocol wrong type for socket",68:"Math result not representable",69:"Read only file system",70:"Illegal seek",71:"No such process",72:"Stale file handle",73:"Connection timed out",74:"Text file busy",75:"Cross-device link",100:"Device not a stream",101:"Bad font file fmt",102:"Invalid slot",103:"Invalid request code",104:"No anode",105:"Block device required",106:"Channel number out of range",107:"Level 3 halted",108:"Level 3 reset",109:"Link number out of range",110:"Protocol driver not attached",111:"No CSI structure available",112:"Level 2 halted",113:"Invalid exchange",114:"Invalid request descriptor",115:"Exchange full",116:"No data (for no delay io)",117:"Timer expired",118:"Out of streams resources",119:"Machine is not on the network",120:"Package not installed",121:"The object is remote",122:"Advertise error",123:"Srmount error",124:"Communication error on send",125:"Cross mount point (not really error)",126:"Given log. name not unique",127:"f.d. invalid for this operation",128:"Remote address changed",129:"Can access a needed shared lib",130:"Accessing a corrupted shared lib",131:".lib section in a.out corrupted",132:"Attempting to link in too many libs",133:"Attempting to exec a shared library",135:"Streams pipe error",136:"Too many users",137:"Socket type not supported",138:"Not supported",139:"Protocol family not supported",140:"Can't send after socket shutdown",141:"Too many references",142:"Host is down",148:"No medium (in tape drive)",156:"Level 2 not synchronized"};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:class extends Error{constructor(errno){super(ERRNO_MESSAGES[errno]);this.name="ErrnoError";this.errno=errno;for(var key in ERRNO_CODES){if(ERRNO_CODES[key]===errno){this.code=key;break}}}},genericErrors:{},filesystems:null,syncFSRequests:0,FSStream:class{constructor(){this.shared={}}get object(){return this.node}set object(val){this.node=val}get isRead(){return(this.flags&2097155)!==1}get isWrite(){return(this.flags&2097155)!==0}get isAppend(){return this.flags&1024}get flags(){return this.shared.flags}set flags(val){this.shared.flags=val}get position(){return this.shared.position}set position(val){this.shared.position=val}},FSNode:class{constructor(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev;this.readMode=292|73;this.writeMode=146}get read(){return(this.mode&this.readMode)===this.readMode}set read(val){val?this.mode|=this.readMode:this.mode&=~this.readMode}get write(){return(this.mode&this.writeMode)===this.writeMode}set write(val){val?this.mode|=this.writeMode:this.mode&=~this.writeMode}get isFolder(){return FS.isDir(this.mode)}get isDevice(){return FS.isChrdev(this.mode)}},lookupPath(path,opts={}){path=PATH_FS.resolve(path);if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};opts=Object.assign(defaults,opts);if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=path.split("/").filter(p=>!!p);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?`${mount}/${path}`:mount+path}path=path?`${node.name}/${path}`:node.name;node=node.parent}},hashName(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode(parent,name,mode,rdev){assert(typeof parent=="object");var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode(node){FS.hashRemoveNode(node)},isRoot(node){return node===node.parent},isMountpoint(node){return!!node.mounted},isFile(mode){return(mode&61440)===32768},isDir(mode){return(mode&61440)===16384},isLink(mode){return(mode&61440)===40960},isChrdev(mode){return(mode&61440)===8192},isBlkdev(mode){return(mode&61440)===24576},isFIFO(mode){return(mode&61440)===4096},isSocket(mode){return(mode&49152)===49152},flagsToPermissionString(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup(dir){if(!FS.isDir(dir.mode))return 54;var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd(){for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked(fd){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream(stream,fd=-1){stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream(fd){FS.streams[fd]=null},dupStream(origStream,fd=-1){var stream=FS.createStream(origStream,fd);stream.stream_ops?.dup?.(stream);return stream},chrdev_stream_ops:{open(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;stream.stream_ops.open?.(stream)},llseek(){throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push(...m.mounts)}return mounts},syncfs(populate,callback){if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){assert(FS.syncFSRequests>0);FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount(type,opts,mountpoint){if(typeof type=="string"){throw type}var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);assert(idx!==-1);node.mount.mounts.splice(idx,1)},lookup(parent,name){return parent.node_ops.lookup(parent,name)},mknod(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree(path,mode){var dirs=path.split("/");var d="";for(var i=0;i=0);if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write(stream,buffer,offset,length,position,canOwn){assert(offset>=0);if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},allocate(stream,offset,length){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(offset<0||length<=0){throw new FS.ErrnoError(28)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(!FS.isFile(stream.node.mode)&&!FS.isDir(stream.node.mode)){throw new FS.ErrnoError(43)}if(!stream.stream_ops.allocate){throw new FS.ErrnoError(138)}stream.stream_ops.allocate(stream,offset,length)},mmap(stream,length,position,prot,flags){if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync(stream,buffer,offset,length,mmapFlags){assert(offset>=0);if(!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},ioctl(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile(path,opts={}){opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error(`Invalid encoding type "${opts.encoding}"`)}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret=UTF8ArrayToString(buf,0)}else if(opts.encoding==="binary"){ret=buf}FS.close(stream);return ret},writeFile(path,data,opts={}){opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){var buf=new Uint8Array(lengthBytesUTF8(data)+1);var actualNumBytes=stringToUTF8Array(data,buf,0,buf.length);FS.write(stream,buf,0,actualNumBytes,undefined,opts.canOwn)}else if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomLeft=randomFill(randomBuffer).byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories(){FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount(){var node=FS.createNode(proc_self,"fd",16384|511,73);node.node_ops={lookup(parent,name){var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams(){if(Module["stdin"]){FS.createDevice("/dev","stdin",Module["stdin"])}else{FS.symlink("/dev/tty","/dev/stdin")}if(Module["stdout"]){FS.createDevice("/dev","stdout",null,Module["stdout"])}else{FS.symlink("/dev/tty","/dev/stdout")}if(Module["stderr"]){FS.createDevice("/dev","stderr",null,Module["stderr"])}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1);assert(stdin.fd===0,`invalid handle for stdin (${stdin.fd})`);assert(stdout.fd===1,`invalid handle for stdout (${stdout.fd})`);assert(stderr.fd===2,`invalid handle for stderr (${stderr.fd})`)},staticInit(){[44].forEach(code=>{FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack=""});FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={MEMFS:MEMFS,NODEFS:NODEFS}},init(input,output,error){assert(!FS.init.initialized,"FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)");FS.init.initialized=true;Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()},quit(){FS.init.initialized=false;_fflush(0);for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]}setDataGetter(getter){this.getter=getter}cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true}get length(){if(!this.lengthKnown){this.cacheLength()}return this._length}get chunkSize(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(key=>{var fn=node.stream_ops[key];stream_ops[key]=(...args)=>{FS.forceLoadFile(node);return fn(...args)}});function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);assert(size>=0);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}};node.stream_ops=stream_ops;return node},absolutePath(){abort("FS.absolutePath has been removed; use PATH_FS.resolve instead")},createFolder(){abort("FS.createFolder has been removed; use FS.mkdir instead")},createLink(){abort("FS.createLink has been removed; use FS.symlink instead")},joinPath(){abort("FS.joinPath has been removed; use PATH.join instead")},mmapAlloc(){abort("FS.mmapAlloc has been replaced by the top level function mmapAlloc")},standardizePath(){abort("FS.standardizePath has been removed; use PATH.normalize instead")}};var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return PATH.join2(dir,path)},doStat(func,path,buf){var stat=func(path);HEAP32[buf>>2]=stat.dev;checkInt32(stat.dev);HEAP32[buf+4>>2]=stat.mode;checkInt32(stat.mode);HEAPU32[buf+8>>2]=stat.nlink;checkInt32(stat.nlink);HEAP32[buf+12>>2]=stat.uid;checkInt32(stat.uid);HEAP32[buf+16>>2]=stat.gid;checkInt32(stat.gid);HEAP32[buf+20>>2]=stat.rdev;checkInt32(stat.rdev);tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+24>>2]=tempI64[0],HEAP32[buf+28>>2]=tempI64[1];checkInt64(stat.size);HEAP32[buf+32>>2]=4096;checkInt32(4096);HEAP32[buf+36>>2]=stat.blocks;checkInt32(stat.blocks);var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();tempI64=[Math.floor(atime/1e3)>>>0,(tempDouble=Math.floor(atime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];checkInt64(Math.floor(atime/1e3));HEAPU32[buf+48>>2]=atime%1e3*1e3;checkInt32(atime%1e3*1e3);tempI64=[Math.floor(mtime/1e3)>>>0,(tempDouble=Math.floor(mtime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+56>>2]=tempI64[0],HEAP32[buf+60>>2]=tempI64[1];checkInt64(Math.floor(mtime/1e3));HEAPU32[buf+64>>2]=mtime%1e3*1e3;checkInt32(mtime%1e3*1e3);tempI64=[Math.floor(ctime/1e3)>>>0,(tempDouble=Math.floor(ctime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+72>>2]=tempI64[0],HEAP32[buf+76>>2]=tempI64[1];checkInt64(Math.floor(ctime/1e3));HEAPU32[buf+80>>2]=ctime%1e3*1e3;checkInt32(ctime%1e3*1e3);tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+88>>2]=tempI64[0],HEAP32[buf+92>>2]=tempI64[1];checkInt64(stat.ino);return 0},doMsync(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},getStreamFromFD(fd){var stream=FS.getStreamChecked(fd);return stream},varargs:undefined,getStr(ptr){var ret=UTF8ToString(ptr);return ret}};function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=syscallGetVarargI();if(arg<0){return-28}while(FS.streams[arg]){arg++}var newStream;newStream=FS.dupStream(stream,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=syscallGetVarargI();stream.flags|=arg;return 0}case 12:{var arg=syscallGetVarargP();var offset=0;HEAP16[arg+offset>>1]=2;checkInt16(2);return 0}case 13:case 14:return 0}return-28}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_fstat64(fd,buf){try{var stream=SYSCALLS.getStreamFromFD(fd);return SYSCALLS.doStat(FS.stat,stream.path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:{if(!stream.tty)return-59;return 0}case 21505:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcgets){var termios=stream.tty.ops.ioctl_tcgets(stream);var argp=syscallGetVarargP();HEAP32[argp>>2]=termios.c_iflag||0;checkInt32(termios.c_iflag||0);HEAP32[argp+4>>2]=termios.c_oflag||0;checkInt32(termios.c_oflag||0);HEAP32[argp+8>>2]=termios.c_cflag||0;checkInt32(termios.c_cflag||0);HEAP32[argp+12>>2]=termios.c_lflag||0;checkInt32(termios.c_lflag||0);for(var i=0;i<32;i++){HEAP8[argp+i+17]=termios.c_cc[i]||0;checkInt8(termios.c_cc[i]||0)}return 0}return 0}case 21510:case 21511:case 21512:{if(!stream.tty)return-59;return 0}case 21506:case 21507:case 21508:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcsets){var argp=syscallGetVarargP();var c_iflag=HEAP32[argp>>2];var c_oflag=HEAP32[argp+4>>2];var c_cflag=HEAP32[argp+8>>2];var c_lflag=HEAP32[argp+12>>2];var c_cc=[];for(var i=0;i<32;i++){c_cc.push(HEAP8[argp+i+17])}return stream.tty.ops.ioctl_tcsets(stream.tty,op,{c_iflag:c_iflag,c_oflag:c_oflag,c_cflag:c_cflag,c_lflag:c_lflag,c_cc:c_cc})}return 0}case 21519:{if(!stream.tty)return-59;var argp=syscallGetVarargP();HEAP32[argp>>2]=0;checkInt32(0);return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=syscallGetVarargP();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tiocgwinsz){var winsize=stream.tty.ops.ioctl_tiocgwinsz(stream.tty);var argp=syscallGetVarargP();HEAP16[argp>>1]=winsize[0];checkInt16(winsize[0]);HEAP16[argp+2>>1]=winsize[1];checkInt16(winsize[1])}return 0}case 21524:{if(!stream.tty)return-59;return 0}case 21515:{if(!stream.tty)return-59;return 0}default:return-28}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_lstat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.lstat,path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_newfstatat(dirfd,path,buf,flags){try{path=SYSCALLS.getStr(path);var nofollow=flags&256;var allowEmpty=flags&4096;flags=flags&~6400;assert(!flags,`unknown flags in __syscall_newfstatat: ${flags}`);path=SYSCALLS.calculateAt(dirfd,path,allowEmpty);return SYSCALLS.doStat(nofollow?FS.lstat:FS.stat,path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?syscallGetVarargI():0;return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_stat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.stat,path,buf)}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var getCppExceptionTag=()=>wasmExports["__cpp_exception"];var getCppExceptionThrownObjectFromWebAssemblyException=ex=>{var unwind_header=ex.getArg(getCppExceptionTag(),0);return ___thrown_object_from_unwind_exception(unwind_header)};var stackSave=()=>_emscripten_stack_get_current();var stackRestore=val=>__emscripten_stack_restore(val);var stackAlloc=sz=>__emscripten_stack_alloc(sz);var getExceptionMessageCommon=ptr=>{var sp=stackSave();var type_addr_addr=stackAlloc(4);var message_addr_addr=stackAlloc(4);___get_exception_message(ptr,type_addr_addr,message_addr_addr);var type_addr=HEAPU32[type_addr_addr>>2];var message_addr=HEAPU32[message_addr_addr>>2];var type=UTF8ToString(type_addr);_free(type_addr);var message;if(message_addr){message=UTF8ToString(message_addr);_free(message_addr)}stackRestore(sp);return[type,message]};var getExceptionMessage=ex=>{var ptr=getCppExceptionThrownObjectFromWebAssemblyException(ex);return getExceptionMessageCommon(ptr)};Module["getExceptionMessage"]=getExceptionMessage;var ___throw_exception_with_stack_trace=ex=>{var e=new WebAssembly.Exception(getCppExceptionTag(),[ex],{traceStack:true});e.message=getExceptionMessage(e);throw e};var __abort_js=()=>{abort("native code called abort()")};var structRegistrations={};var runDestructors=destructors=>{while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}};function readPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var InternalError;var throwInternalError=message=>{throw new InternalError(message)};var whenDependentTypesAreResolved=(myTypes,dependentTypes,getTypeConverters)=>{myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}};var __embind_finalize_value_object=structType=>{var reg=structRegistrations[structType];delete structRegistrations[structType];var rawConstructor=reg.rawConstructor;var rawDestructor=reg.rawDestructor;var fieldRecords=reg.fields;var fieldTypes=fieldRecords.map(field=>field.getterReturnType).concat(fieldRecords.map(field=>field.setterArgumentType));whenDependentTypesAreResolved([structType],fieldTypes,fieldTypes=>{var fields={};fieldRecords.forEach((field,i)=>{var fieldName=field.fieldName;var getterReturnType=fieldTypes[i];var getter=field.getter;var getterContext=field.getterContext;var setterArgumentType=fieldTypes[i+fieldRecords.length];var setter=field.setter;var setterContext=field.setterContext;fields[fieldName]={read:ptr=>getterReturnType["fromWireType"](getter(getterContext,ptr)),write:(ptr,o)=>{var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,o));runDestructors(destructors)}}});return[{name:reg.name,fromWireType:ptr=>{var rv={};for(var i in fields){rv[i]=fields[i].read(ptr)}rawDestructor(ptr);return rv},toWireType:(destructors,o)=>{for(var fieldName in fields){if(!(fieldName in o)){throw new TypeError(`Missing field: "${fieldName}"`)}}var ptr=rawConstructor();for(fieldName in fields){fields[fieldName].write(ptr,o[fieldName])}if(destructors!==null){destructors.push(rawDestructor,ptr)}return ptr},argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,destructorFunction:rawDestructor}]})};var __embind_register_bigint=(primitiveType,name,size,minRange,maxRange)=>{};var embind_init_charCodes=()=>{var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes};var embind_charCodes;var readLatin1String=ptr=>{var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret};var BindingError;var throwBindingError=message=>{throw new BindingError(message)};function sharedRegisterType(rawType,registeredInstance,options={}){var name=registeredInstance.name;if(!rawType){throwBindingError(`type "${name}" must have a positive integer typeid pointer`)}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError(`Cannot register type '${name}' twice`)}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(cb=>cb())}}function registerType(rawType,registeredInstance,options={}){if(!("argPackAdvance"in registeredInstance)){throw new TypeError("registerType registeredInstance requires argPackAdvance")}return sharedRegisterType(rawType,registeredInstance,options)}var GenericWireTypeSize=8;var __embind_register_bool=(rawType,name,trueValue,falseValue)=>{name=readLatin1String(name);registerType(rawType,{name:name,fromWireType:function(wt){return!!wt},toWireType:function(destructors,o){return o?trueValue:falseValue},argPackAdvance:GenericWireTypeSize,readValueFromPointer:function(pointer){return this["fromWireType"](HEAPU8[pointer])},destructorFunction:null})};var shallowCopyInternalPointer=o=>({count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType});var throwInstanceAlreadyDeleted=obj=>{function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")};var finalizationRegistry=false;var detachFinalizer=handle=>{};var runDestructor=$$=>{if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}};var releaseClassHandle=$$=>{$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}};var downcastPointer=(ptr,ptrClass,desiredClass)=>{if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)};var registeredPointers={};var getInheritedInstanceCount=()=>Object.keys(registeredInstances).length;var getLiveInheritedInstances=()=>{var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv};var deletionQueue=[];var flushPendingDeletes=()=>{while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}};var delayFunction;var setDelayFunction=fn=>{delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}};var init_embind=()=>{Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction};var registeredInstances={};var getBasestPointer=(class_,ptr)=>{if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr};var getInheritedInstance=(class_,ptr)=>{ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]};var makeClassHandle=(prototype,record)=>{if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record,writable:true}}))};function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}var attachFinalizer=handle=>{if("undefined"===typeof FinalizationRegistry){attachFinalizer=handle=>handle;return handle}finalizationRegistry=new FinalizationRegistry(info=>{console.warn(info.leakWarning.stack.replace(/^Error: /,""));releaseClassHandle(info.$$)});attachFinalizer=handle=>{var $$=handle.$$;var hasSmartPtr=!!$$.smartPtr;if(hasSmartPtr){var info={$$:$$};var cls=$$.ptrType.registeredClass;info.leakWarning=new Error(`Embind found a leaked C++ instance ${cls.name} <${ptrToString($$.ptr)}>.\n`+"We'll free it automatically in this case, but this functionality is not reliable across various environments.\n"+"Make sure to invoke .delete() manually once you're done with the instance instead.\n"+"Originally allocated");if("captureStackTrace"in Error){Error.captureStackTrace(info.leakWarning,RegisteredPointer_fromWireType)}finalizationRegistry.register(handle,info,handle)}return handle};detachFinalizer=handle=>finalizationRegistry.unregister(handle);return attachFinalizer(handle)};var init_ClassHandle=()=>{Object.assign(ClassHandle.prototype,{isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;other.$$=other.$$;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right},clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}},delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}},isDeleted(){return!this.$$.ptr},deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}})};function ClassHandle(){}var createNamedFunction=(name,body)=>Object.defineProperty(body,"name",{value:name});var ensureOverloadTable=(proto,methodName,humanName)=>{if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(...args){if(!proto[methodName].overloadTable.hasOwnProperty(args.length)){throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${args.length}) - expects one of (${proto[methodName].overloadTable})!`)}return proto[methodName].overloadTable[args.length].apply(this,args)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}};var exposePublicSymbol=(name,value,numArguments)=>{if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError(`Cannot register public name '${name}' twice`)}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`)}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}};var char_0=48;var char_9=57;var makeLegalFunctionName=name=>{if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return`_${name}`}return name};function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}var upcastPointer=(ptr,ptrClass,desiredClass)=>{while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError(`Expected null or instance of ${desiredClass.name}, got an instance of ${ptrClass.name}`)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr};function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle||!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,Emval.toHandle(()=>clonedHandle["delete"]()));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass "${embindRepr(handle)}" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}var init_RegisteredPointer=()=>{Object.assign(RegisteredPointer.prototype,{getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr},destructor(ptr){this.rawDestructor?.(ptr)},argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,fromWireType:RegisteredPointer_fromWireType})};function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}var replacePublicSymbol=(name,value,numArguments)=>{if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistent public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}};var dynCallLegacy=(sig,ptr,args)=>{sig=sig.replace(/p/g,"i");assert("dynCall_"+sig in Module,`bad function pointer type - dynCall function not found for sig '${sig}'`);if(args?.length){assert(args.length===sig.substring(1).replace(/j/g,"--").length)}else{assert(sig.length==1)}var f=Module["dynCall_"+sig];return f(ptr,...args)};var wasmTableMirror=[];var wasmTable;var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}assert(wasmTable.get(funcPtr)==func,"JavaScript-side Wasm function table mirror is out of date!");return func};var dynCall=(sig,ptr,args=[])=>{if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}assert(getWasmTableEntry(ptr),`missing table entry in dynCall: ${ptr}`);var rtn=getWasmTableEntry(ptr)(...args);return rtn};var getDynCaller=(sig,ptr)=>{assert(sig.includes("j")||sig.includes("p"),"getDynCaller should only be called with i64 sigs");return(...args)=>dynCall(sig,ptr,args)};var embind__requireFunction=(signature,rawFunction)=>{signature=readLatin1String(signature);function makeDynCaller(){if(signature.includes("j")){return getDynCaller(signature,rawFunction)}return getWasmTableEntry(rawFunction)}var fp=makeDynCaller();if(typeof fp!="function"){throwBindingError(`unknown function pointer with signature ${signature}: ${rawFunction}`)}return fp};var extendError=(baseErrorType,errorName)=>{var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return`${this.name}: ${this.message}`}};return errorClass};var UnboundTypeError;var getTypeName=type=>{var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv};var throwUnboundTypeError=(message,types)=>{var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(`${message}: `+unboundTypes.map(getTypeName).join([", "]))};var __embind_register_class=(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor)=>{name=readLatin1String(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);upcast&&=embind__requireFunction(upcastSignature,upcast);downcast&&=embind__requireFunction(downcastSignature,downcast);rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,function(){throwUnboundTypeError(`Cannot construct ${name} due to unbound types`,[baseClassRawType])});whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],base=>{base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(name,function(...args){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError("Use 'new' to construct "+name)}if(undefined===registeredClass.constructor_body){throw new BindingError(name+" has no accessible constructor")}var body=registeredClass.constructor_body[args.length];if(undefined===body){throw new BindingError(`Tried to invoke ctor of ${name} with invalid number of parameters (${args.length}) - expected (${Object.keys(registeredClass.constructor_body).toString()}) parameters instead!`)}return body.apply(this,args)});var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);if(registeredClass.baseClass){registeredClass.baseClass.__derivedClasses??=[];registeredClass.baseClass.__derivedClasses.push(registeredClass)}var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+"*",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+" const*",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]})};var heap32VectorToArray=(count,firstElement)=>{var array=[];for(var i=0;i>2])}return array};function usesDestructorStack(argTypes){for(var i=1;i0?", ":"")+argsListWired}invokerFnBody+=(returns||isAsync?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i{assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],classType=>{classType=classType[0];var humanName=`constructor ${classType.name}`;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError(`Cannot register multiple constructors with identical number of parameters (${argCount-1}) for class '${classType.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!`)}classType.registeredClass.constructor_body[argCount-1]=()=>{throwUnboundTypeError(`Cannot construct ${classType.name} due to unbound types`,rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,argTypes=>{argTypes.splice(1,0,null);classType.registeredClass.constructor_body[argCount-1]=craftInvokerFunction(humanName,argTypes,null,invoker,rawConstructor);return[]});return[]})};var getFunctionName=signature=>{signature=signature.trim();const argsIndex=signature.indexOf("(");if(argsIndex!==-1){assert(signature[signature.length-1]==")","Parentheses for argument names should match.");return signature.substr(0,argsIndex)}else{return signature}};var __embind_register_class_function=(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual,isAsync)=>{var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);methodName=getFunctionName(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],classType=>{classType=classType[0];var humanName=`${classType.name}.${methodName}`;if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError(`Cannot call ${humanName} due to unbound types`,rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,argTypes=>{var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context,isAsync);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]});return[]})};var emval_freelist=[];var emval_handles=[];var __emval_decref=handle=>{if(handle>9&&0===--emval_handles[handle+1]){assert(emval_handles[handle]!==undefined,`Decref for unallocated handle.`);emval_handles[handle]=undefined;emval_freelist.push(handle)}};var count_emval_handles=()=>emval_handles.length/2-5-emval_freelist.length;var init_emval=()=>{emval_handles.push(0,1,undefined,1,null,1,true,1,false,1);assert(emval_handles.length===5*2);Module["count_emval_handles"]=count_emval_handles};var Emval={toValue:handle=>{if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}assert(handle===2||emval_handles[handle]!==undefined&&handle%2===0,`invalid handle: ${handle}`);return emval_handles[handle]},toHandle:value=>{switch(value){case undefined:return 2;case null:return 4;case true:return 6;case false:return 8;default:{const handle=emval_freelist.pop()||emval_handles.length;emval_handles[handle]=value;emval_handles[handle+1]=1;return handle}}}};var EmValType={name:"emscripten::val",fromWireType:handle=>{var rv=Emval.toValue(handle);__emval_decref(handle);return rv},toWireType:(destructors,value)=>Emval.toHandle(value),argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,destructorFunction:null};var __embind_register_emval=rawType=>registerType(rawType,EmValType);var embindRepr=v=>{if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}};var floatReadValueFromPointer=(name,width)=>{switch(width){case 4:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 8:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError(`invalid float width (${width}): ${name}`)}};var __embind_register_float=(rawType,name,size)=>{name=readLatin1String(name);registerType(rawType,{name:name,fromWireType:value=>value,toWireType:(destructors,value)=>{if(typeof value!="number"&&typeof value!="boolean"){throw new TypeError(`Cannot convert ${embindRepr(value)} to ${this.name}`)}return value},argPackAdvance:GenericWireTypeSize,readValueFromPointer:floatReadValueFromPointer(name,size),destructorFunction:null})};var __embind_register_function=(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn,isAsync)=>{var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);name=getFunctionName(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError(`Cannot call ${name} due to unbound types`,argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,argTypes=>{var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn,isAsync),argCount-1);return[]})};var integerReadValueFromPointer=(name,width,signed)=>{switch(width){case 1:return signed?pointer=>HEAP8[pointer]:pointer=>HEAPU8[pointer];case 2:return signed?pointer=>HEAP16[pointer>>1]:pointer=>HEAPU16[pointer>>1];case 4:return signed?pointer=>HEAP32[pointer>>2]:pointer=>HEAPU32[pointer>>2];default:throw new TypeError(`invalid integer width (${width}): ${name}`)}};var __embind_register_integer=(primitiveType,name,size,minRange,maxRange)=>{name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var fromWireType=value=>value;if(minRange===0){var bitshift=32-8*size;fromWireType=value=>value<>>bitshift}var isUnsignedType=name.includes("unsigned");var checkAssertions=(value,toTypeName)=>{if(typeof value!="number"&&typeof value!="boolean"){throw new TypeError(`Cannot convert "${embindRepr(value)}" to ${toTypeName}`)}if(valuemaxRange){throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!`)}};var toWireType;if(isUnsignedType){toWireType=function(destructors,value){checkAssertions(value,this.name);return value>>>0}}else{toWireType=function(destructors,value){checkAssertions(value,this.name);return value}}registerType(primitiveType,{name:name,fromWireType:fromWireType,toWireType:toWireType,argPackAdvance:GenericWireTypeSize,readValueFromPointer:integerReadValueFromPointer(name,size,minRange!==0),destructorFunction:null})};var __embind_register_memory_view=(rawType,dataTypeIndex,name)=>{var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){var size=HEAPU32[handle>>2];var data=HEAPU32[handle+4>>2];return new TA(HEAP8.buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,fromWireType:decodeMemoryView,argPackAdvance:GenericWireTypeSize,readValueFromPointer:decodeMemoryView},{ignoreDuplicateRegistrations:true})};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>{assert(typeof maxBytesToWrite=="number","stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)};var __embind_register_std_string=(rawType,name)=>{name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,fromWireType(value){var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;checkInt32(length);if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+i]=charCode}}else{for(var i=0;i{assert(ptr%2==0,"Pointer passed to UTF16ToString must be aligned to two bytes!");var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder)return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr));var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str};var stringToUTF16=(str,outPtr,maxBytesToWrite)=>{assert(outPtr%2==0,"Pointer passed to stringToUTF16 must be aligned to two bytes!");assert(typeof maxBytesToWrite=="number","stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");maxBytesToWrite??=2147483647;if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;checkInt16(codeUnit);outPtr+=2}HEAP16[outPtr>>1]=0;checkInt16(0);return outPtr-startPtr};var lengthBytesUTF16=str=>str.length*2;var UTF32ToString=(ptr,maxBytesToRead)=>{assert(ptr%4==0,"Pointer passed to UTF32ToString must be aligned to four bytes!");var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str};var stringToUTF32=(str,outPtr,maxBytesToWrite)=>{assert(outPtr%4==0,"Pointer passed to stringToUTF32 must be aligned to four bytes!");assert(typeof maxBytesToWrite=="number","stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");maxBytesToWrite??=2147483647;if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;checkInt32(codeUnit);outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;checkInt32(0);return outPtr-startPtr};var lengthBytesUTF32=str=>{var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len};var __embind_register_std_wstring=(rawType,charSize,name)=>{name=readLatin1String(name);var decodeString,encodeString,readCharAt,lengthBytesUTF;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;readCharAt=pointer=>HEAPU16[pointer>>1]}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;readCharAt=pointer=>HEAPU32[pointer>>2]}registerType(rawType,{name:name,fromWireType:value=>{var length=HEAPU32[value>>2];var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||readCharAt(currentBytePtr)==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},toWireType:(destructors,value)=>{if(!(typeof value=="string")){throwBindingError(`Cannot pass non-string to C++ string type ${name}`)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length/charSize;checkInt32(length/charSize);encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,destructorFunction(ptr){_free(ptr)}})};var __embind_register_value_object=(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor)=>{structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}};var __embind_register_value_object_field=(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext)=>{structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})};var __embind_register_void=(rawType,name)=>{name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,argPackAdvance:0,fromWireType:()=>undefined,toWireType:(destructors,o)=>undefined})};var __emscripten_memcpy_js=(dest,src,num)=>HEAPU8.copyWithin(dest,src,src+num);var requireRegisteredType=(rawType,humanName)=>{var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(`${humanName} has unknown type ${getTypeName(rawType)}`)}return impl};var __emval_take_value=(type,arg)=>{type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](arg);return Emval.toHandle(v)};var convertI32PairToI53Checked=(lo,hi)=>{assert(lo==lo>>>0||lo==(lo|0));assert(hi===(hi|0));return hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN};function __mmap_js(len,prot,flags,fd,offset_low,offset_high,allocated,addr){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);var res=FS.mmap(stream,len,offset,prot,flags);var ptr=res.ptr;HEAP32[allocated>>2]=res.allocated;checkInt32(res.allocated);HEAPU32[addr>>2]=ptr;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function __munmap_js(addr,len,prot,flags,fd,offset_low,offset_high){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{var stream=SYSCALLS.getStreamFromFD(fd);if(prot&2){SYSCALLS.doMsync(addr,stream,len,flags,offset)}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var getHeapMax=()=>2147483648;var _emscripten_get_now;_emscripten_get_now=()=>performance.now();var growMemory=size=>{var b=wasmMemory.buffer;var pages=(size-b.byteLength+65535)/65536;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){err(`growMemory: Attempted to grow heap from ${b.byteLength} bytes to ${size} bytes, but got error: ${e}`)}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;assert(requestedSize>oldSize);var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){err(`Cannot enlarge memory, requested ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!`);return false}var alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var t0=_emscripten_get_now();var replacement=growMemory(newSize);var t1=_emscripten_get_now();dbg(`Heap resize call from ${oldSize} to ${newSize} took ${t1-t0} msecs. Success: ${!!replacement}`);if(replacement){return true}}err(`Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!`);return false};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:lang,_:getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var stringToAscii=(str,buffer)=>{for(var i=0;i{var bufSize=0;getEnvStrings().forEach((string,i)=>{var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>2]=ptr;checkInt32(ptr);stringToAscii(string,ptr);bufSize+=string.length+1});return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;checkInt32(strings.length);var bufSize=0;strings.forEach(string=>bufSize+=string.length+1);HEAPU32[penviron_buf_size>>2]=bufSize;checkInt32(bufSize);return 0};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;checkInt32(num);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];checkInt64(stream.position);if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(typeof offset!="undefined"){offset+=curr}}return ret};function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=doWritev(stream,iov,iovcnt);HEAPU32[pnum>>2]=num;checkInt32(num);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var arraySum=(array,index)=>{var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum};var MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];var addDays=(date,days)=>{var newDate=new Date(date.getTime());while(days>0){var leap=isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate};var writeArrayToMemory=(array,buffer)=>{assert(array.length>=0,"writeArrayToMemory array must have a length (should be an array or typed array)");HEAP8.set(array,buffer)};var _strftime=(s,maxsize,format,tm)=>{var tm_zone=HEAPU32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value=="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}return thisDate.getFullYear()}return thisDate.getFullYear()-1}var EXPANSION_RULES_2={"%a":date=>WEEKDAYS[date.tm_wday].substring(0,3),"%A":date=>WEEKDAYS[date.tm_wday],"%b":date=>MONTHS[date.tm_mon].substring(0,3),"%B":date=>MONTHS[date.tm_mon],"%C":date=>{var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":date=>leadingNulls(date.tm_mday,2),"%e":date=>leadingSomething(date.tm_mday,2," "),"%g":date=>getWeekBasedYear(date).toString().substring(2),"%G":getWeekBasedYear,"%H":date=>leadingNulls(date.tm_hour,2),"%I":date=>{var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":date=>leadingNulls(date.tm_mday+arraySum(isLeapYear(date.tm_year+1900)?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR,date.tm_mon-1),3),"%m":date=>leadingNulls(date.tm_mon+1,2),"%M":date=>leadingNulls(date.tm_min,2),"%n":()=>"\n","%p":date=>{if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}return"PM"},"%S":date=>leadingNulls(date.tm_sec,2),"%t":()=>"\t","%u":date=>date.tm_wday||7,"%U":date=>{var days=date.tm_yday+7-date.tm_wday;return leadingNulls(Math.floor(days/7),2)},"%V":date=>{var val=Math.floor((date.tm_yday+7-(date.tm_wday+6)%7)/7);if((date.tm_wday+371-date.tm_yday-2)%7<=2){val++}if(!val){val=52;var dec31=(date.tm_wday+7-date.tm_yday-1)%7;if(dec31==4||dec31==5&&isLeapYear(date.tm_year%400-1)){val++}}else if(val==53){var jan1=(date.tm_wday+371-date.tm_yday)%7;if(jan1!=4&&(jan1!=3||!isLeapYear(date.tm_year)))val=1}return leadingNulls(val,2)},"%w":date=>date.tm_wday,"%W":date=>{var days=date.tm_yday+7-(date.tm_wday+6)%7;return leadingNulls(Math.floor(days/7),2)},"%y":date=>(date.tm_year+1900).toString().substring(2),"%Y":date=>date.tm_year+1900,"%z":date=>{var off=date.tm_gmtoff;var ahead=off>=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":date=>date.tm_zone,"%%":()=>"%"};pattern=pattern.replace(/%%/g,"\0\0");for(var rule in EXPANSION_RULES_2){if(pattern.includes(rule)){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}pattern=pattern.replace(/\0\0/g,"%");var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1};var _strftime_l=(s,maxsize,format,tm,loc)=>_strftime(s,maxsize,format,tm);var FS_createPath=FS.createPath;var FS_unlink=path=>FS.unlink(path);var FS_createLazyFile=FS.createLazyFile;var FS_createDevice=FS.createDevice;var incrementExceptionRefcount=ex=>{var ptr=getCppExceptionThrownObjectFromWebAssemblyException(ex);___cxa_increment_exception_refcount(ptr)};Module["incrementExceptionRefcount"]=incrementExceptionRefcount;var decrementExceptionRefcount=ex=>{var ptr=getCppExceptionThrownObjectFromWebAssemblyException(ex);___cxa_decrement_exception_refcount(ptr)};Module["decrementExceptionRefcount"]=decrementExceptionRefcount;FS.createPreloadedFile=FS_createPreloadedFile;FS.staticInit();Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_unlink"]=FS.unlink;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createDevice"]=FS.createDevice;if(ENVIRONMENT_IS_NODE){NODEFS.staticInit()}InternalError=Module["InternalError"]=class InternalError extends Error{constructor(message){super(message);this.name="InternalError"}};embind_init_charCodes();BindingError=Module["BindingError"]=class BindingError extends Error{constructor(message){super(message);this.name="BindingError"}};init_ClassHandle();init_embind();init_RegisteredPointer();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();function checkIncomingModuleAPI(){ignoredModuleProp("fetchSettings")}var wasmImports={__assert_fail:___assert_fail,__handle_stack_overflow:___handle_stack_overflow,__syscall_fcntl64:___syscall_fcntl64,__syscall_fstat64:___syscall_fstat64,__syscall_ioctl:___syscall_ioctl,__syscall_lstat64:___syscall_lstat64,__syscall_newfstatat:___syscall_newfstatat,__syscall_openat:___syscall_openat,__syscall_stat64:___syscall_stat64,__throw_exception_with_stack_trace:___throw_exception_with_stack_trace,_abort_js:__abort_js,_embind_finalize_value_object:__embind_finalize_value_object,_embind_register_bigint:__embind_register_bigint,_embind_register_bool:__embind_register_bool,_embind_register_class:__embind_register_class,_embind_register_class_constructor:__embind_register_class_constructor,_embind_register_class_function:__embind_register_class_function,_embind_register_emval:__embind_register_emval,_embind_register_float:__embind_register_float,_embind_register_function:__embind_register_function,_embind_register_integer:__embind_register_integer,_embind_register_memory_view:__embind_register_memory_view,_embind_register_std_string:__embind_register_std_string,_embind_register_std_wstring:__embind_register_std_wstring,_embind_register_value_object:__embind_register_value_object,_embind_register_value_object_field:__embind_register_value_object_field,_embind_register_void:__embind_register_void,_emscripten_memcpy_js:__emscripten_memcpy_js,_emval_take_value:__emval_take_value,_mmap_js:__mmap_js,_munmap_js:__munmap_js,emscripten_resize_heap:_emscripten_resize_heap,environ_get:_environ_get,environ_sizes_get:_environ_sizes_get,fd_close:_fd_close,fd_read:_fd_read,fd_seek:_fd_seek,fd_write:_fd_write,strftime_l:_strftime_l};var wasmExports=createWasm();var ___wasm_call_ctors=createExportWrapper("__wasm_call_ctors",0);var ___getTypeName=createExportWrapper("__getTypeName",1);var _malloc=createExportWrapper("malloc",1);var _fflush=createExportWrapper("fflush",1);var _free=createExportWrapper("free",1);var ___funcs_on_exit=createExportWrapper("__funcs_on_exit",0);var _emscripten_builtin_memalign=createExportWrapper("emscripten_builtin_memalign",2);var ___trap=()=>(___trap=wasmExports["__trap"])();var __emscripten_tempret_set=createExportWrapper("_emscripten_tempret_set",1);var _emscripten_stack_init=()=>(_emscripten_stack_init=wasmExports["emscripten_stack_init"])();var _emscripten_stack_get_free=()=>(_emscripten_stack_get_free=wasmExports["emscripten_stack_get_free"])();var _emscripten_stack_get_base=()=>(_emscripten_stack_get_base=wasmExports["emscripten_stack_get_base"])();var _emscripten_stack_get_end=()=>(_emscripten_stack_get_end=wasmExports["emscripten_stack_get_end"])();var __emscripten_stack_restore=a0=>(__emscripten_stack_restore=wasmExports["_emscripten_stack_restore"])(a0);var __emscripten_stack_alloc=a0=>(__emscripten_stack_alloc=wasmExports["_emscripten_stack_alloc"])(a0);var _emscripten_stack_get_current=()=>(_emscripten_stack_get_current=wasmExports["emscripten_stack_get_current"])();var ___cxa_decrement_exception_refcount=createExportWrapper("__cxa_decrement_exception_refcount",1);var ___cxa_increment_exception_refcount=createExportWrapper("__cxa_increment_exception_refcount",1);var ___thrown_object_from_unwind_exception=createExportWrapper("__thrown_object_from_unwind_exception",1);var ___get_exception_message=createExportWrapper("__get_exception_message",3);var ___set_stack_limits=Module["___set_stack_limits"]=createExportWrapper("__set_stack_limits",2);var dynCall_jiji=Module["dynCall_jiji"]=createExportWrapper("dynCall_jiji",5);var dynCall_viijii=Module["dynCall_viijii"]=createExportWrapper("dynCall_viijii",7);var dynCall_iiiiij=Module["dynCall_iiiiij"]=createExportWrapper("dynCall_iiiiij",7);var dynCall_iiiiijj=Module["dynCall_iiiiijj"]=createExportWrapper("dynCall_iiiiijj",9);var dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=createExportWrapper("dynCall_iiiiiijj",10);Module["addRunDependency"]=addRunDependency;Module["removeRunDependency"]=removeRunDependency;Module["FS_createPreloadedFile"]=FS_createPreloadedFile;Module["FS_unlink"]=FS_unlink;Module["FS_createPath"]=FS_createPath;Module["FS_createDevice"]=FS_createDevice;Module["FS"]=FS;Module["FS_createDataFile"]=FS_createDataFile;Module["FS_createLazyFile"]=FS_createLazyFile;var missingLibrarySymbols=["writeI53ToI64","writeI53ToI64Clamped","writeI53ToI64Signaling","writeI53ToU64Clamped","writeI53ToU64Signaling","readI53FromI64","readI53FromU64","convertI32PairToI53","convertU32PairToI53","getTempRet0","setTempRet0","exitJS","ydayFromDate","inetPton4","inetNtop4","inetPton6","inetNtop6","readSockaddr","writeSockaddr","emscriptenLog","readEmAsmArgs","jstoi_q","listenOnce","autoResumeAudioContext","handleException","keepRuntimeAlive","runtimeKeepalivePush","runtimeKeepalivePop","callUserCallback","maybeExit","asmjsMangle","HandleAllocator","getNativeTypeSize","STACK_SIZE","STACK_ALIGN","POINTER_SIZE","ASSERTIONS","getCFunc","ccall","cwrap","uleb128Encode","sigToWasmTypes","generateFuncType","convertJsFunctionToWasm","getEmptyTableSlot","updateTableMap","getFunctionAddress","addFunction","removeFunction","reallyNegative","unSign","strLen","reSign","formatString","intArrayToString","AsciiToString","stringToNewUTF8","stringToUTF8OnStack","registerKeyEventCallback","maybeCStringToJsString","findEventTarget","getBoundingClientRect","fillMouseEventData","registerMouseEventCallback","registerWheelEventCallback","registerUiEventCallback","registerFocusEventCallback","fillDeviceOrientationEventData","registerDeviceOrientationEventCallback","fillDeviceMotionEventData","registerDeviceMotionEventCallback","screenOrientation","fillOrientationChangeEventData","registerOrientationChangeEventCallback","fillFullscreenChangeEventData","registerFullscreenChangeEventCallback","JSEvents_requestFullscreen","JSEvents_resizeCanvasForFullscreen","registerRestoreOldStyle","hideEverythingExceptGivenElement","restoreHiddenElements","setLetterbox","softFullscreenResizeWebGLRenderTarget","doRequestFullscreen","fillPointerlockChangeEventData","registerPointerlockChangeEventCallback","registerPointerlockErrorEventCallback","requestPointerLock","fillVisibilityChangeEventData","registerVisibilityChangeEventCallback","registerTouchEventCallback","fillGamepadEventData","registerGamepadEventCallback","registerBeforeUnloadEventCallback","fillBatteryEventData","battery","registerBatteryEventCallback","setCanvasElementSize","getCanvasElementSize","jsStackTrace","getCallstack","convertPCtoSourceLocation","checkWasiClock","wasiRightsToMuslOFlags","wasiOFlagsToMuslOFlags","createDyncallWrapper","safeSetTimeout","setImmediateWrapped","clearImmediateWrapped","polyfillSetImmediate","getPromise","makePromise","idsToPromises","makePromiseCallback","Browser_asyncPrepareDataCounter","setMainLoop","getSocketFromFD","getSocketAddress","FS_mkdirTree","_setNetworkCallback","heapObjectForWebGLType","toTypedArrayIndex","webgl_enable_ANGLE_instanced_arrays","webgl_enable_OES_vertex_array_object","webgl_enable_WEBGL_draw_buffers","webgl_enable_WEBGL_multi_draw","emscriptenWebGLGet","computeUnpackAlignedImageSize","colorChannelsInGlTextureFormat","emscriptenWebGLGetTexPixelData","emscriptenWebGLGetUniform","webglGetUniformLocation","webglPrepareUniformLocationsBeforeFirstUse","webglGetLeftBracePos","emscriptenWebGLGetVertexAttrib","__glGetActiveAttribOrUniform","writeGLArray","registerWebGlEventCallback","runAndAbortIfError","ALLOC_NORMAL","ALLOC_STACK","allocate","writeStringToMemory","writeAsciiToMemory","setErrNo","demangle","stackTrace","getFunctionArgsName","createJsInvokerSignature","registerInheritedInstance","unregisterInheritedInstance","enumReadValueFromPointer","validateThis","getStringOrSymbol","emval_get_global","emval_returnValue","emval_lookupTypes","emval_addMethodCaller"];missingLibrarySymbols.forEach(missingLibrarySymbol);var unexportedSymbols=["run","addOnPreRun","addOnInit","addOnPreMain","addOnExit","addOnPostRun","out","err","callMain","abort","wasmMemory","wasmExports","writeStackCookie","checkStackCookie","convertI32PairToI53Checked","stackSave","stackRestore","stackAlloc","ptrToString","zeroMemory","getHeapMax","growMemory","ENV","setStackLimits","MONTH_DAYS_REGULAR","MONTH_DAYS_LEAP","MONTH_DAYS_REGULAR_CUMULATIVE","MONTH_DAYS_LEAP_CUMULATIVE","isLeapYear","arraySum","addDays","ERRNO_CODES","ERRNO_MESSAGES","DNS","Protocols","Sockets","initRandomFill","randomFill","timers","warnOnce","readEmAsmArgsArray","jstoi_s","getExecutableName","dynCallLegacy","getDynCaller","dynCall","asyncLoad","alignMemory","mmapAlloc","wasmTable","noExitRuntime","freeTableIndexes","functionsInTableMap","setValue","getValue","PATH","PATH_FS","UTF8Decoder","UTF8ArrayToString","UTF8ToString","stringToUTF8Array","stringToUTF8","lengthBytesUTF8","intArrayFromString","stringToAscii","UTF16Decoder","UTF16ToString","stringToUTF16","lengthBytesUTF16","UTF32ToString","stringToUTF32","lengthBytesUTF32","writeArrayToMemory","JSEvents","specialHTMLTargets","findCanvasEventTarget","currentFullscreenStrategy","restoreOldWindowedStyle","UNWIND_CACHE","ExitStatus","getEnvStrings","doReadv","doWritev","promiseMap","getExceptionMessageCommon","getCppExceptionTag","getCppExceptionThrownObjectFromWebAssemblyException","incrementExceptionRefcount","decrementExceptionRefcount","getExceptionMessage","Browser","getPreloadedImageData__data","wget","SYSCALLS","preloadPlugins","FS_modeStringToFlags","FS_getMode","FS_stdin_getChar_buffer","FS_stdin_getChar","FS_readFile","MEMFS","TTY","PIPEFS","SOCKFS","tempFixedLengthArray","miniTempWebGLFloatBuffers","miniTempWebGLIntBuffers","GL","AL","GLUT","EGL","GLEW","IDBStore","SDL","SDL_gfx","allocateUTF8","allocateUTF8OnStack","print","printErr","InternalError","BindingError","throwInternalError","throwBindingError","registeredTypes","awaitingDependencies","typeDependencies","tupleRegistrations","structRegistrations","sharedRegisterType","whenDependentTypesAreResolved","embind_charCodes","embind_init_charCodes","readLatin1String","getTypeName","getFunctionName","heap32VectorToArray","requireRegisteredType","usesDestructorStack","createJsInvoker","UnboundTypeError","PureVirtualError","GenericWireTypeSize","EmValType","init_embind","throwUnboundTypeError","ensureOverloadTable","exposePublicSymbol","replacePublicSymbol","extendError","createNamedFunction","embindRepr","registeredInstances","getBasestPointer","getInheritedInstance","getInheritedInstanceCount","getLiveInheritedInstances","registeredPointers","registerType","integerReadValueFromPointer","floatReadValueFromPointer","readPointer","runDestructors","newFunc","craftInvokerFunction","embind__requireFunction","genericPointerToWireType","constNoSmartPtrRawPointerToWireType","nonConstNoSmartPtrRawPointerToWireType","init_RegisteredPointer","RegisteredPointer","RegisteredPointer_fromWireType","runDestructor","releaseClassHandle","finalizationRegistry","detachFinalizer_deps","detachFinalizer","attachFinalizer","makeClassHandle","init_ClassHandle","ClassHandle","throwInstanceAlreadyDeleted","deletionQueue","flushPendingDeletes","delayFunction","setDelayFunction","RegisteredClass","shallowCopyInternalPointer","downcastPointer","upcastPointer","char_0","char_9","makeLegalFunctionName","emval_freelist","emval_handles","emval_symbols","init_emval","count_emval_handles","Emval","emval_methodCallers","reflectConstruct","NODEFS"];unexportedSymbols.forEach(unexportedRuntimeSymbol);var calledRun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function stackCheckInit(){_emscripten_stack_init();writeStackCookie()}function run(){if(runDependencies>0){return}stackCheckInit();preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();assert(!Module["_main"],'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]');postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}checkStackCookie()}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run();moduleRtn=readyPromise;for(const prop of Object.keys(Module)){if(!(prop in moduleArg)){Object.defineProperty(moduleArg,prop,{configurable:true,get(){abort(`Access to module property ('${prop}') is no longer possible via the module constructor argument; Instead, use the result of the module constructor.`)}})}} - return async function (moduleArg = {}) { - var Module = moduleArg; - var readyPromiseResolve, readyPromiseReject; - Module['ready'] = new Promise((resolve, reject) => { - readyPromiseResolve = resolve; - readyPromiseReject = reject; - }); - [ - '_main', - 'getExceptionMessage', - '___get_exception_message', - '_free', - '___cpp_exception', - '___cxa_increment_exception_refcount', - '___cxa_decrement_exception_refcount', - '___thrown_object_from_unwind_exception', - '_fflush', - '__embind_initialize_bindings', - '___set_stack_limits', - 'onRuntimeInitialized', - ].forEach((prop) => { - if (!Object.getOwnPropertyDescriptor(Module['ready'], prop)) { - Object.defineProperty(Module['ready'], prop, { - get: () => - abort( - 'You are getting ' + - prop + - ' on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js' - ), - set: () => - abort( - 'You are setting ' + - prop + - ' on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js' - ), - }); - } - }); - if (!Module.expectedDataFileDownloads) { - Module.expectedDataFileDownloads = 0; - } - Module.expectedDataFileDownloads++; - (function () { - if (Module['ENVIRONMENT_IS_PTHREAD'] || Module['$ww']) return; - var loadPackage = function (metadata) { - var PACKAGE_PATH = ''; - if (typeof window === 'object') { - PACKAGE_PATH = window['encodeURIComponent']( - window.location.pathname - .toString() - .substring( - 0, - window.location.pathname - .toString() - .lastIndexOf('/') - ) + '/' - ); - } else if ( - typeof process === 'undefined' && - typeof location !== 'undefined' - ) { - PACKAGE_PATH = encodeURIComponent( - location.pathname - .toString() - .substring( - 0, - location.pathname.toString().lastIndexOf('/') - ) + '/' - ); - } - var PACKAGE_NAME = 'privateer.data'; - var REMOTE_PACKAGE_BASE = 'privateer.data'; - if ( - typeof Module['locateFilePackage'] === 'function' && - !Module['locateFile'] - ) { - Module['locateFile'] = Module['locateFilePackage']; - err( - 'warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)' - ); - } - var REMOTE_PACKAGE_NAME = Module['locateFile'] - ? Module['locateFile'](REMOTE_PACKAGE_BASE, '') - : REMOTE_PACKAGE_BASE; - var REMOTE_PACKAGE_SIZE = metadata['remote_package_size']; - function fetchRemotePackage( - packageName, - packageSize, - callback, - errback - ) { - if ( - typeof process === 'object' && - typeof process.versions === 'object' && - typeof process.versions.node === 'string' - ) { - require('fs').readFile( - packageName, - function (err, contents) { - if (err) { - errback(err); - } else { - callback(contents.buffer); - } - } - ); - return; - } - var xhr = new XMLHttpRequest(); - xhr.open('GET', packageName, true); - xhr.responseType = 'arraybuffer'; - xhr.onprogress = function (event) { - var url = packageName; - var size = packageSize; - if (event.total) size = event.total; - if (event.loaded) { - if (!xhr.addedTotal) { - xhr.addedTotal = true; - if (!Module.dataFileDownloads) - Module.dataFileDownloads = {}; - Module.dataFileDownloads[url] = { - loaded: event.loaded, - total: size, - }; - } else { - Module.dataFileDownloads[url].loaded = - event.loaded; - } - var total = 0; - var loaded = 0; - var num = 0; - for (var download in Module.dataFileDownloads) { - var data = Module.dataFileDownloads[download]; - total += data.total; - loaded += data.loaded; - num++; - } - total = Math.ceil( - (total * Module.expectedDataFileDownloads) / num - ); - if (Module['setStatus']) - Module['setStatus']( - `Downloading data... (${loaded}/${total})` - ); - } else if (!Module.dataFileDownloads) { - if (Module['setStatus']) - Module['setStatus']('Downloading data...'); - } - }; - xhr.onerror = function (event) { - throw new Error('NetworkError for: ' + packageName); - }; - xhr.onload = function (event) { - if ( - xhr.status == 200 || - xhr.status == 304 || - xhr.status == 206 || - (xhr.status == 0 && xhr.response) - ) { - var packageData = xhr.response; - callback(packageData); - } else { - throw new Error( - xhr.statusText + ' : ' + xhr.responseURL - ); - } - }; - xhr.send(null); - } - function handleError(error) { - console.error('package error:', error); - } - var fetchedCallback = null; - var fetched = Module['getPreloadedPackage'] - ? Module['getPreloadedPackage']( - REMOTE_PACKAGE_NAME, - REMOTE_PACKAGE_SIZE - ) - : null; - if (!fetched) - fetchRemotePackage( - REMOTE_PACKAGE_NAME, - REMOTE_PACKAGE_SIZE, - function (data) { - if (fetchedCallback) { - fetchedCallback(data); - fetchedCallback = null; - } else { - fetched = data; - } - }, - handleError - ); - function runWithFS() { - function assert(check, msg) { - if (!check) throw msg + new Error().stack; - } - Module['FS_createPath']( - '/', - 'unprocessed_files', - true, - true - ); - function DataRequest(start, end, audio) { - this.start = start; - this.end = end; - this.audio = audio; - } - DataRequest.prototype = { - requests: {}, - open: function (mode, name) { - this.name = name; - this.requests[name] = this; - Module['addRunDependency'](`fp ${this.name}`); - }, - send: function () {}, - onload: function () { - var byteArray = this.byteArray.subarray( - this.start, - this.end - ); - this.finish(byteArray); - }, - finish: function (byteArray) { - var that = this; - Module['FS_createDataFile']( - this.name, - null, - byteArray, - true, - true, - true - ); - Module['removeRunDependency'](`fp ${that.name}`); - this.requests[this.name] = null; - }, - }; - var files = metadata['files']; - for (var i = 0; i < files.length; ++i) { - new DataRequest( - files[i]['start'], - files[i]['end'], - files[i]['audio'] || 0 - ).open('GET', files[i]['filename']); - } - function processPackageData(arrayBuffer) { - assert(arrayBuffer, 'Loading data file failed.'); - assert( - arrayBuffer.constructor.name === ArrayBuffer.name, - 'bad input to processPackageData' - ); - var byteArray = new Uint8Array(arrayBuffer); - DataRequest.prototype.byteArray = byteArray; - var files = metadata['files']; - for (var i = 0; i < files.length; ++i) { - DataRequest.prototype.requests[ - files[i].filename - ].onload(); - } - Module['removeRunDependency']( - 'datafile_privateer.data' - ); - } - Module['addRunDependency']('datafile_privateer.data'); - if (!Module.preloadResults) Module.preloadResults = {}; - Module.preloadResults[PACKAGE_NAME] = { fromCache: false }; - if (fetched) { - processPackageData(fetched); - fetched = null; - } else { - fetchedCallback = processPackageData; - } - } - if (Module['calledRun']) { - runWithFS(); - } else { - if (!Module['preRun']) Module['preRun'] = []; - Module['preRun'].push(runWithFS); - } - }; - loadPackage({ - files: [ - { - filename: '/privateer_torsion_database.json', - start: 0, - end: 2313860, - }, - { - filename: '/privateer_torsion_statistics.json', - start: 2313860, - end: 2326506, - }, - { - filename: '/privateer_torsions_z_score_database.json', - start: 2326506, - end: 10108540, - }, - { - filename: '/unprocessed_files/ASN-NAG_reduced.json', - start: 10108540, - end: 10757358, - }, - { - filename: '/unprocessed_files/ASN-NGA_reduced.json', - start: 10757358, - end: 10758631, - }, - { - filename: '/unprocessed_files/BGC-BGC_reduced.json', - start: 10758631, - end: 10760275, - }, - { - filename: '/unprocessed_files/BGC-GAL_reduced.json', - start: 10760275, - end: 10760795, - }, - { - filename: '/unprocessed_files/BGC-GLA_reduced.json', - start: 10760795, - end: 10761054, - }, - { - filename: '/unprocessed_files/BGC-XYS_reduced.json', - start: 10761054, - end: 10761397, - }, - { - filename: '/unprocessed_files/BMA-BMA_reduced.json', - start: 10761397, - end: 10762693, - }, - { - filename: '/unprocessed_files/BMA-GAL_reduced.json', - start: 10762693, - end: 10762868, - }, - { - filename: '/unprocessed_files/BMA-MAN_reduced.json', - start: 10762868, - end: 10888263, - }, - { - filename: '/unprocessed_files/BMA-NAG_reduced.json', - start: 10888263, - end: 10888862, - }, - { - filename: '/unprocessed_files/BMA-NDG_reduced.json', - start: 10888862, - end: 10888948, - }, - { - filename: '/unprocessed_files/BMA-XYP_reduced.json', - start: 10888948, - end: 10889890, - }, - { - filename: '/unprocessed_files/FRU-FRU_reduced.json', - start: 10889890, - end: 10890666, - }, - { - filename: '/unprocessed_files/FRU-GLC_reduced.json', - start: 10890666, - end: 10891785, - }, - { - filename: '/unprocessed_files/FUC-BGC_reduced.json', - start: 10891785, - end: 10892733, - }, - { - filename: '/unprocessed_files/GAL-A2G_reduced.json', - start: 10892733, - end: 10892991, - }, - { - filename: '/unprocessed_files/GAL-FUC_reduced.json', - start: 10892991, - end: 10893162, - }, - { - filename: '/unprocessed_files/GAL-GAL_reduced.json', - start: 10893162, - end: 10894023, - }, - { - filename: '/unprocessed_files/GAL-GLA_reduced.json', - start: 10894023, - end: 10894532, - }, - { - filename: '/unprocessed_files/GAL-NAG_reduced.json', - start: 10894532, - end: 10894961, - }, - { - filename: '/unprocessed_files/GAL-SIA_reduced.json', - start: 10894961, - end: 10899540, - }, - { - filename: '/unprocessed_files/GLA-A2G_reduced.json', - start: 10899540, - end: 10899714, - }, - { - filename: '/unprocessed_files/GLA-GLA_reduced.json', - start: 10899714, - end: 10900142, - }, - { - filename: '/unprocessed_files/GLC-BGC_reduced.json', - start: 10900142, - end: 10900319, - }, - { - filename: '/unprocessed_files/GLC-FRU_reduced.json', - start: 10900319, - end: 10900493, - }, - { - filename: '/unprocessed_files/GLC-GAL_reduced.json', - start: 10900493, - end: 10900581, - }, - { - filename: '/unprocessed_files/GLC-GLA_reduced.json', - start: 10900581, - end: 10900752, - }, - { - filename: '/unprocessed_files/GLC-GLC_reduced.json', - start: 10900752, - end: 10901525, - }, - { - filename: '/unprocessed_files/GLC-MAN_reduced.json', - start: 10901525, - end: 10901612, - }, - { - filename: '/unprocessed_files/GLC-XYS_reduced.json', - start: 10901612, - end: 10901699, - }, - { - filename: '/unprocessed_files/MAG-GAL_reduced.json', - start: 10901699, - end: 10901787, - }, - { - filename: '/unprocessed_files/MAN-BMA_reduced.json', - start: 10901787, - end: 10901875, - }, - { - filename: '/unprocessed_files/MAN-GLC_reduced.json', - start: 10901875, - end: 10902549, - }, - { - filename: '/unprocessed_files/MAN-MAN_reduced.json', - start: 10902549, - end: 10987921, - }, - { - filename: '/unprocessed_files/MAN-NAG_reduced.json', - start: 10987921, - end: 11008593, - }, - { - filename: '/unprocessed_files/NAG-BMA_reduced.json', - start: 11008593, - end: 11152243, - }, - { - filename: '/unprocessed_files/NAG-FCA_reduced.json', - start: 11152243, - end: 11152331, - }, - { - filename: '/unprocessed_files/NAG-FUC_reduced.json', - start: 11152331, - end: 11206617, - }, - { - filename: '/unprocessed_files/NAG-FUL_reduced.json', - start: 11206617, - end: 11208669, - }, - { - filename: '/unprocessed_files/NAG-GAL_reduced.json', - start: 11208669, - end: 11215929, - }, - { - filename: '/unprocessed_files/NAG-GLC_reduced.json', - start: 11215929, - end: 11216018, - }, - { - filename: '/unprocessed_files/NAG-MAN_reduced.json', - start: 11216018, - end: 11216364, - }, - { - filename: '/unprocessed_files/NAG-NAG_reduced.json', - start: 11216364, - end: 11545985, - }, - { - filename: '/unprocessed_files/NAG-NDG_reduced.json', - start: 11545985, - end: 11546494, - }, - { - filename: '/unprocessed_files/NAG-SIA_reduced.json', - start: 11546494, - end: 11546667, - }, - { - filename: '/unprocessed_files/NDG-BMA_reduced.json', - start: 11546667, - end: 11546928, - }, - { - filename: '/unprocessed_files/NDG-GAL_reduced.json', - start: 11546928, - end: 11547102, - }, - { - filename: '/unprocessed_files/NDG-NAG_reduced.json', - start: 11547102, - end: 11547278, - }, - { - filename: '/unprocessed_files/NGA-GAL_reduced.json', - start: 11547278, - end: 11547454, - }, - { - filename: '/unprocessed_files/NGA-NAG_reduced.json', - start: 11547454, - end: 11547542, - }, - { - filename: '/unprocessed_files/PA1-GCS_reduced.json', - start: 11547542, - end: 11547631, - }, - { - filename: '/unprocessed_files/XYP-GCV_reduced.json', - start: 11547631, - end: 11547719, - }, - { - filename: '/unprocessed_files/XYP-XYP_reduced.json', - start: 11547719, - end: 11548065, - }, - ], - remote_package_size: 11548065, - }); - })(); - if (Module['ENVIRONMENT_IS_PTHREAD'] || Module['$ww']) - Module['preRun'] = []; - var necessaryPreJSTasks = Module['preRun'].slice(); - if (!Module['preRun']) - throw 'Module.preRun should exist because file support used it; did a pre-js delete it?'; - necessaryPreJSTasks.forEach(function (task) { - if (Module['preRun'].indexOf(task) < 0) - throw 'All preRun tasks that exist before user pre-js code should remain after; did you replace Module or modify Module.preRun?'; - }); - var moduleOverrides = Object.assign({}, Module); - var arguments_ = []; - var thisProgram = './this.program'; - var quit_ = (status, toThrow) => { - throw toThrow; - }; - var ENVIRONMENT_IS_WEB = typeof window == 'object'; - var ENVIRONMENT_IS_WORKER = typeof importScripts == 'function'; - var ENVIRONMENT_IS_NODE = - typeof process == 'object' && - typeof process.versions == 'object' && - typeof process.versions.node == 'string'; - var ENVIRONMENT_IS_SHELL = - !ENVIRONMENT_IS_WEB && - !ENVIRONMENT_IS_NODE && - !ENVIRONMENT_IS_WORKER; - if (Module['ENVIRONMENT']) { - throw new Error( - 'Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)' - ); - } - var scriptDirectory = ''; - function locateFile(path) { - if (Module['locateFile']) { - return Module['locateFile'](path, scriptDirectory); - } - return scriptDirectory + path; - } - var read_, readAsync, readBinary, setWindowTitle; - if (ENVIRONMENT_IS_NODE) { - if ( - typeof process == 'undefined' || - !process.release || - process.release.name !== 'node' - ) - throw new Error( - 'not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)' - ); - var nodeVersion = process.versions.node; - var numericVersion = nodeVersion.split('.').slice(0, 3); - numericVersion = - numericVersion[0] * 1e4 + - numericVersion[1] * 100 + - numericVersion[2].split('-')[0] * 1; - if (numericVersion < 16e4) { - throw new Error( - 'This emscripten-generated code requires node v16.0.0 (detected v' + - nodeVersion + - ')' - ); - } - const { createRequire: createRequire } = await import('module'); - var require = createRequire(import.meta.url); - var fs = require('fs'); - var nodePath = require('path'); - if (ENVIRONMENT_IS_WORKER) { - scriptDirectory = nodePath.dirname(scriptDirectory) + '/'; - } else { - scriptDirectory = require('url').fileURLToPath( - new URL('./', import.meta.url) - ); - } - read_ = (filename, binary) => { - filename = isFileURI(filename) - ? new URL(filename) - : nodePath.normalize(filename); - return fs.readFileSync(filename, binary ? undefined : 'utf8'); - }; - readBinary = (filename) => { - var ret = read_(filename, true); - if (!ret.buffer) { - ret = new Uint8Array(ret); - } - assert(ret.buffer); - return ret; - }; - readAsync = (filename, onload, onerror, binary = true) => { - filename = isFileURI(filename) - ? new URL(filename) - : nodePath.normalize(filename); - fs.readFile( - filename, - binary ? undefined : 'utf8', - (err, data) => { - if (err) onerror(err); - else onload(binary ? data.buffer : data); - } - ); - }; - if (!Module['thisProgram'] && process.argv.length > 1) { - thisProgram = process.argv[1].replace(/\\/g, '/'); - } - arguments_ = process.argv.slice(2); - quit_ = (status, toThrow) => { - process.exitCode = status; - throw toThrow; - }; - Module['inspect'] = () => '[Emscripten Module object]'; - } else if (ENVIRONMENT_IS_SHELL) { - if ( - (typeof process == 'object' && typeof require === 'function') || - typeof window == 'object' || - typeof importScripts == 'function' - ) - throw new Error( - 'not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)' - ); - if (typeof read != 'undefined') { - read_ = (f) => read(f); - } - readBinary = (f) => { - let data; - if (typeof readbuffer == 'function') { - return new Uint8Array(readbuffer(f)); - } - data = read(f, 'binary'); - assert(typeof data == 'object'); - return data; - }; - readAsync = (f, onload, onerror) => { - setTimeout(() => onload(readBinary(f))); - }; - if (typeof clearTimeout == 'undefined') { - globalThis.clearTimeout = (id) => {}; - } - if (typeof setTimeout == 'undefined') { - globalThis.setTimeout = (f) => - typeof f == 'function' ? f() : abort(); - } - if (typeof scriptArgs != 'undefined') { - arguments_ = scriptArgs; - } else if (typeof arguments != 'undefined') { - arguments_ = arguments; - } - if (typeof quit == 'function') { - quit_ = (status, toThrow) => { - setTimeout(() => { - if (!(toThrow instanceof ExitStatus)) { - let toLog = toThrow; - if ( - toThrow && - typeof toThrow == 'object' && - toThrow.stack - ) { - toLog = [toThrow, toThrow.stack]; - } - err(`exiting due to exception: ${toLog}`); - } - quit(status); - }); - throw toThrow; - }; - } - if (typeof print != 'undefined') { - if (typeof console == 'undefined') console = {}; - console.log = print; - console.warn = console.error = - typeof printErr != 'undefined' ? printErr : print; - } - } else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { - if (ENVIRONMENT_IS_WORKER) { - scriptDirectory = self.location.href; - } else if ( - typeof document != 'undefined' && - document.currentScript - ) { - scriptDirectory = document.currentScript.src; - } - if (_scriptDir) { - scriptDirectory = _scriptDir; - } - if (scriptDirectory.indexOf('blob:') !== 0) { - scriptDirectory = scriptDirectory.substr( - 0, - scriptDirectory.replace(/[?#].*/, '').lastIndexOf('/') + 1 - ); - } else { - scriptDirectory = ''; - } - if ( - !( - typeof window == 'object' || - typeof importScripts == 'function' - ) - ) - throw new Error( - 'not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)' - ); - { - read_ = (url) => { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, false); - xhr.send(null); - return xhr.responseText; - }; - if (ENVIRONMENT_IS_WORKER) { - readBinary = (url) => { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, false); - xhr.responseType = 'arraybuffer'; - xhr.send(null); - return new Uint8Array(xhr.response); - }; - } - readAsync = (url, onload, onerror) => { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, true); - xhr.responseType = 'arraybuffer'; - xhr.onload = () => { - if ( - xhr.status == 200 || - (xhr.status == 0 && xhr.response) - ) { - onload(xhr.response); - return; - } - onerror(); - }; - xhr.onerror = onerror; - xhr.send(null); - }; - } - setWindowTitle = (title) => (document.title = title); - } else { - throw new Error('environment detection error'); - } - var out = Module['print'] || console.log.bind(console); - var err = Module['printErr'] || console.error.bind(console); - Object.assign(Module, moduleOverrides); - moduleOverrides = null; - checkIncomingModuleAPI(); - if (Module['arguments']) arguments_ = Module['arguments']; - legacyModuleProp('arguments', 'arguments_'); - if (Module['thisProgram']) thisProgram = Module['thisProgram']; - legacyModuleProp('thisProgram', 'thisProgram'); - if (Module['quit']) quit_ = Module['quit']; - legacyModuleProp('quit', 'quit_'); - assert( - typeof Module['memoryInitializerPrefixURL'] == 'undefined', - 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead' - ); - assert( - typeof Module['pthreadMainPrefixURL'] == 'undefined', - 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead' - ); - assert( - typeof Module['cdInitializerPrefixURL'] == 'undefined', - 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead' - ); - assert( - typeof Module['filePackagePrefixURL'] == 'undefined', - 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead' - ); - assert( - typeof Module['read'] == 'undefined', - 'Module.read option was removed (modify read_ in JS)' - ); - assert( - typeof Module['readAsync'] == 'undefined', - 'Module.readAsync option was removed (modify readAsync in JS)' - ); - assert( - typeof Module['readBinary'] == 'undefined', - 'Module.readBinary option was removed (modify readBinary in JS)' - ); - assert( - typeof Module['setWindowTitle'] == 'undefined', - 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)' - ); - assert( - typeof Module['TOTAL_MEMORY'] == 'undefined', - 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY' - ); - legacyModuleProp('read', 'read_'); - legacyModuleProp('readAsync', 'readAsync'); - legacyModuleProp('readBinary', 'readBinary'); - legacyModuleProp('setWindowTitle', 'setWindowTitle'); - assert( - !ENVIRONMENT_IS_SHELL, - "shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable." - ); - var wasmBinary; - if (Module['wasmBinary']) wasmBinary = Module['wasmBinary']; - legacyModuleProp('wasmBinary', 'wasmBinary'); - var noExitRuntime = Module['noExitRuntime'] || false; - legacyModuleProp('noExitRuntime', 'noExitRuntime'); - if (typeof WebAssembly != 'object') { - abort('no native wasm support detected'); - } - var wasmMemory; - var ABORT = false; - var EXITSTATUS; - function assert(condition, text) { - if (!condition) { - abort('Assertion failed' + (text ? ': ' + text : '')); - } - } - var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64; - function updateMemoryViews() { - var b = wasmMemory.buffer; - Module['HEAP8'] = HEAP8 = new Int8Array(b); - Module['HEAP16'] = HEAP16 = new Int16Array(b); - Module['HEAP32'] = HEAP32 = new Int32Array(b); - Module['HEAPU8'] = HEAPU8 = new Uint8Array(b); - Module['HEAPU16'] = HEAPU16 = new Uint16Array(b); - Module['HEAPU32'] = HEAPU32 = new Uint32Array(b); - Module['HEAPF32'] = HEAPF32 = new Float32Array(b); - Module['HEAPF64'] = HEAPF64 = new Float64Array(b); - } - assert( - !Module['STACK_SIZE'], - 'STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time' - ); - assert( - typeof Int32Array != 'undefined' && - typeof Float64Array !== 'undefined' && - Int32Array.prototype.subarray != undefined && - Int32Array.prototype.set != undefined, - 'JS engine does not provide full typed array support' - ); - assert( - !Module['wasmMemory'], - 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally' - ); - assert( - !Module['INITIAL_MEMORY'], - 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically' - ); - var wasmTable; - function writeStackCookie() { - var max = _emscripten_stack_get_end(); - assert((max & 3) == 0); - if (max == 0) { - max += 4; - } - HEAPU32[max >> 2] = 34821223; - checkInt32(34821223); - HEAPU32[(max + 4) >> 2] = 2310721022; - checkInt32(2310721022); - HEAPU32[0 >> 2] = 1668509029; - checkInt32(1668509029); - } - function checkStackCookie() { - if (ABORT) return; - var max = _emscripten_stack_get_end(); - if (max == 0) { - max += 4; - } - var cookie1 = HEAPU32[max >> 2]; - var cookie2 = HEAPU32[(max + 4) >> 2]; - if (cookie1 != 34821223 || cookie2 != 2310721022) { - abort( - `Stack overflow! Stack cookie has been overwritten at ${ptrToString( - max - )}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString( - cookie2 - )} ${ptrToString(cookie1)}` - ); - } - if (HEAPU32[0 >> 2] != 1668509029) { - abort( - 'Runtime error: The application has corrupted its heap memory area (address zero)!' - ); - } - } - (function () { - var h16 = new Int16Array(1); - var h8 = new Int8Array(h16.buffer); - h16[0] = 25459; - if (h8[0] !== 115 || h8[1] !== 99) - throw 'Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)'; - })(); - var __ATPRERUN__ = []; - var __ATINIT__ = []; - var __ATEXIT__ = []; - var __ATPOSTRUN__ = []; - var runtimeInitialized = false; - var runtimeExited = false; - var runtimeKeepaliveCounter = 0; - function preRun() { - if (Module['preRun']) { - if (typeof Module['preRun'] == 'function') - Module['preRun'] = [Module['preRun']]; - while (Module['preRun'].length) { - addOnPreRun(Module['preRun'].shift()); - } - } - callRuntimeCallbacks(__ATPRERUN__); - } - function initRuntime() { - assert(!runtimeInitialized); - runtimeInitialized = true; - checkStackCookie(); - setStackLimits(); - if (!Module['noFSInit'] && !FS.init.initialized) FS.init(); - FS.ignorePermissions = false; - TTY.init(); - callRuntimeCallbacks(__ATINIT__); - } - function postRun() { - checkStackCookie(); - if (Module['postRun']) { - if (typeof Module['postRun'] == 'function') - Module['postRun'] = [Module['postRun']]; - while (Module['postRun'].length) { - addOnPostRun(Module['postRun'].shift()); - } - } - callRuntimeCallbacks(__ATPOSTRUN__); - } - function addOnPreRun(cb) { - __ATPRERUN__.unshift(cb); - } - function addOnInit(cb) { - __ATINIT__.unshift(cb); - } - function addOnPostRun(cb) { - __ATPOSTRUN__.unshift(cb); - } - assert( - Math.imul, - 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill' - ); - assert( - Math.fround, - 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill' - ); - assert( - Math.clz32, - 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill' - ); - assert( - Math.trunc, - 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill' - ); - var runDependencies = 0; - var runDependencyWatcher = null; - var dependenciesFulfilled = null; - var runDependencyTracking = {}; - function getUniqueRunDependency(id) { - var orig = id; - while (1) { - if (!runDependencyTracking[id]) return id; - id = orig + Math.random(); - } - } - function addRunDependency(id) { - runDependencies++; - if (Module['monitorRunDependencies']) { - Module['monitorRunDependencies'](runDependencies); - } - if (id) { - assert(!runDependencyTracking[id]); - runDependencyTracking[id] = 1; - if ( - runDependencyWatcher === null && - typeof setInterval != 'undefined' - ) { - runDependencyWatcher = setInterval(() => { - if (ABORT) { - clearInterval(runDependencyWatcher); - runDependencyWatcher = null; - return; - } - var shown = false; - for (var dep in runDependencyTracking) { - if (!shown) { - shown = true; - err('still waiting on run dependencies:'); - } - err('dependency: ' + dep); - } - if (shown) { - err('(end of list)'); - } - }, 1e4); - } - } else { - err('warning: run dependency added without ID'); - } - } - function removeRunDependency(id) { - runDependencies--; - if (Module['monitorRunDependencies']) { - Module['monitorRunDependencies'](runDependencies); - } - if (id) { - assert(runDependencyTracking[id]); - delete runDependencyTracking[id]; - } else { - err('warning: run dependency removed without ID'); - } - if (runDependencies == 0) { - if (runDependencyWatcher !== null) { - clearInterval(runDependencyWatcher); - runDependencyWatcher = null; - } - if (dependenciesFulfilled) { - var callback = dependenciesFulfilled; - dependenciesFulfilled = null; - callback(); - } - } - } - function abort(what) { - if (Module['onAbort']) { - Module['onAbort'](what); - } - what = 'Aborted(' + what + ')'; - err(what); - ABORT = true; - EXITSTATUS = 1; - if (runtimeInitialized) { - ___trap(); - } - var e = new WebAssembly.RuntimeError(what); - readyPromiseReject(e); - throw e; - } - var dataURIPrefix = 'data:application/octet-stream;base64,'; - function isDataURI(filename) { - return filename.startsWith(dataURIPrefix); - } - function isFileURI(filename) { - return filename.startsWith('file://'); - } - function createExportWrapper(name, fixedasm) { - return function () { - var displayName = name; - var asm = fixedasm; - if (!fixedasm) { - asm = Module['asm']; - } - assert( - runtimeInitialized, - 'native function `' + - displayName + - '` called before runtime initialization' - ); - assert( - !runtimeExited, - 'native function `' + - displayName + - '` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)' - ); - if (!asm[name]) { - assert( - asm[name], - 'exported native function `' + - displayName + - '` not found' - ); - } - return asm[name].apply(null, arguments); - }; - } - var wasmBinaryFile; - if (Module['locateFile']) { - wasmBinaryFile = 'privateer.wasm'; - if (!isDataURI(wasmBinaryFile)) { - wasmBinaryFile = locateFile(wasmBinaryFile); - } - } else { - wasmBinaryFile = new URL('privateer.wasm', import.meta.url).href; - } - function getBinarySync(file) { - if (file == wasmBinaryFile && wasmBinary) { - return new Uint8Array(wasmBinary); - } - if (readBinary) { - return readBinary(file); - } - throw 'both async and sync fetching of the wasm failed'; - } - function getBinaryPromise(binaryFile) { - if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) { - if (typeof fetch == 'function' && !isFileURI(binaryFile)) { - return fetch(binaryFile, { credentials: 'same-origin' }) - .then((response) => { - if (!response['ok']) { - throw ( - "failed to load wasm binary file at '" + - binaryFile + - "'" - ); - } - return response['arrayBuffer'](); - }) - .catch(() => getBinarySync(binaryFile)); - } else if (readAsync) { - return new Promise((resolve, reject) => { - readAsync( - binaryFile, - (response) => resolve(new Uint8Array(response)), - reject - ); - }); - } - } - return Promise.resolve().then(() => getBinarySync(binaryFile)); - } - function instantiateArrayBuffer(binaryFile, imports, receiver) { - return getBinaryPromise(binaryFile) - .then((binary) => WebAssembly.instantiate(binary, imports)) - .then((instance) => instance) - .then(receiver, (reason) => { - err('failed to asynchronously prepare wasm: ' + reason); - if (isFileURI(wasmBinaryFile)) { - err( - 'warning: Loading from a file URI (' + - wasmBinaryFile + - ') is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing' - ); - } - abort(reason); - }); - } - function instantiateAsync(binary, binaryFile, imports, callback) { - if ( - !binary && - typeof WebAssembly.instantiateStreaming == 'function' && - !isDataURI(binaryFile) && - !isFileURI(binaryFile) && - !ENVIRONMENT_IS_NODE && - typeof fetch == 'function' - ) { - return fetch(binaryFile, { credentials: 'same-origin' }).then( - (response) => { - var result = WebAssembly.instantiateStreaming( - response, - imports - ); - return result.then(callback, function (reason) { - err('wasm streaming compile failed: ' + reason); - err('falling back to ArrayBuffer instantiation'); - return instantiateArrayBuffer( - binaryFile, - imports, - callback - ); - }); - } - ); - } - return instantiateArrayBuffer(binaryFile, imports, callback); - } - function createWasm() { - var info = { - env: wasmImports, - wasi_snapshot_preview1: wasmImports, - }; - function receiveInstance(instance, module) { - var exports = instance.exports; - Module['asm'] = exports; - wasmMemory = Module['asm']['memory']; - assert(wasmMemory, 'memory not found in wasm exports'); - updateMemoryViews(); - wasmTable = Module['asm']['__indirect_function_table']; - assert(wasmTable, 'table not found in wasm exports'); - addOnInit(Module['asm']['__wasm_call_ctors']); - removeRunDependency('wasm-instantiate'); - return exports; - } - addRunDependency('wasm-instantiate'); - var trueModule = Module; - function receiveInstantiationResult(result) { - assert( - Module === trueModule, - 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?' - ); - trueModule = null; - receiveInstance(result['instance']); - } - if (Module['instantiateWasm']) { - try { - return Module['instantiateWasm'](info, receiveInstance); - } catch (e) { - err( - 'Module.instantiateWasm callback failed with error: ' + - e - ); - readyPromiseReject(e); - } - } - instantiateAsync( - wasmBinary, - wasmBinaryFile, - info, - receiveInstantiationResult - ).catch(readyPromiseReject); - return {}; - } - var tempDouble; - var tempI64; - function legacyModuleProp(prop, newName) { - if (!Object.getOwnPropertyDescriptor(Module, prop)) { - Object.defineProperty(Module, prop, { - configurable: true, - get() { - abort( - 'Module.' + - prop + - ' has been replaced with plain ' + - newName + - ' (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)' - ); - }, - }); - } - } - function ignoredModuleProp(prop) { - if (Object.getOwnPropertyDescriptor(Module, prop)) { - abort( - '`Module.' + - prop + - '` was supplied but `' + - prop + - '` not included in INCOMING_MODULE_JS_API' - ); - } - } - function isExportedByForceFilesystem(name) { - return ( - name === 'FS_createPath' || - name === 'FS_createDataFile' || - name === 'FS_createPreloadedFile' || - name === 'FS_unlink' || - name === 'addRunDependency' || - name === 'FS_createLazyFile' || - name === 'FS_createDevice' || - name === 'removeRunDependency' - ); - } - function missingGlobal(sym, msg) { - if (typeof globalThis !== 'undefined') { - Object.defineProperty(globalThis, sym, { - configurable: true, - get() { - warnOnce( - '`' + - sym + - '` is not longer defined by emscripten. ' + - msg - ); - return undefined; - }, - }); - } - } - missingGlobal('buffer', 'Please use HEAP8.buffer or wasmMemory.buffer'); - function missingLibrarySymbol(sym) { - if ( - typeof globalThis !== 'undefined' && - !Object.getOwnPropertyDescriptor(globalThis, sym) - ) { - Object.defineProperty(globalThis, sym, { - configurable: true, - get() { - var msg = - '`' + - sym + - '` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line'; - var librarySymbol = sym; - if (!librarySymbol.startsWith('_')) { - librarySymbol = '$' + sym; - } - msg += - " (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='" + - librarySymbol + - "')"; - if (isExportedByForceFilesystem(sym)) { - msg += - '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you'; - } - warnOnce(msg); - return undefined; - }, - }); - } - unexportedRuntimeSymbol(sym); - } - function unexportedRuntimeSymbol(sym) { - if (!Object.getOwnPropertyDescriptor(Module, sym)) { - Object.defineProperty(Module, sym, { - configurable: true, - get() { - var msg = - "'" + - sym + - "' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)"; - if (isExportedByForceFilesystem(sym)) { - msg += - '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you'; - } - abort(msg); - }, - }); - } - } - var MAX_UINT8 = 2 ** 8 - 1; - var MAX_UINT16 = 2 ** 16 - 1; - var MAX_UINT32 = 2 ** 32 - 1; - var MAX_UINT53 = 2 ** 53 - 1; - var MAX_UINT64 = 2 ** 64 - 1; - var MIN_INT8 = -(2 ** (8 - 1)) + 1; - var MIN_INT16 = -(2 ** (16 - 1)) + 1; - var MIN_INT32 = -(2 ** (32 - 1)) + 1; - var MIN_INT53 = -(2 ** (53 - 1)) + 1; - var MIN_INT64 = -(2 ** (64 - 1)) + 1; - function checkInt(value, bits, min, max) { - assert( - Number.isInteger(Number(value)), - 'attempt to write non-integer (' + value + ') into integer heap' - ); - assert( - value <= max, - 'value (' + - value + - ') too large to write as ' + - bits + - '-bit value' - ); - assert( - value >= min, - 'value (' + - value + - ') too small to write as ' + - bits + - '-bit value' - ); - } - var checkInt8 = (value) => checkInt(value, 8, MIN_INT8, MAX_UINT8); - var checkInt16 = (value) => checkInt(value, 16, MIN_INT16, MAX_UINT16); - var checkInt32 = (value) => checkInt(value, 32, MIN_INT32, MAX_UINT32); - var checkInt64 = (value) => checkInt(value, 64, MIN_INT64, MAX_UINT64); - function ExitStatus(status) { - this.name = 'ExitStatus'; - this.message = `Program terminated with exit(${status})`; - this.status = status; - } - var callRuntimeCallbacks = (callbacks) => { - while (callbacks.length > 0) { - callbacks.shift()(Module); - } - }; - function getCppExceptionTag() { - return Module['asm']['__cpp_exception']; - } - function getCppExceptionThrownObjectFromWebAssemblyException(ex) { - var unwind_header = ex.getArg(getCppExceptionTag(), 0); - return ___thrown_object_from_unwind_exception(unwind_header); - } - var withStackSave = (f) => { - var stack = stackSave(); - var ret = f(); - stackRestore(stack); - return ret; - }; - var UTF8Decoder = - typeof TextDecoder != 'undefined' - ? new TextDecoder('utf8') - : undefined; - var UTF8ArrayToString = (heapOrArray, idx, maxBytesToRead) => { - var endIdx = idx + maxBytesToRead; - var endPtr = idx; - while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr; - if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) { - return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr)); - } - var str = ''; - while (idx < endPtr) { - var u0 = heapOrArray[idx++]; - if (!(u0 & 128)) { - str += String.fromCharCode(u0); - continue; - } - var u1 = heapOrArray[idx++] & 63; - if ((u0 & 224) == 192) { - str += String.fromCharCode(((u0 & 31) << 6) | u1); - continue; - } - var u2 = heapOrArray[idx++] & 63; - if ((u0 & 240) == 224) { - u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; - } else { - if ((u0 & 248) != 240) - warnOnce( - 'Invalid UTF-8 leading byte ' + - ptrToString(u0) + - ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!' - ); - u0 = - ((u0 & 7) << 18) | - (u1 << 12) | - (u2 << 6) | - (heapOrArray[idx++] & 63); - } - if (u0 < 65536) { - str += String.fromCharCode(u0); - } else { - var ch = u0 - 65536; - str += String.fromCharCode( - 55296 | (ch >> 10), - 56320 | (ch & 1023) - ); - } - } - return str; - }; - var UTF8ToString = (ptr, maxBytesToRead) => { - assert(typeof ptr == 'number'); - return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ''; - }; - var getExceptionMessageCommon = (ptr) => - withStackSave(() => { - var type_addr_addr = stackAlloc(4); - var message_addr_addr = stackAlloc(4); - ___get_exception_message( - ptr, - type_addr_addr, - message_addr_addr - ); - var type_addr = HEAPU32[type_addr_addr >> 2]; - var message_addr = HEAPU32[message_addr_addr >> 2]; - var type = UTF8ToString(type_addr); - _free(type_addr); - var message; - if (message_addr) { - message = UTF8ToString(message_addr); - _free(message_addr); - } - return [type, message]; - }); - function getExceptionMessage(ex) { - var ptr = getCppExceptionThrownObjectFromWebAssemblyException(ex); - return getExceptionMessageCommon(ptr); - } - Module['getExceptionMessage'] = getExceptionMessage; - var ptrToString = (ptr) => { - assert(typeof ptr === 'number'); - ptr >>>= 0; - return '0x' + ptr.toString(16).padStart(8, '0'); - }; - var setStackLimits = () => { - var stackLow = _emscripten_stack_get_base(); - var stackHigh = _emscripten_stack_get_end(); - ___set_stack_limits(stackLow, stackHigh); - }; - var warnOnce = (text) => { - if (!warnOnce.shown) warnOnce.shown = {}; - if (!warnOnce.shown[text]) { - warnOnce.shown[text] = 1; - if (ENVIRONMENT_IS_NODE) text = 'warning: ' + text; - err(text); - } - }; - var ___assert_fail = (condition, filename, line, func) => { - abort( - `Assertion failed: ${UTF8ToString(condition)}, at: ` + - [ - filename ? UTF8ToString(filename) : 'unknown filename', - line, - func ? UTF8ToString(func) : 'unknown function', - ] - ); - }; - var ___handle_stack_overflow = (requested) => { - var base = _emscripten_stack_get_base(); - var end = _emscripten_stack_get_end(); - abort( - `stack overflow (Attempt to set SP to ${ptrToString( - requested - )}` + - `, with stack limits [${ptrToString(end)} - ${ptrToString( - base - )}` + - ']). If you require more stack space build with -sSTACK_SIZE=' - ); - }; - var setErrNo = (value) => { - HEAP32[___errno_location() >> 2] = value; - checkInt32(value); - return value; - }; - var PATH = { - isAbs: (path) => path.charAt(0) === '/', - splitPath: (filename) => { - var splitPathRe = - /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; - return splitPathRe.exec(filename).slice(1); - }, - normalizeArray: (parts, allowAboveRoot) => { - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } - if (allowAboveRoot) { - for (; up; up--) { - parts.unshift('..'); - } - } - return parts; - }, - normalize: (path) => { - var isAbsolute = PATH.isAbs(path), - trailingSlash = path.substr(-1) === '/'; - path = PATH.normalizeArray( - path.split('/').filter((p) => !!p), - !isAbsolute - ).join('/'); - if (!path && !isAbsolute) { - path = '.'; - } - if (path && trailingSlash) { - path += '/'; - } - return (isAbsolute ? '/' : '') + path; - }, - dirname: (path) => { - var result = PATH.splitPath(path), - root = result[0], - dir = result[1]; - if (!root && !dir) { - return '.'; - } - if (dir) { - dir = dir.substr(0, dir.length - 1); - } - return root + dir; - }, - basename: (path) => { - if (path === '/') return '/'; - path = PATH.normalize(path); - path = path.replace(/\/$/, ''); - var lastSlash = path.lastIndexOf('/'); - if (lastSlash === -1) return path; - return path.substr(lastSlash + 1); - }, - join: function () { - var paths = Array.prototype.slice.call(arguments); - return PATH.normalize(paths.join('/')); - }, - join2: (l, r) => PATH.normalize(l + '/' + r), - }; - var initRandomFill = () => { - if ( - typeof crypto == 'object' && - typeof crypto['getRandomValues'] == 'function' - ) { - return (view) => crypto.getRandomValues(view); - } else if (ENVIRONMENT_IS_NODE) { - try { - var crypto_module = require('crypto'); - var randomFillSync = crypto_module['randomFillSync']; - if (randomFillSync) { - return (view) => crypto_module['randomFillSync'](view); - } - var randomBytes = crypto_module['randomBytes']; - return (view) => ( - view.set(randomBytes(view.byteLength)), view - ); - } catch (e) {} - } - abort( - 'no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: (array) => { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };' - ); - }; - var randomFill = (view) => (randomFill = initRandomFill())(view); - var PATH_FS = { - resolve: function () { - var resolvedPath = '', - resolvedAbsolute = false; - for ( - var i = arguments.length - 1; - i >= -1 && !resolvedAbsolute; - i-- - ) { - var path = i >= 0 ? arguments[i] : FS.cwd(); - if (typeof path != 'string') { - throw new TypeError( - 'Arguments to path.resolve must be strings' - ); - } else if (!path) { - return ''; - } - resolvedPath = path + '/' + resolvedPath; - resolvedAbsolute = PATH.isAbs(path); - } - resolvedPath = PATH.normalizeArray( - resolvedPath.split('/').filter((p) => !!p), - !resolvedAbsolute - ).join('/'); - return (resolvedAbsolute ? '/' : '') + resolvedPath || '.'; - }, - relative: (from, to) => { - from = PATH_FS.resolve(from).substr(1); - to = PATH_FS.resolve(to).substr(1); - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') break; - } - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') break; - } - if (start > end) return []; - return arr.slice(start, end - start + 1); - } - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); - } - outputParts = outputParts.concat( - toParts.slice(samePartsLength) - ); - return outputParts.join('/'); - }, - }; - var FS_stdin_getChar_buffer = []; - var lengthBytesUTF8 = (str) => { - var len = 0; - for (var i = 0; i < str.length; ++i) { - var c = str.charCodeAt(i); - if (c <= 127) { - len++; - } else if (c <= 2047) { - len += 2; - } else if (c >= 55296 && c <= 57343) { - len += 4; - ++i; - } else { - len += 3; - } - } - return len; - }; - var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => { - assert(typeof str === 'string'); - if (!(maxBytesToWrite > 0)) return 0; - var startIdx = outIdx; - var endIdx = outIdx + maxBytesToWrite - 1; - for (var i = 0; i < str.length; ++i) { - var u = str.charCodeAt(i); - if (u >= 55296 && u <= 57343) { - var u1 = str.charCodeAt(++i); - u = (65536 + ((u & 1023) << 10)) | (u1 & 1023); - } - if (u <= 127) { - if (outIdx >= endIdx) break; - heap[outIdx++] = u; - } else if (u <= 2047) { - if (outIdx + 1 >= endIdx) break; - heap[outIdx++] = 192 | (u >> 6); - heap[outIdx++] = 128 | (u & 63); - } else if (u <= 65535) { - if (outIdx + 2 >= endIdx) break; - heap[outIdx++] = 224 | (u >> 12); - heap[outIdx++] = 128 | ((u >> 6) & 63); - heap[outIdx++] = 128 | (u & 63); - } else { - if (outIdx + 3 >= endIdx) break; - if (u > 1114111) - warnOnce( - 'Invalid Unicode code point ' + - ptrToString(u) + - ' encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).' - ); - heap[outIdx++] = 240 | (u >> 18); - heap[outIdx++] = 128 | ((u >> 12) & 63); - heap[outIdx++] = 128 | ((u >> 6) & 63); - heap[outIdx++] = 128 | (u & 63); - } - } - heap[outIdx] = 0; - return outIdx - startIdx; - }; - function intArrayFromString(stringy, dontAddNull, length) { - var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1; - var u8array = new Array(len); - var numBytesWritten = stringToUTF8Array( - stringy, - u8array, - 0, - u8array.length - ); - if (dontAddNull) u8array.length = numBytesWritten; - return u8array; - } - var FS_stdin_getChar = () => { - if (!FS_stdin_getChar_buffer.length) { - var result = null; - if (ENVIRONMENT_IS_NODE) { - var BUFSIZE = 256; - var buf = Buffer.alloc(BUFSIZE); - var bytesRead = 0; - var fd = process.stdin.fd; - try { - bytesRead = fs.readSync(fd, buf, 0, BUFSIZE, -1); - } catch (e) { - if (e.toString().includes('EOF')) bytesRead = 0; - else throw e; - } - if (bytesRead > 0) { - result = buf.slice(0, bytesRead).toString('utf-8'); - } else { - result = null; - } - } else if ( - typeof window != 'undefined' && - typeof window.prompt == 'function' - ) { - result = window.prompt('Input: '); - if (result !== null) { - result += '\n'; - } - } else if (typeof readline == 'function') { - result = readline(); - if (result !== null) { - result += '\n'; - } - } - if (!result) { - return null; - } - FS_stdin_getChar_buffer = intArrayFromString(result, true); - } - return FS_stdin_getChar_buffer.shift(); - }; - var TTY = { - ttys: [], - init: function () {}, - shutdown: function () {}, - register: function (dev, ops) { - TTY.ttys[dev] = { input: [], output: [], ops: ops }; - FS.registerDevice(dev, TTY.stream_ops); - }, - stream_ops: { - open: function (stream) { - var tty = TTY.ttys[stream.node.rdev]; - if (!tty) { - throw new FS.ErrnoError(43); - } - stream.tty = tty; - stream.seekable = false; - }, - close: function (stream) { - stream.tty.ops.fsync(stream.tty); - }, - fsync: function (stream) { - stream.tty.ops.fsync(stream.tty); - }, - read: function (stream, buffer, offset, length, pos) { - if (!stream.tty || !stream.tty.ops.get_char) { - throw new FS.ErrnoError(60); - } - var bytesRead = 0; - for (var i = 0; i < length; i++) { - var result; - try { - result = stream.tty.ops.get_char(stream.tty); - } catch (e) { - throw new FS.ErrnoError(29); - } - if (result === undefined && bytesRead === 0) { - throw new FS.ErrnoError(6); - } - if (result === null || result === undefined) break; - bytesRead++; - buffer[offset + i] = result; - } - if (bytesRead) { - stream.node.timestamp = Date.now(); - } - return bytesRead; - }, - write: function (stream, buffer, offset, length, pos) { - if (!stream.tty || !stream.tty.ops.put_char) { - throw new FS.ErrnoError(60); - } - try { - for (var i = 0; i < length; i++) { - stream.tty.ops.put_char( - stream.tty, - buffer[offset + i] - ); - } - } catch (e) { - throw new FS.ErrnoError(29); - } - if (length) { - stream.node.timestamp = Date.now(); - } - return i; - }, - }, - default_tty_ops: { - get_char: function (tty) { - return FS_stdin_getChar(); - }, - put_char: function (tty, val) { - if (val === null || val === 10) { - out(UTF8ArrayToString(tty.output, 0)); - tty.output = []; - } else { - if (val != 0) tty.output.push(val); - } - }, - fsync: function (tty) { - if (tty.output && tty.output.length > 0) { - out(UTF8ArrayToString(tty.output, 0)); - tty.output = []; - } - }, - ioctl_tcgets: function (tty) { - return { - c_iflag: 25856, - c_oflag: 5, - c_cflag: 191, - c_lflag: 35387, - c_cc: [ - 3, 28, 127, 21, 4, 0, 1, 0, 17, 19, 26, 0, 18, 15, - 23, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, - ], - }; - }, - ioctl_tcsets: function (tty, optional_actions, data) { - return 0; - }, - ioctl_tiocgwinsz: function (tty) { - return [24, 80]; - }, - }, - default_tty1_ops: { - put_char: function (tty, val) { - if (val === null || val === 10) { - err(UTF8ArrayToString(tty.output, 0)); - tty.output = []; - } else { - if (val != 0) tty.output.push(val); - } - }, - fsync: function (tty) { - if (tty.output && tty.output.length > 0) { - err(UTF8ArrayToString(tty.output, 0)); - tty.output = []; - } - }, - }, - }; - var zeroMemory = (address, size) => { - HEAPU8.fill(0, address, address + size); - return address; - }; - var alignMemory = (size, alignment) => { - assert(alignment, 'alignment argument is required'); - return Math.ceil(size / alignment) * alignment; - }; - var mmapAlloc = (size) => { - size = alignMemory(size, 65536); - var ptr = _emscripten_builtin_memalign(65536, size); - if (!ptr) return 0; - return zeroMemory(ptr, size); - }; - var MEMFS = { - ops_table: null, - mount(mount) { - return MEMFS.createNode(null, '/', 16384 | 511, 0); - }, - createNode(parent, name, mode, dev) { - if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { - throw new FS.ErrnoError(63); - } - if (!MEMFS.ops_table) { - MEMFS.ops_table = { - dir: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - lookup: MEMFS.node_ops.lookup, - mknod: MEMFS.node_ops.mknod, - rename: MEMFS.node_ops.rename, - unlink: MEMFS.node_ops.unlink, - rmdir: MEMFS.node_ops.rmdir, - readdir: MEMFS.node_ops.readdir, - symlink: MEMFS.node_ops.symlink, - }, - stream: { llseek: MEMFS.stream_ops.llseek }, - }, - file: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - }, - stream: { - llseek: MEMFS.stream_ops.llseek, - read: MEMFS.stream_ops.read, - write: MEMFS.stream_ops.write, - allocate: MEMFS.stream_ops.allocate, - mmap: MEMFS.stream_ops.mmap, - msync: MEMFS.stream_ops.msync, - }, - }, - link: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - readlink: MEMFS.node_ops.readlink, - }, - stream: {}, - }, - chrdev: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - }, - stream: FS.chrdev_stream_ops, - }, - }; - } - var node = FS.createNode(parent, name, mode, dev); - if (FS.isDir(node.mode)) { - node.node_ops = MEMFS.ops_table.dir.node; - node.stream_ops = MEMFS.ops_table.dir.stream; - node.contents = {}; - } else if (FS.isFile(node.mode)) { - node.node_ops = MEMFS.ops_table.file.node; - node.stream_ops = MEMFS.ops_table.file.stream; - node.usedBytes = 0; - node.contents = null; - } else if (FS.isLink(node.mode)) { - node.node_ops = MEMFS.ops_table.link.node; - node.stream_ops = MEMFS.ops_table.link.stream; - } else if (FS.isChrdev(node.mode)) { - node.node_ops = MEMFS.ops_table.chrdev.node; - node.stream_ops = MEMFS.ops_table.chrdev.stream; - } - node.timestamp = Date.now(); - if (parent) { - parent.contents[name] = node; - parent.timestamp = node.timestamp; - } - return node; - }, - getFileDataAsTypedArray(node) { - if (!node.contents) return new Uint8Array(0); - if (node.contents.subarray) - return node.contents.subarray(0, node.usedBytes); - return new Uint8Array(node.contents); - }, - expandFileStorage(node, newCapacity) { - var prevCapacity = node.contents ? node.contents.length : 0; - if (prevCapacity >= newCapacity) return; - var CAPACITY_DOUBLING_MAX = 1024 * 1024; - newCapacity = Math.max( - newCapacity, - (prevCapacity * - (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125)) >>> - 0 - ); - if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); - var oldContents = node.contents; - node.contents = new Uint8Array(newCapacity); - if (node.usedBytes > 0) - node.contents.set( - oldContents.subarray(0, node.usedBytes), - 0 - ); - }, - resizeFileStorage(node, newSize) { - if (node.usedBytes == newSize) return; - if (newSize == 0) { - node.contents = null; - node.usedBytes = 0; - } else { - var oldContents = node.contents; - node.contents = new Uint8Array(newSize); - if (oldContents) { - node.contents.set( - oldContents.subarray( - 0, - Math.min(newSize, node.usedBytes) - ) - ); - } - node.usedBytes = newSize; - } - }, - node_ops: { - getattr(node) { - var attr = {}; - attr.dev = FS.isChrdev(node.mode) ? node.id : 1; - attr.ino = node.id; - attr.mode = node.mode; - attr.nlink = 1; - attr.uid = 0; - attr.gid = 0; - attr.rdev = node.rdev; - if (FS.isDir(node.mode)) { - attr.size = 4096; - } else if (FS.isFile(node.mode)) { - attr.size = node.usedBytes; - } else if (FS.isLink(node.mode)) { - attr.size = node.link.length; - } else { - attr.size = 0; - } - attr.atime = new Date(node.timestamp); - attr.mtime = new Date(node.timestamp); - attr.ctime = new Date(node.timestamp); - attr.blksize = 4096; - attr.blocks = Math.ceil(attr.size / attr.blksize); - return attr; - }, - setattr(node, attr) { - if (attr.mode !== undefined) { - node.mode = attr.mode; - } - if (attr.timestamp !== undefined) { - node.timestamp = attr.timestamp; - } - if (attr.size !== undefined) { - MEMFS.resizeFileStorage(node, attr.size); - } - }, - lookup(parent, name) { - throw FS.genericErrors[44]; - }, - mknod(parent, name, mode, dev) { - return MEMFS.createNode(parent, name, mode, dev); - }, - rename(old_node, new_dir, new_name) { - if (FS.isDir(old_node.mode)) { - var new_node; - try { - new_node = FS.lookupNode(new_dir, new_name); - } catch (e) {} - if (new_node) { - for (var i in new_node.contents) { - throw new FS.ErrnoError(55); - } - } - } - delete old_node.parent.contents[old_node.name]; - old_node.parent.timestamp = Date.now(); - old_node.name = new_name; - new_dir.contents[new_name] = old_node; - new_dir.timestamp = old_node.parent.timestamp; - old_node.parent = new_dir; - }, - unlink(parent, name) { - delete parent.contents[name]; - parent.timestamp = Date.now(); - }, - rmdir(parent, name) { - var node = FS.lookupNode(parent, name); - for (var i in node.contents) { - throw new FS.ErrnoError(55); - } - delete parent.contents[name]; - parent.timestamp = Date.now(); - }, - readdir(node) { - var entries = ['.', '..']; - for (var key in node.contents) { - if (!node.contents.hasOwnProperty(key)) { - continue; - } - entries.push(key); - } - return entries; - }, - symlink(parent, newname, oldpath) { - var node = MEMFS.createNode( - parent, - newname, - 511 | 40960, - 0 - ); - node.link = oldpath; - return node; - }, - readlink(node) { - if (!FS.isLink(node.mode)) { - throw new FS.ErrnoError(28); - } - return node.link; - }, - }, - stream_ops: { - read(stream, buffer, offset, length, position) { - var contents = stream.node.contents; - if (position >= stream.node.usedBytes) return 0; - var size = Math.min( - stream.node.usedBytes - position, - length - ); - assert(size >= 0); - if (size > 8 && contents.subarray) { - buffer.set( - contents.subarray(position, position + size), - offset - ); - } else { - for (var i = 0; i < size; i++) - buffer[offset + i] = contents[position + i]; - } - return size; - }, - write(stream, buffer, offset, length, position, canOwn) { - assert(!(buffer instanceof ArrayBuffer)); - if (buffer.buffer === HEAP8.buffer) { - canOwn = false; - } - if (!length) return 0; - var node = stream.node; - node.timestamp = Date.now(); - if ( - buffer.subarray && - (!node.contents || node.contents.subarray) - ) { - if (canOwn) { - assert( - position === 0, - 'canOwn must imply no weird position inside the file' - ); - node.contents = buffer.subarray( - offset, - offset + length - ); - node.usedBytes = length; - return length; - } else if (node.usedBytes === 0 && position === 0) { - node.contents = buffer.slice( - offset, - offset + length - ); - node.usedBytes = length; - return length; - } else if (position + length <= node.usedBytes) { - node.contents.set( - buffer.subarray(offset, offset + length), - position - ); - return length; - } - } - MEMFS.expandFileStorage(node, position + length); - if (node.contents.subarray && buffer.subarray) { - node.contents.set( - buffer.subarray(offset, offset + length), - position - ); - } else { - for (var i = 0; i < length; i++) { - node.contents[position + i] = buffer[offset + i]; - } - } - node.usedBytes = Math.max( - node.usedBytes, - position + length - ); - return length; - }, - llseek(stream, offset, whence) { - var position = offset; - if (whence === 1) { - position += stream.position; - } else if (whence === 2) { - if (FS.isFile(stream.node.mode)) { - position += stream.node.usedBytes; - } - } - if (position < 0) { - throw new FS.ErrnoError(28); - } - return position; - }, - allocate(stream, offset, length) { - MEMFS.expandFileStorage(stream.node, offset + length); - stream.node.usedBytes = Math.max( - stream.node.usedBytes, - offset + length - ); - }, - mmap(stream, length, position, prot, flags) { - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43); - } - var ptr; - var allocated; - var contents = stream.node.contents; - if (!(flags & 2) && contents.buffer === HEAP8.buffer) { - allocated = false; - ptr = contents.byteOffset; - } else { - if ( - position > 0 || - position + length < contents.length - ) { - if (contents.subarray) { - contents = contents.subarray( - position, - position + length - ); - } else { - contents = Array.prototype.slice.call( - contents, - position, - position + length - ); - } - } - allocated = true; - ptr = mmapAlloc(length); - if (!ptr) { - throw new FS.ErrnoError(48); - } - HEAP8.set(contents, ptr); - } - return { ptr: ptr, allocated: allocated }; - }, - msync(stream, buffer, offset, length, mmapFlags) { - MEMFS.stream_ops.write( - stream, - buffer, - 0, - length, - offset, - false - ); - return 0; - }, - }, - }; - var asyncLoad = (url, onload, onerror, noRunDep) => { - var dep = !noRunDep ? getUniqueRunDependency(`al ${url}`) : ''; - readAsync( - url, - (arrayBuffer) => { - assert( - arrayBuffer, - `Loading data file "${url}" failed (no arrayBuffer).` - ); - onload(new Uint8Array(arrayBuffer)); - if (dep) removeRunDependency(dep); - }, - (event) => { - if (onerror) { - onerror(); - } else { - throw `Loading data file "${url}" failed.`; - } - } - ); - if (dep) addRunDependency(dep); - }; - var preloadPlugins = Module['preloadPlugins'] || []; - function FS_handledByPreloadPlugin( - byteArray, - fullname, - finish, - onerror - ) { - if (typeof Browser != 'undefined') Browser.init(); - var handled = false; - preloadPlugins.forEach(function (plugin) { - if (handled) return; - if (plugin['canHandle'](fullname)) { - plugin['handle'](byteArray, fullname, finish, onerror); - handled = true; - } - }); - return handled; - } - function FS_createPreloadedFile( - parent, - name, - url, - canRead, - canWrite, - onload, - onerror, - dontCreateFile, - canOwn, - preFinish - ) { - var fullname = name - ? PATH_FS.resolve(PATH.join2(parent, name)) - : parent; - var dep = getUniqueRunDependency(`cp ${fullname}`); - function processData(byteArray) { - function finish(byteArray) { - if (preFinish) preFinish(); - if (!dontCreateFile) { - FS.createDataFile( - parent, - name, - byteArray, - canRead, - canWrite, - canOwn - ); - } - if (onload) onload(); - removeRunDependency(dep); - } - if ( - FS_handledByPreloadPlugin( - byteArray, - fullname, - finish, - () => { - if (onerror) onerror(); - removeRunDependency(dep); - } - ) - ) { - return; - } - finish(byteArray); - } - addRunDependency(dep); - if (typeof url == 'string') { - asyncLoad(url, (byteArray) => processData(byteArray), onerror); - } else { - processData(url); - } - } - function FS_modeStringToFlags(str) { - var flagModes = { - r: 0, - 'r+': 2, - w: 512 | 64 | 1, - 'w+': 512 | 64 | 2, - a: 1024 | 64 | 1, - 'a+': 1024 | 64 | 2, - }; - var flags = flagModes[str]; - if (typeof flags == 'undefined') { - throw new Error(`Unknown file open mode: ${str}`); - } - return flags; - } - function FS_getMode(canRead, canWrite) { - var mode = 0; - if (canRead) mode |= 292 | 73; - if (canWrite) mode |= 146; - return mode; - } - var ERRNO_CODES = {}; - var NODEFS = { - isWindows: false, - staticInit: () => { - NODEFS.isWindows = !!process.platform.match(/^win/); - var flags = process.binding('constants'); - if (flags['fs']) { - flags = flags['fs']; - } - NODEFS.flagsForNodeMap = { - 1024: flags['O_APPEND'], - 64: flags['O_CREAT'], - 128: flags['O_EXCL'], - 256: flags['O_NOCTTY'], - 0: flags['O_RDONLY'], - 2: flags['O_RDWR'], - 4096: flags['O_SYNC'], - 512: flags['O_TRUNC'], - 1: flags['O_WRONLY'], - 131072: flags['O_NOFOLLOW'], - }; - assert(NODEFS.flagsForNodeMap['0'] === 0); - }, - convertNodeCode: (e) => { - var code = e.code; - assert( - code in ERRNO_CODES, - `unexpected node error code: ${code} (${e})` - ); - return ERRNO_CODES[code]; - }, - mount: (mount) => { - assert(ENVIRONMENT_IS_NODE); - return NODEFS.createNode( - null, - '/', - NODEFS.getMode(mount.opts.root), - 0 - ); - }, - createNode: (parent, name, mode, dev) => { - if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) { - throw new FS.ErrnoError(28); - } - var node = FS.createNode(parent, name, mode); - node.node_ops = NODEFS.node_ops; - node.stream_ops = NODEFS.stream_ops; - return node; - }, - getMode: (path) => { - var stat; - try { - stat = fs.lstatSync(path); - if (NODEFS.isWindows) { - stat.mode = stat.mode | ((stat.mode & 292) >> 2); - } - } catch (e) { - if (!e.code) throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - return stat.mode; - }, - realPath: (node) => { - var parts = []; - while (node.parent !== node) { - parts.push(node.name); - node = node.parent; - } - parts.push(node.mount.opts.root); - parts.reverse(); - return PATH.join.apply(null, parts); - }, - flagsForNode: (flags) => { - flags &= ~2097152; - flags &= ~2048; - flags &= ~32768; - flags &= ~524288; - flags &= ~65536; - var newFlags = 0; - for (var k in NODEFS.flagsForNodeMap) { - if (flags & k) { - newFlags |= NODEFS.flagsForNodeMap[k]; - flags ^= k; - } - } - if (flags) { - throw new FS.ErrnoError(28); - } - return newFlags; - }, - node_ops: { - getattr: (node) => { - var path = NODEFS.realPath(node); - var stat; - try { - stat = fs.lstatSync(path); - } catch (e) { - if (!e.code) throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - if (NODEFS.isWindows && !stat.blksize) { - stat.blksize = 4096; - } - if (NODEFS.isWindows && !stat.blocks) { - stat.blocks = - ((stat.size + stat.blksize - 1) / stat.blksize) | 0; - } - return { - dev: stat.dev, - ino: stat.ino, - mode: stat.mode, - nlink: stat.nlink, - uid: stat.uid, - gid: stat.gid, - rdev: stat.rdev, - size: stat.size, - atime: stat.atime, - mtime: stat.mtime, - ctime: stat.ctime, - blksize: stat.blksize, - blocks: stat.blocks, - }; - }, - setattr: (node, attr) => { - var path = NODEFS.realPath(node); - try { - if (attr.mode !== undefined) { - fs.chmodSync(path, attr.mode); - node.mode = attr.mode; - } - if (attr.timestamp !== undefined) { - var date = new Date(attr.timestamp); - fs.utimesSync(path, date, date); - } - if (attr.size !== undefined) { - fs.truncateSync(path, attr.size); - } - } catch (e) { - if (!e.code) throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - lookup: (parent, name) => { - var path = PATH.join2(NODEFS.realPath(parent), name); - var mode = NODEFS.getMode(path); - return NODEFS.createNode(parent, name, mode); - }, - mknod: (parent, name, mode, dev) => { - var node = NODEFS.createNode(parent, name, mode, dev); - var path = NODEFS.realPath(node); - try { - if (FS.isDir(node.mode)) { - fs.mkdirSync(path, node.mode); - } else { - fs.writeFileSync(path, '', { mode: node.mode }); - } - } catch (e) { - if (!e.code) throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - return node; - }, - rename: (oldNode, newDir, newName) => { - var oldPath = NODEFS.realPath(oldNode); - var newPath = PATH.join2(NODEFS.realPath(newDir), newName); - try { - fs.renameSync(oldPath, newPath); - } catch (e) { - if (!e.code) throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - oldNode.name = newName; - }, - unlink: (parent, name) => { - var path = PATH.join2(NODEFS.realPath(parent), name); - try { - fs.unlinkSync(path); - } catch (e) { - if (!e.code) throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - rmdir: (parent, name) => { - var path = PATH.join2(NODEFS.realPath(parent), name); - try { - fs.rmdirSync(path); - } catch (e) { - if (!e.code) throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - readdir: (node) => { - var path = NODEFS.realPath(node); - try { - return fs.readdirSync(path); - } catch (e) { - if (!e.code) throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - symlink: (parent, newName, oldPath) => { - var newPath = PATH.join2(NODEFS.realPath(parent), newName); - try { - fs.symlinkSync(oldPath, newPath); - } catch (e) { - if (!e.code) throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - readlink: (node) => { - var path = NODEFS.realPath(node); - try { - path = fs.readlinkSync(path); - path = nodePath.relative( - nodePath.resolve(node.mount.opts.root), - path - ); - return path; - } catch (e) { - if (!e.code) throw e; - if (e.code === 'UNKNOWN') throw new FS.ErrnoError(28); - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - }, - stream_ops: { - open: (stream) => { - var path = NODEFS.realPath(stream.node); - try { - if (FS.isFile(stream.node.mode)) { - stream.nfd = fs.openSync( - path, - NODEFS.flagsForNode(stream.flags) - ); - } - } catch (e) { - if (!e.code) throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - close: (stream) => { - try { - if (FS.isFile(stream.node.mode) && stream.nfd) { - fs.closeSync(stream.nfd); - } - } catch (e) { - if (!e.code) throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - read: (stream, buffer, offset, length, position) => { - if (length === 0) return 0; - try { - return fs.readSync( - stream.nfd, - Buffer.from(buffer.buffer), - offset, - length, - position - ); - } catch (e) { - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - write: (stream, buffer, offset, length, position) => { - try { - return fs.writeSync( - stream.nfd, - Buffer.from(buffer.buffer), - offset, - length, - position - ); - } catch (e) { - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - llseek: (stream, offset, whence) => { - var position = offset; - if (whence === 1) { - position += stream.position; - } else if (whence === 2) { - if (FS.isFile(stream.node.mode)) { - try { - var stat = fs.fstatSync(stream.nfd); - position += stat.size; - } catch (e) { - throw new FS.ErrnoError( - NODEFS.convertNodeCode(e) - ); - } - } - } - if (position < 0) { - throw new FS.ErrnoError(28); - } - return position; - }, - mmap: (stream, length, position, prot, flags) => { - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43); - } - var ptr = mmapAlloc(length); - NODEFS.stream_ops.read( - stream, - HEAP8, - ptr, - length, - position - ); - return { ptr: ptr, allocated: true }; - }, - msync: (stream, buffer, offset, length, mmapFlags) => { - NODEFS.stream_ops.write( - stream, - buffer, - 0, - length, - offset, - false - ); - return 0; - }, - }, - }; - var ERRNO_MESSAGES = { - 0: 'Success', - 1: 'Arg list too long', - 2: 'Permission denied', - 3: 'Address already in use', - 4: 'Address not available', - 5: 'Address family not supported by protocol family', - 6: 'No more processes', - 7: 'Socket already connected', - 8: 'Bad file number', - 9: 'Trying to read unreadable message', - 10: 'Mount device busy', - 11: 'Operation canceled', - 12: 'No children', - 13: 'Connection aborted', - 14: 'Connection refused', - 15: 'Connection reset by peer', - 16: 'File locking deadlock error', - 17: 'Destination address required', - 18: 'Math arg out of domain of func', - 19: 'Quota exceeded', - 20: 'File exists', - 21: 'Bad address', - 22: 'File too large', - 23: 'Host is unreachable', - 24: 'Identifier removed', - 25: 'Illegal byte sequence', - 26: 'Connection already in progress', - 27: 'Interrupted system call', - 28: 'Invalid argument', - 29: 'I/O error', - 30: 'Socket is already connected', - 31: 'Is a directory', - 32: 'Too many symbolic links', - 33: 'Too many open files', - 34: 'Too many links', - 35: 'Message too long', - 36: 'Multihop attempted', - 37: 'File or path name too long', - 38: 'Network interface is not configured', - 39: 'Connection reset by network', - 40: 'Network is unreachable', - 41: 'Too many open files in system', - 42: 'No buffer space available', - 43: 'No such device', - 44: 'No such file or directory', - 45: 'Exec format error', - 46: 'No record locks available', - 47: 'The link has been severed', - 48: 'Not enough core', - 49: 'No message of desired type', - 50: 'Protocol not available', - 51: 'No space left on device', - 52: 'Function not implemented', - 53: 'Socket is not connected', - 54: 'Not a directory', - 55: 'Directory not empty', - 56: 'State not recoverable', - 57: 'Socket operation on non-socket', - 59: 'Not a typewriter', - 60: 'No such device or address', - 61: 'Value too large for defined data type', - 62: 'Previous owner died', - 63: 'Not super-user', - 64: 'Broken pipe', - 65: 'Protocol error', - 66: 'Unknown protocol', - 67: 'Protocol wrong type for socket', - 68: 'Math result not representable', - 69: 'Read only file system', - 70: 'Illegal seek', - 71: 'No such process', - 72: 'Stale file handle', - 73: 'Connection timed out', - 74: 'Text file busy', - 75: 'Cross-device link', - 100: 'Device not a stream', - 101: 'Bad font file fmt', - 102: 'Invalid slot', - 103: 'Invalid request code', - 104: 'No anode', - 105: 'Block device required', - 106: 'Channel number out of range', - 107: 'Level 3 halted', - 108: 'Level 3 reset', - 109: 'Link number out of range', - 110: 'Protocol driver not attached', - 111: 'No CSI structure available', - 112: 'Level 2 halted', - 113: 'Invalid exchange', - 114: 'Invalid request descriptor', - 115: 'Exchange full', - 116: 'No data (for no delay io)', - 117: 'Timer expired', - 118: 'Out of streams resources', - 119: 'Machine is not on the network', - 120: 'Package not installed', - 121: 'The object is remote', - 122: 'Advertise error', - 123: 'Srmount error', - 124: 'Communication error on send', - 125: 'Cross mount point (not really error)', - 126: 'Given log. name not unique', - 127: 'f.d. invalid for this operation', - 128: 'Remote address changed', - 129: 'Can access a needed shared lib', - 130: 'Accessing a corrupted shared lib', - 131: '.lib section in a.out corrupted', - 132: 'Attempting to link in too many libs', - 133: 'Attempting to exec a shared library', - 135: 'Streams pipe error', - 136: 'Too many users', - 137: 'Socket type not supported', - 138: 'Not supported', - 139: 'Protocol family not supported', - 140: "Can't send after socket shutdown", - 141: 'Too many references', - 142: 'Host is down', - 148: 'No medium (in tape drive)', - 156: 'Level 2 not synchronized', - }; - function demangle(func) { - warnOnce( - 'warning: build with -sDEMANGLE_SUPPORT to link in libcxxabi demangling' - ); - return func; - } - function demangleAll(text) { - var regex = /\b_Z[\w\d_]+/g; - return text.replace(regex, function (x) { - var y = demangle(x); - return x === y ? x : y + ' [' + x + ']'; - }); - } - var FS = { - root: null, - mounts: [], - devices: {}, - streams: [], - nextInode: 1, - nameTable: null, - currentPath: '/', - initialized: false, - ignorePermissions: true, - ErrnoError: null, - genericErrors: {}, - filesystems: null, - syncFSRequests: 0, - lookupPath: (path, opts = {}) => { - path = PATH_FS.resolve(path); - if (!path) return { path: '', node: null }; - var defaults = { follow_mount: true, recurse_count: 0 }; - opts = Object.assign(defaults, opts); - if (opts.recurse_count > 8) { - throw new FS.ErrnoError(32); - } - var parts = path.split('/').filter((p) => !!p); - var current = FS.root; - var current_path = '/'; - for (var i = 0; i < parts.length; i++) { - var islast = i === parts.length - 1; - if (islast && opts.parent) { - break; - } - current = FS.lookupNode(current, parts[i]); - current_path = PATH.join2(current_path, parts[i]); - if (FS.isMountpoint(current)) { - if (!islast || (islast && opts.follow_mount)) { - current = current.mounted.root; - } - } - if (!islast || opts.follow) { - var count = 0; - while (FS.isLink(current.mode)) { - var link = FS.readlink(current_path); - current_path = PATH_FS.resolve( - PATH.dirname(current_path), - link - ); - var lookup = FS.lookupPath(current_path, { - recurse_count: opts.recurse_count + 1, - }); - current = lookup.node; - if (count++ > 40) { - throw new FS.ErrnoError(32); - } - } - } - } - return { path: current_path, node: current }; - }, - getPath: (node) => { - var path; - while (true) { - if (FS.isRoot(node)) { - var mount = node.mount.mountpoint; - if (!path) return mount; - return mount[mount.length - 1] !== '/' - ? `${mount}/${path}` - : mount + path; - } - path = path ? `${node.name}/${path}` : node.name; - node = node.parent; - } - }, - hashName: (parentid, name) => { - var hash = 0; - for (var i = 0; i < name.length; i++) { - hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0; - } - return ((parentid + hash) >>> 0) % FS.nameTable.length; - }, - hashAddNode: (node) => { - var hash = FS.hashName(node.parent.id, node.name); - node.name_next = FS.nameTable[hash]; - FS.nameTable[hash] = node; - }, - hashRemoveNode: (node) => { - var hash = FS.hashName(node.parent.id, node.name); - if (FS.nameTable[hash] === node) { - FS.nameTable[hash] = node.name_next; - } else { - var current = FS.nameTable[hash]; - while (current) { - if (current.name_next === node) { - current.name_next = node.name_next; - break; - } - current = current.name_next; - } - } - }, - lookupNode: (parent, name) => { - var errCode = FS.mayLookup(parent); - if (errCode) { - throw new FS.ErrnoError(errCode, parent); - } - var hash = FS.hashName(parent.id, name); - for ( - var node = FS.nameTable[hash]; - node; - node = node.name_next - ) { - var nodeName = node.name; - if (node.parent.id === parent.id && nodeName === name) { - return node; - } - } - return FS.lookup(parent, name); - }, - createNode: (parent, name, mode, rdev) => { - assert(typeof parent == 'object'); - var node = new FS.FSNode(parent, name, mode, rdev); - FS.hashAddNode(node); - return node; - }, - destroyNode: (node) => { - FS.hashRemoveNode(node); - }, - isRoot: (node) => node === node.parent, - isMountpoint: (node) => !!node.mounted, - isFile: (mode) => (mode & 61440) === 32768, - isDir: (mode) => (mode & 61440) === 16384, - isLink: (mode) => (mode & 61440) === 40960, - isChrdev: (mode) => (mode & 61440) === 8192, - isBlkdev: (mode) => (mode & 61440) === 24576, - isFIFO: (mode) => (mode & 61440) === 4096, - isSocket: (mode) => (mode & 49152) === 49152, - flagsToPermissionString: (flag) => { - var perms = ['r', 'w', 'rw'][flag & 3]; - if (flag & 512) { - perms += 'w'; - } - return perms; - }, - nodePermissions: (node, perms) => { - if (FS.ignorePermissions) { - return 0; - } - if (perms.includes('r') && !(node.mode & 292)) { - return 2; - } else if (perms.includes('w') && !(node.mode & 146)) { - return 2; - } else if (perms.includes('x') && !(node.mode & 73)) { - return 2; - } - return 0; - }, - mayLookup: (dir) => { - var errCode = FS.nodePermissions(dir, 'x'); - if (errCode) return errCode; - if (!dir.node_ops.lookup) return 2; - return 0; - }, - mayCreate: (dir, name) => { - try { - var node = FS.lookupNode(dir, name); - return 20; - } catch (e) {} - return FS.nodePermissions(dir, 'wx'); - }, - mayDelete: (dir, name, isdir) => { - var node; - try { - node = FS.lookupNode(dir, name); - } catch (e) { - return e.errno; - } - var errCode = FS.nodePermissions(dir, 'wx'); - if (errCode) { - return errCode; - } - if (isdir) { - if (!FS.isDir(node.mode)) { - return 54; - } - if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) { - return 10; - } - } else { - if (FS.isDir(node.mode)) { - return 31; - } - } - return 0; - }, - mayOpen: (node, flags) => { - if (!node) { - return 44; - } - if (FS.isLink(node.mode)) { - return 32; - } else if (FS.isDir(node.mode)) { - if ( - FS.flagsToPermissionString(flags) !== 'r' || - flags & 512 - ) { - return 31; - } - } - return FS.nodePermissions( - node, - FS.flagsToPermissionString(flags) - ); - }, - MAX_OPEN_FDS: 4096, - nextfd: () => { - for (var fd = 0; fd <= FS.MAX_OPEN_FDS; fd++) { - if (!FS.streams[fd]) { - return fd; - } - } - throw new FS.ErrnoError(33); - }, - getStreamChecked: (fd) => { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8); - } - return stream; - }, - getStream: (fd) => FS.streams[fd], - createStream: (stream, fd = -1) => { - if (!FS.FSStream) { - FS.FSStream = function () { - this.shared = {}; - }; - FS.FSStream.prototype = {}; - Object.defineProperties(FS.FSStream.prototype, { - object: { - get() { - return this.node; - }, - set(val) { - this.node = val; - }, - }, - isRead: { - get() { - return (this.flags & 2097155) !== 1; - }, - }, - isWrite: { - get() { - return (this.flags & 2097155) !== 0; - }, - }, - isAppend: { - get() { - return this.flags & 1024; - }, - }, - flags: { - get() { - return this.shared.flags; - }, - set(val) { - this.shared.flags = val; - }, - }, - position: { - get() { - return this.shared.position; - }, - set(val) { - this.shared.position = val; - }, - }, - }); - } - stream = Object.assign(new FS.FSStream(), stream); - if (fd == -1) { - fd = FS.nextfd(); - } - stream.fd = fd; - FS.streams[fd] = stream; - return stream; - }, - closeStream: (fd) => { - FS.streams[fd] = null; - }, - chrdev_stream_ops: { - open: (stream) => { - var device = FS.getDevice(stream.node.rdev); - stream.stream_ops = device.stream_ops; - if (stream.stream_ops.open) { - stream.stream_ops.open(stream); - } - }, - llseek: () => { - throw new FS.ErrnoError(70); - }, - }, - major: (dev) => dev >> 8, - minor: (dev) => dev & 255, - makedev: (ma, mi) => (ma << 8) | mi, - registerDevice: (dev, ops) => { - FS.devices[dev] = { stream_ops: ops }; - }, - getDevice: (dev) => FS.devices[dev], - getMounts: (mount) => { - var mounts = []; - var check = [mount]; - while (check.length) { - var m = check.pop(); - mounts.push(m); - check.push.apply(check, m.mounts); - } - return mounts; - }, - syncfs: (populate, callback) => { - if (typeof populate == 'function') { - callback = populate; - populate = false; - } - FS.syncFSRequests++; - if (FS.syncFSRequests > 1) { - err( - `warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work` - ); - } - var mounts = FS.getMounts(FS.root.mount); - var completed = 0; - function doCallback(errCode) { - assert(FS.syncFSRequests > 0); - FS.syncFSRequests--; - return callback(errCode); - } - function done(errCode) { - if (errCode) { - if (!done.errored) { - done.errored = true; - return doCallback(errCode); - } - return; - } - if (++completed >= mounts.length) { - doCallback(null); - } - } - mounts.forEach((mount) => { - if (!mount.type.syncfs) { - return done(null); - } - mount.type.syncfs(mount, populate, done); - }); - }, - mount: (type, opts, mountpoint) => { - if (typeof type == 'string') { - throw type; - } - var root = mountpoint === '/'; - var pseudo = !mountpoint; - var node; - if (root && FS.root) { - throw new FS.ErrnoError(10); - } else if (!root && !pseudo) { - var lookup = FS.lookupPath(mountpoint, { - follow_mount: false, - }); - mountpoint = lookup.path; - node = lookup.node; - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10); - } - if (!FS.isDir(node.mode)) { - throw new FS.ErrnoError(54); - } - } - var mount = { - type: type, - opts: opts, - mountpoint: mountpoint, - mounts: [], - }; - var mountRoot = type.mount(mount); - mountRoot.mount = mount; - mount.root = mountRoot; - if (root) { - FS.root = mountRoot; - } else if (node) { - node.mounted = mount; - if (node.mount) { - node.mount.mounts.push(mount); - } - } - return mountRoot; - }, - unmount: (mountpoint) => { - var lookup = FS.lookupPath(mountpoint, { follow_mount: false }); - if (!FS.isMountpoint(lookup.node)) { - throw new FS.ErrnoError(28); - } - var node = lookup.node; - var mount = node.mounted; - var mounts = FS.getMounts(mount); - Object.keys(FS.nameTable).forEach((hash) => { - var current = FS.nameTable[hash]; - while (current) { - var next = current.name_next; - if (mounts.includes(current.mount)) { - FS.destroyNode(current); - } - current = next; - } - }); - node.mounted = null; - var idx = node.mount.mounts.indexOf(mount); - assert(idx !== -1); - node.mount.mounts.splice(idx, 1); - }, - lookup: (parent, name) => parent.node_ops.lookup(parent, name), - mknod: (path, mode, dev) => { - var lookup = FS.lookupPath(path, { parent: true }); - var parent = lookup.node; - var name = PATH.basename(path); - if (!name || name === '.' || name === '..') { - throw new FS.ErrnoError(28); - } - var errCode = FS.mayCreate(parent, name); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - if (!parent.node_ops.mknod) { - throw new FS.ErrnoError(63); - } - return parent.node_ops.mknod(parent, name, mode, dev); - }, - create: (path, mode) => { - mode = mode !== undefined ? mode : 438; - mode &= 4095; - mode |= 32768; - return FS.mknod(path, mode, 0); - }, - mkdir: (path, mode) => { - mode = mode !== undefined ? mode : 511; - mode &= 511 | 512; - mode |= 16384; - return FS.mknod(path, mode, 0); - }, - mkdirTree: (path, mode) => { - var dirs = path.split('/'); - var d = ''; - for (var i = 0; i < dirs.length; ++i) { - if (!dirs[i]) continue; - d += '/' + dirs[i]; - try { - FS.mkdir(d, mode); - } catch (e) { - if (e.errno != 20) throw e; - } - } - }, - mkdev: (path, mode, dev) => { - if (typeof dev == 'undefined') { - dev = mode; - mode = 438; - } - mode |= 8192; - return FS.mknod(path, mode, dev); - }, - symlink: (oldpath, newpath) => { - if (!PATH_FS.resolve(oldpath)) { - throw new FS.ErrnoError(44); - } - var lookup = FS.lookupPath(newpath, { parent: true }); - var parent = lookup.node; - if (!parent) { - throw new FS.ErrnoError(44); - } - var newname = PATH.basename(newpath); - var errCode = FS.mayCreate(parent, newname); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - if (!parent.node_ops.symlink) { - throw new FS.ErrnoError(63); - } - return parent.node_ops.symlink(parent, newname, oldpath); - }, - rename: (old_path, new_path) => { - var old_dirname = PATH.dirname(old_path); - var new_dirname = PATH.dirname(new_path); - var old_name = PATH.basename(old_path); - var new_name = PATH.basename(new_path); - var lookup, old_dir, new_dir; - lookup = FS.lookupPath(old_path, { parent: true }); - old_dir = lookup.node; - lookup = FS.lookupPath(new_path, { parent: true }); - new_dir = lookup.node; - if (!old_dir || !new_dir) throw new FS.ErrnoError(44); - if (old_dir.mount !== new_dir.mount) { - throw new FS.ErrnoError(75); - } - var old_node = FS.lookupNode(old_dir, old_name); - var relative = PATH_FS.relative(old_path, new_dirname); - if (relative.charAt(0) !== '.') { - throw new FS.ErrnoError(28); - } - relative = PATH_FS.relative(new_path, old_dirname); - if (relative.charAt(0) !== '.') { - throw new FS.ErrnoError(55); - } - var new_node; - try { - new_node = FS.lookupNode(new_dir, new_name); - } catch (e) {} - if (old_node === new_node) { - return; - } - var isdir = FS.isDir(old_node.mode); - var errCode = FS.mayDelete(old_dir, old_name, isdir); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - errCode = new_node - ? FS.mayDelete(new_dir, new_name, isdir) - : FS.mayCreate(new_dir, new_name); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - if (!old_dir.node_ops.rename) { - throw new FS.ErrnoError(63); - } - if ( - FS.isMountpoint(old_node) || - (new_node && FS.isMountpoint(new_node)) - ) { - throw new FS.ErrnoError(10); - } - if (new_dir !== old_dir) { - errCode = FS.nodePermissions(old_dir, 'w'); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - } - FS.hashRemoveNode(old_node); - try { - old_dir.node_ops.rename(old_node, new_dir, new_name); - } catch (e) { - throw e; - } finally { - FS.hashAddNode(old_node); - } - }, - rmdir: (path) => { - var lookup = FS.lookupPath(path, { parent: true }); - var parent = lookup.node; - var name = PATH.basename(path); - var node = FS.lookupNode(parent, name); - var errCode = FS.mayDelete(parent, name, true); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - if (!parent.node_ops.rmdir) { - throw new FS.ErrnoError(63); - } - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10); - } - parent.node_ops.rmdir(parent, name); - FS.destroyNode(node); - }, - readdir: (path) => { - var lookup = FS.lookupPath(path, { follow: true }); - var node = lookup.node; - if (!node.node_ops.readdir) { - throw new FS.ErrnoError(54); - } - return node.node_ops.readdir(node); - }, - unlink: (path) => { - var lookup = FS.lookupPath(path, { parent: true }); - var parent = lookup.node; - if (!parent) { - throw new FS.ErrnoError(44); - } - var name = PATH.basename(path); - var node = FS.lookupNode(parent, name); - var errCode = FS.mayDelete(parent, name, false); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - if (!parent.node_ops.unlink) { - throw new FS.ErrnoError(63); - } - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10); - } - parent.node_ops.unlink(parent, name); - FS.destroyNode(node); - }, - readlink: (path) => { - var lookup = FS.lookupPath(path); - var link = lookup.node; - if (!link) { - throw new FS.ErrnoError(44); - } - if (!link.node_ops.readlink) { - throw new FS.ErrnoError(28); - } - return PATH_FS.resolve( - FS.getPath(link.parent), - link.node_ops.readlink(link) - ); - }, - stat: (path, dontFollow) => { - var lookup = FS.lookupPath(path, { follow: !dontFollow }); - var node = lookup.node; - if (!node) { - throw new FS.ErrnoError(44); - } - if (!node.node_ops.getattr) { - throw new FS.ErrnoError(63); - } - return node.node_ops.getattr(node); - }, - lstat: (path) => FS.stat(path, true), - chmod: (path, mode, dontFollow) => { - var node; - if (typeof path == 'string') { - var lookup = FS.lookupPath(path, { follow: !dontFollow }); - node = lookup.node; - } else { - node = path; - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63); - } - node.node_ops.setattr(node, { - mode: (mode & 4095) | (node.mode & ~4095), - timestamp: Date.now(), - }); - }, - lchmod: (path, mode) => { - FS.chmod(path, mode, true); - }, - fchmod: (fd, mode) => { - var stream = FS.getStreamChecked(fd); - FS.chmod(stream.node, mode); - }, - chown: (path, uid, gid, dontFollow) => { - var node; - if (typeof path == 'string') { - var lookup = FS.lookupPath(path, { follow: !dontFollow }); - node = lookup.node; - } else { - node = path; - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63); - } - node.node_ops.setattr(node, { timestamp: Date.now() }); - }, - lchown: (path, uid, gid) => { - FS.chown(path, uid, gid, true); - }, - fchown: (fd, uid, gid) => { - var stream = FS.getStreamChecked(fd); - FS.chown(stream.node, uid, gid); - }, - truncate: (path, len) => { - if (len < 0) { - throw new FS.ErrnoError(28); - } - var node; - if (typeof path == 'string') { - var lookup = FS.lookupPath(path, { follow: true }); - node = lookup.node; - } else { - node = path; - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63); - } - if (FS.isDir(node.mode)) { - throw new FS.ErrnoError(31); - } - if (!FS.isFile(node.mode)) { - throw new FS.ErrnoError(28); - } - var errCode = FS.nodePermissions(node, 'w'); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - node.node_ops.setattr(node, { - size: len, - timestamp: Date.now(), - }); - }, - ftruncate: (fd, len) => { - var stream = FS.getStreamChecked(fd); - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(28); - } - FS.truncate(stream.node, len); - }, - utime: (path, atime, mtime) => { - var lookup = FS.lookupPath(path, { follow: true }); - var node = lookup.node; - node.node_ops.setattr(node, { - timestamp: Math.max(atime, mtime), - }); - }, - open: (path, flags, mode) => { - if (path === '') { - throw new FS.ErrnoError(44); - } - flags = - typeof flags == 'string' - ? FS_modeStringToFlags(flags) - : flags; - mode = typeof mode == 'undefined' ? 438 : mode; - if (flags & 64) { - mode = (mode & 4095) | 32768; - } else { - mode = 0; - } - var node; - if (typeof path == 'object') { - node = path; - } else { - path = PATH.normalize(path); - try { - var lookup = FS.lookupPath(path, { - follow: !(flags & 131072), - }); - node = lookup.node; - } catch (e) {} - } - var created = false; - if (flags & 64) { - if (node) { - if (flags & 128) { - throw new FS.ErrnoError(20); - } - } else { - node = FS.mknod(path, mode, 0); - created = true; - } - } - if (!node) { - throw new FS.ErrnoError(44); - } - if (FS.isChrdev(node.mode)) { - flags &= ~512; - } - if (flags & 65536 && !FS.isDir(node.mode)) { - throw new FS.ErrnoError(54); - } - if (!created) { - var errCode = FS.mayOpen(node, flags); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - } - if (flags & 512 && !created) { - FS.truncate(node, 0); - } - flags &= ~(128 | 512 | 131072); - var stream = FS.createStream({ - node: node, - path: FS.getPath(node), - flags: flags, - seekable: true, - position: 0, - stream_ops: node.stream_ops, - ungotten: [], - error: false, - }); - if (stream.stream_ops.open) { - stream.stream_ops.open(stream); - } - if (Module['logReadFiles'] && !(flags & 1)) { - if (!FS.readFiles) FS.readFiles = {}; - if (!(path in FS.readFiles)) { - FS.readFiles[path] = 1; - } - } - return stream; - }, - close: (stream) => { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if (stream.getdents) stream.getdents = null; - try { - if (stream.stream_ops.close) { - stream.stream_ops.close(stream); - } - } catch (e) { - throw e; - } finally { - FS.closeStream(stream.fd); - } - stream.fd = null; - }, - isClosed: (stream) => stream.fd === null, - llseek: (stream, offset, whence) => { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if (!stream.seekable || !stream.stream_ops.llseek) { - throw new FS.ErrnoError(70); - } - if (whence != 0 && whence != 1 && whence != 2) { - throw new FS.ErrnoError(28); - } - stream.position = stream.stream_ops.llseek( - stream, - offset, - whence - ); - stream.ungotten = []; - return stream.position; - }, - read: (stream, buffer, offset, length, position) => { - assert(offset >= 0); - if (length < 0 || position < 0) { - throw new FS.ErrnoError(28); - } - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if ((stream.flags & 2097155) === 1) { - throw new FS.ErrnoError(8); - } - if (FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(31); - } - if (!stream.stream_ops.read) { - throw new FS.ErrnoError(28); - } - var seeking = typeof position != 'undefined'; - if (!seeking) { - position = stream.position; - } else if (!stream.seekable) { - throw new FS.ErrnoError(70); - } - var bytesRead = stream.stream_ops.read( - stream, - buffer, - offset, - length, - position - ); - if (!seeking) stream.position += bytesRead; - return bytesRead; - }, - write: (stream, buffer, offset, length, position, canOwn) => { - assert(offset >= 0); - if (length < 0 || position < 0) { - throw new FS.ErrnoError(28); - } - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(8); - } - if (FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(31); - } - if (!stream.stream_ops.write) { - throw new FS.ErrnoError(28); - } - if (stream.seekable && stream.flags & 1024) { - FS.llseek(stream, 0, 2); - } - var seeking = typeof position != 'undefined'; - if (!seeking) { - position = stream.position; - } else if (!stream.seekable) { - throw new FS.ErrnoError(70); - } - var bytesWritten = stream.stream_ops.write( - stream, - buffer, - offset, - length, - position, - canOwn - ); - if (!seeking) stream.position += bytesWritten; - return bytesWritten; - }, - allocate: (stream, offset, length) => { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if (offset < 0 || length <= 0) { - throw new FS.ErrnoError(28); - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(8); - } - if ( - !FS.isFile(stream.node.mode) && - !FS.isDir(stream.node.mode) - ) { - throw new FS.ErrnoError(43); - } - if (!stream.stream_ops.allocate) { - throw new FS.ErrnoError(138); - } - stream.stream_ops.allocate(stream, offset, length); - }, - mmap: (stream, length, position, prot, flags) => { - if ( - (prot & 2) !== 0 && - (flags & 2) === 0 && - (stream.flags & 2097155) !== 2 - ) { - throw new FS.ErrnoError(2); - } - if ((stream.flags & 2097155) === 1) { - throw new FS.ErrnoError(2); - } - if (!stream.stream_ops.mmap) { - throw new FS.ErrnoError(43); - } - return stream.stream_ops.mmap( - stream, - length, - position, - prot, - flags - ); - }, - msync: (stream, buffer, offset, length, mmapFlags) => { - assert(offset >= 0); - if (!stream.stream_ops.msync) { - return 0; - } - return stream.stream_ops.msync( - stream, - buffer, - offset, - length, - mmapFlags - ); - }, - munmap: (stream) => 0, - ioctl: (stream, cmd, arg) => { - if (!stream.stream_ops.ioctl) { - throw new FS.ErrnoError(59); - } - return stream.stream_ops.ioctl(stream, cmd, arg); - }, - readFile: (path, opts = {}) => { - opts.flags = opts.flags || 0; - opts.encoding = opts.encoding || 'binary'; - if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') { - throw new Error(`Invalid encoding type "${opts.encoding}"`); - } - var ret; - var stream = FS.open(path, opts.flags); - var stat = FS.stat(path); - var length = stat.size; - var buf = new Uint8Array(length); - FS.read(stream, buf, 0, length, 0); - if (opts.encoding === 'utf8') { - ret = UTF8ArrayToString(buf, 0); - } else if (opts.encoding === 'binary') { - ret = buf; - } - FS.close(stream); - return ret; - }, - writeFile: (path, data, opts = {}) => { - opts.flags = opts.flags || 577; - var stream = FS.open(path, opts.flags, opts.mode); - if (typeof data == 'string') { - var buf = new Uint8Array(lengthBytesUTF8(data) + 1); - var actualNumBytes = stringToUTF8Array( - data, - buf, - 0, - buf.length - ); - FS.write( - stream, - buf, - 0, - actualNumBytes, - undefined, - opts.canOwn - ); - } else if (ArrayBuffer.isView(data)) { - FS.write( - stream, - data, - 0, - data.byteLength, - undefined, - opts.canOwn - ); - } else { - throw new Error('Unsupported data type'); - } - FS.close(stream); - }, - cwd: () => FS.currentPath, - chdir: (path) => { - var lookup = FS.lookupPath(path, { follow: true }); - if (lookup.node === null) { - throw new FS.ErrnoError(44); - } - if (!FS.isDir(lookup.node.mode)) { - throw new FS.ErrnoError(54); - } - var errCode = FS.nodePermissions(lookup.node, 'x'); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - FS.currentPath = lookup.path; - }, - createDefaultDirectories: () => { - FS.mkdir('/tmp'); - FS.mkdir('/home'); - FS.mkdir('/home/web_user'); - }, - createDefaultDevices: () => { - FS.mkdir('/dev'); - FS.registerDevice(FS.makedev(1, 3), { - read: () => 0, - write: (stream, buffer, offset, length, pos) => length, - }); - FS.mkdev('/dev/null', FS.makedev(1, 3)); - TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); - TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); - FS.mkdev('/dev/tty', FS.makedev(5, 0)); - FS.mkdev('/dev/tty1', FS.makedev(6, 0)); - var randomBuffer = new Uint8Array(1024), - randomLeft = 0; - var randomByte = () => { - if (randomLeft === 0) { - randomLeft = randomFill(randomBuffer).byteLength; - } - return randomBuffer[--randomLeft]; - }; - FS.createDevice('/dev', 'random', randomByte); - FS.createDevice('/dev', 'urandom', randomByte); - FS.mkdir('/dev/shm'); - FS.mkdir('/dev/shm/tmp'); - }, - createSpecialDirectories: () => { - FS.mkdir('/proc'); - var proc_self = FS.mkdir('/proc/self'); - FS.mkdir('/proc/self/fd'); - FS.mount( - { - mount: () => { - var node = FS.createNode( - proc_self, - 'fd', - 16384 | 511, - 73 - ); - node.node_ops = { - lookup: (parent, name) => { - var fd = +name; - var stream = FS.getStreamChecked(fd); - var ret = { - parent: null, - mount: { mountpoint: 'fake' }, - node_ops: { - readlink: () => stream.path, - }, - }; - ret.parent = ret; - return ret; - }, - }; - return node; - }, - }, - {}, - '/proc/self/fd' - ); - }, - createStandardStreams: () => { - if (Module['stdin']) { - FS.createDevice('/dev', 'stdin', Module['stdin']); - } else { - FS.symlink('/dev/tty', '/dev/stdin'); - } - if (Module['stdout']) { - FS.createDevice('/dev', 'stdout', null, Module['stdout']); - } else { - FS.symlink('/dev/tty', '/dev/stdout'); - } - if (Module['stderr']) { - FS.createDevice('/dev', 'stderr', null, Module['stderr']); - } else { - FS.symlink('/dev/tty1', '/dev/stderr'); - } - var stdin = FS.open('/dev/stdin', 0); - var stdout = FS.open('/dev/stdout', 1); - var stderr = FS.open('/dev/stderr', 1); - assert( - stdin.fd === 0, - `invalid handle for stdin (${stdin.fd})` - ); - assert( - stdout.fd === 1, - `invalid handle for stdout (${stdout.fd})` - ); - assert( - stderr.fd === 2, - `invalid handle for stderr (${stderr.fd})` - ); - }, - ensureErrnoError: () => { - if (FS.ErrnoError) return; - FS.ErrnoError = function ErrnoError(errno, node) { - this.name = 'ErrnoError'; - this.node = node; - this.setErrno = function (errno) { - this.errno = errno; - for (var key in ERRNO_CODES) { - if (ERRNO_CODES[key] === errno) { - this.code = key; - break; - } - } - }; - this.setErrno(errno); - this.message = ERRNO_MESSAGES[errno]; - if (this.stack) { - Object.defineProperty(this, 'stack', { - value: new Error().stack, - writable: true, - }); - this.stack = demangleAll(this.stack); - } - }; - FS.ErrnoError.prototype = new Error(); - FS.ErrnoError.prototype.constructor = FS.ErrnoError; - [44].forEach((code) => { - FS.genericErrors[code] = new FS.ErrnoError(code); - FS.genericErrors[code].stack = ''; - }); - }, - staticInit: () => { - FS.ensureErrnoError(); - FS.nameTable = new Array(4096); - FS.mount(MEMFS, {}, '/'); - FS.createDefaultDirectories(); - FS.createDefaultDevices(); - FS.createSpecialDirectories(); - FS.filesystems = { MEMFS: MEMFS, NODEFS: NODEFS }; - }, - init: (input, output, error) => { - assert( - !FS.init.initialized, - 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)' - ); - FS.init.initialized = true; - FS.ensureErrnoError(); - Module['stdin'] = input || Module['stdin']; - Module['stdout'] = output || Module['stdout']; - Module['stderr'] = error || Module['stderr']; - FS.createStandardStreams(); - }, - quit: () => { - FS.init.initialized = false; - _fflush(0); - for (var i = 0; i < FS.streams.length; i++) { - var stream = FS.streams[i]; - if (!stream) { - continue; - } - FS.close(stream); - } - }, - findObject: (path, dontResolveLastLink) => { - var ret = FS.analyzePath(path, dontResolveLastLink); - if (!ret.exists) { - return null; - } - return ret.object; - }, - analyzePath: (path, dontResolveLastLink) => { - try { - var lookup = FS.lookupPath(path, { - follow: !dontResolveLastLink, - }); - path = lookup.path; - } catch (e) {} - var ret = { - isRoot: false, - exists: false, - error: 0, - name: null, - path: null, - object: null, - parentExists: false, - parentPath: null, - parentObject: null, - }; - try { - var lookup = FS.lookupPath(path, { parent: true }); - ret.parentExists = true; - ret.parentPath = lookup.path; - ret.parentObject = lookup.node; - ret.name = PATH.basename(path); - lookup = FS.lookupPath(path, { - follow: !dontResolveLastLink, - }); - ret.exists = true; - ret.path = lookup.path; - ret.object = lookup.node; - ret.name = lookup.node.name; - ret.isRoot = lookup.path === '/'; - } catch (e) { - ret.error = e.errno; - } - return ret; - }, - createPath: (parent, path, canRead, canWrite) => { - parent = - typeof parent == 'string' ? parent : FS.getPath(parent); - var parts = path.split('/').reverse(); - while (parts.length) { - var part = parts.pop(); - if (!part) continue; - var current = PATH.join2(parent, part); - try { - FS.mkdir(current); - } catch (e) {} - parent = current; - } - return current; - }, - createFile: (parent, name, properties, canRead, canWrite) => { - var path = PATH.join2( - typeof parent == 'string' ? parent : FS.getPath(parent), - name - ); - var mode = FS_getMode(canRead, canWrite); - return FS.create(path, mode); - }, - createDataFile: (parent, name, data, canRead, canWrite, canOwn) => { - var path = name; - if (parent) { - parent = - typeof parent == 'string' ? parent : FS.getPath(parent); - path = name ? PATH.join2(parent, name) : parent; - } - var mode = FS_getMode(canRead, canWrite); - var node = FS.create(path, mode); - if (data) { - if (typeof data == 'string') { - var arr = new Array(data.length); - for (var i = 0, len = data.length; i < len; ++i) - arr[i] = data.charCodeAt(i); - data = arr; - } - FS.chmod(node, mode | 146); - var stream = FS.open(node, 577); - FS.write(stream, data, 0, data.length, 0, canOwn); - FS.close(stream); - FS.chmod(node, mode); - } - return node; - }, - createDevice: (parent, name, input, output) => { - var path = PATH.join2( - typeof parent == 'string' ? parent : FS.getPath(parent), - name - ); - var mode = FS_getMode(!!input, !!output); - if (!FS.createDevice.major) FS.createDevice.major = 64; - var dev = FS.makedev(FS.createDevice.major++, 0); - FS.registerDevice(dev, { - open: (stream) => { - stream.seekable = false; - }, - close: (stream) => { - if (output && output.buffer && output.buffer.length) { - output(10); - } - }, - read: (stream, buffer, offset, length, pos) => { - var bytesRead = 0; - for (var i = 0; i < length; i++) { - var result; - try { - result = input(); - } catch (e) { - throw new FS.ErrnoError(29); - } - if (result === undefined && bytesRead === 0) { - throw new FS.ErrnoError(6); - } - if (result === null || result === undefined) break; - bytesRead++; - buffer[offset + i] = result; - } - if (bytesRead) { - stream.node.timestamp = Date.now(); - } - return bytesRead; - }, - write: (stream, buffer, offset, length, pos) => { - for (var i = 0; i < length; i++) { - try { - output(buffer[offset + i]); - } catch (e) { - throw new FS.ErrnoError(29); - } - } - if (length) { - stream.node.timestamp = Date.now(); - } - return i; - }, - }); - return FS.mkdev(path, mode, dev); - }, - forceLoadFile: (obj) => { - if (obj.isDevice || obj.isFolder || obj.link || obj.contents) - return true; - if (typeof XMLHttpRequest != 'undefined') { - throw new Error( - 'Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.' - ); - } else if (read_) { - try { - obj.contents = intArrayFromString(read_(obj.url), true); - obj.usedBytes = obj.contents.length; - } catch (e) { - throw new FS.ErrnoError(29); - } - } else { - throw new Error( - 'Cannot load without read() or XMLHttpRequest.' - ); - } - }, - createLazyFile: (parent, name, url, canRead, canWrite) => { - function LazyUint8Array() { - this.lengthKnown = false; - this.chunks = []; - } - LazyUint8Array.prototype.get = function LazyUint8Array_get( - idx - ) { - if (idx > this.length - 1 || idx < 0) { - return undefined; - } - var chunkOffset = idx % this.chunkSize; - var chunkNum = (idx / this.chunkSize) | 0; - return this.getter(chunkNum)[chunkOffset]; - }; - LazyUint8Array.prototype.setDataGetter = - function LazyUint8Array_setDataGetter(getter) { - this.getter = getter; - }; - LazyUint8Array.prototype.cacheLength = - function LazyUint8Array_cacheLength() { - var xhr = new XMLHttpRequest(); - xhr.open('HEAD', url, false); - xhr.send(null); - if ( - !( - (xhr.status >= 200 && xhr.status < 300) || - xhr.status === 304 - ) - ) - throw new Error( - "Couldn't load " + - url + - '. Status: ' + - xhr.status - ); - var datalength = Number( - xhr.getResponseHeader('Content-length') - ); - var header; - var hasByteServing = - (header = xhr.getResponseHeader('Accept-Ranges')) && - header === 'bytes'; - var usesGzip = - (header = - xhr.getResponseHeader('Content-Encoding')) && - header === 'gzip'; - var chunkSize = 1024 * 1024; - if (!hasByteServing) chunkSize = datalength; - var doXHR = (from, to) => { - if (from > to) - throw new Error( - 'invalid range (' + - from + - ', ' + - to + - ') or no bytes requested!' - ); - if (to > datalength - 1) - throw new Error( - 'only ' + - datalength + - ' bytes available! programmer error!' - ); - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, false); - if (datalength !== chunkSize) - xhr.setRequestHeader( - 'Range', - 'bytes=' + from + '-' + to - ); - xhr.responseType = 'arraybuffer'; - if (xhr.overrideMimeType) { - xhr.overrideMimeType( - 'text/plain; charset=x-user-defined' - ); - } - xhr.send(null); - if ( - !( - (xhr.status >= 200 && xhr.status < 300) || - xhr.status === 304 - ) - ) - throw new Error( - "Couldn't load " + - url + - '. Status: ' + - xhr.status - ); - if (xhr.response !== undefined) { - return new Uint8Array(xhr.response || []); - } - return intArrayFromString( - xhr.responseText || '', - true - ); - }; - var lazyArray = this; - lazyArray.setDataGetter((chunkNum) => { - var start = chunkNum * chunkSize; - var end = (chunkNum + 1) * chunkSize - 1; - end = Math.min(end, datalength - 1); - if ( - typeof lazyArray.chunks[chunkNum] == 'undefined' - ) { - lazyArray.chunks[chunkNum] = doXHR(start, end); - } - if ( - typeof lazyArray.chunks[chunkNum] == 'undefined' - ) - throw new Error('doXHR failed!'); - return lazyArray.chunks[chunkNum]; - }); - if (usesGzip || !datalength) { - chunkSize = datalength = 1; - datalength = this.getter(0).length; - chunkSize = datalength; - out( - 'LazyFiles on gzip forces download of the whole file when length is accessed' - ); - } - this._length = datalength; - this._chunkSize = chunkSize; - this.lengthKnown = true; - }; - if (typeof XMLHttpRequest != 'undefined') { - if (!ENVIRONMENT_IS_WORKER) - throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc'; - var lazyArray = new LazyUint8Array(); - Object.defineProperties(lazyArray, { - length: { - get: function () { - if (!this.lengthKnown) { - this.cacheLength(); - } - return this._length; - }, - }, - chunkSize: { - get: function () { - if (!this.lengthKnown) { - this.cacheLength(); - } - return this._chunkSize; - }, - }, - }); - var properties = { isDevice: false, contents: lazyArray }; - } else { - var properties = { isDevice: false, url: url }; - } - var node = FS.createFile( - parent, - name, - properties, - canRead, - canWrite - ); - if (properties.contents) { - node.contents = properties.contents; - } else if (properties.url) { - node.contents = null; - node.url = properties.url; - } - Object.defineProperties(node, { - usedBytes: { - get: function () { - return this.contents.length; - }, - }, - }); - var stream_ops = {}; - var keys = Object.keys(node.stream_ops); - keys.forEach((key) => { - var fn = node.stream_ops[key]; - stream_ops[key] = function forceLoadLazyFile() { - FS.forceLoadFile(node); - return fn.apply(null, arguments); - }; - }); - function writeChunks(stream, buffer, offset, length, position) { - var contents = stream.node.contents; - if (position >= contents.length) return 0; - var size = Math.min(contents.length - position, length); - assert(size >= 0); - if (contents.slice) { - for (var i = 0; i < size; i++) { - buffer[offset + i] = contents[position + i]; - } - } else { - for (var i = 0; i < size; i++) { - buffer[offset + i] = contents.get(position + i); - } - } - return size; - } - stream_ops.read = ( - stream, - buffer, - offset, - length, - position - ) => { - FS.forceLoadFile(node); - return writeChunks( - stream, - buffer, - offset, - length, - position - ); - }; - stream_ops.mmap = (stream, length, position, prot, flags) => { - FS.forceLoadFile(node); - var ptr = mmapAlloc(length); - if (!ptr) { - throw new FS.ErrnoError(48); - } - writeChunks(stream, HEAP8, ptr, length, position); - return { ptr: ptr, allocated: true }; - }; - node.stream_ops = stream_ops; - return node; - }, - absolutePath: () => { - abort( - 'FS.absolutePath has been removed; use PATH_FS.resolve instead' - ); - }, - createFolder: () => { - abort('FS.createFolder has been removed; use FS.mkdir instead'); - }, - createLink: () => { - abort('FS.createLink has been removed; use FS.symlink instead'); - }, - joinPath: () => { - abort('FS.joinPath has been removed; use PATH.join instead'); - }, - mmapAlloc: () => { - abort( - 'FS.mmapAlloc has been replaced by the top level function mmapAlloc' - ); - }, - standardizePath: () => { - abort( - 'FS.standardizePath has been removed; use PATH.normalize instead' - ); - }, - }; - var SYSCALLS = { - DEFAULT_POLLMASK: 5, - calculateAt: function (dirfd, path, allowEmpty) { - if (PATH.isAbs(path)) { - return path; - } - var dir; - if (dirfd === -100) { - dir = FS.cwd(); - } else { - var dirstream = SYSCALLS.getStreamFromFD(dirfd); - dir = dirstream.path; - } - if (path.length == 0) { - if (!allowEmpty) { - throw new FS.ErrnoError(44); - } - return dir; - } - return PATH.join2(dir, path); - }, - doStat: function (func, path, buf) { - try { - var stat = func(path); - } catch (e) { - if ( - e && - e.node && - PATH.normalize(path) !== - PATH.normalize(FS.getPath(e.node)) - ) { - return -54; - } - throw e; - } - HEAP32[buf >> 2] = stat.dev; - checkInt32(stat.dev); - HEAP32[(buf + 4) >> 2] = stat.mode; - checkInt32(stat.mode); - HEAPU32[(buf + 8) >> 2] = stat.nlink; - checkInt32(stat.nlink); - HEAP32[(buf + 12) >> 2] = stat.uid; - checkInt32(stat.uid); - HEAP32[(buf + 16) >> 2] = stat.gid; - checkInt32(stat.gid); - HEAP32[(buf + 20) >> 2] = stat.rdev; - checkInt32(stat.rdev); - (tempI64 = [ - stat.size >>> 0, - ((tempDouble = stat.size), - +Math.abs(tempDouble) >= 1 - ? tempDouble > 0 - ? +Math.floor(tempDouble / 4294967296) >>> 0 - : ~~+Math.ceil( - (tempDouble - +(~~tempDouble >>> 0)) / - 4294967296 - ) >>> 0 - : 0), - ]), - (HEAP32[(buf + 24) >> 2] = tempI64[0]), - (HEAP32[(buf + 28) >> 2] = tempI64[1]); - checkInt64(stat.size); - HEAP32[(buf + 32) >> 2] = 4096; - checkInt32(4096); - HEAP32[(buf + 36) >> 2] = stat.blocks; - checkInt32(stat.blocks); - var atime = stat.atime.getTime(); - var mtime = stat.mtime.getTime(); - var ctime = stat.ctime.getTime(); - (tempI64 = [ - Math.floor(atime / 1e3) >>> 0, - ((tempDouble = Math.floor(atime / 1e3)), - +Math.abs(tempDouble) >= 1 - ? tempDouble > 0 - ? +Math.floor(tempDouble / 4294967296) >>> 0 - : ~~+Math.ceil( - (tempDouble - +(~~tempDouble >>> 0)) / - 4294967296 - ) >>> 0 - : 0), - ]), - (HEAP32[(buf + 40) >> 2] = tempI64[0]), - (HEAP32[(buf + 44) >> 2] = tempI64[1]); - checkInt64(Math.floor(atime / 1e3)); - HEAPU32[(buf + 48) >> 2] = (atime % 1e3) * 1e3; - checkInt32((atime % 1e3) * 1e3); - (tempI64 = [ - Math.floor(mtime / 1e3) >>> 0, - ((tempDouble = Math.floor(mtime / 1e3)), - +Math.abs(tempDouble) >= 1 - ? tempDouble > 0 - ? +Math.floor(tempDouble / 4294967296) >>> 0 - : ~~+Math.ceil( - (tempDouble - +(~~tempDouble >>> 0)) / - 4294967296 - ) >>> 0 - : 0), - ]), - (HEAP32[(buf + 56) >> 2] = tempI64[0]), - (HEAP32[(buf + 60) >> 2] = tempI64[1]); - checkInt64(Math.floor(mtime / 1e3)); - HEAPU32[(buf + 64) >> 2] = (mtime % 1e3) * 1e3; - checkInt32((mtime % 1e3) * 1e3); - (tempI64 = [ - Math.floor(ctime / 1e3) >>> 0, - ((tempDouble = Math.floor(ctime / 1e3)), - +Math.abs(tempDouble) >= 1 - ? tempDouble > 0 - ? +Math.floor(tempDouble / 4294967296) >>> 0 - : ~~+Math.ceil( - (tempDouble - +(~~tempDouble >>> 0)) / - 4294967296 - ) >>> 0 - : 0), - ]), - (HEAP32[(buf + 72) >> 2] = tempI64[0]), - (HEAP32[(buf + 76) >> 2] = tempI64[1]); - checkInt64(Math.floor(ctime / 1e3)); - HEAPU32[(buf + 80) >> 2] = (ctime % 1e3) * 1e3; - checkInt32((ctime % 1e3) * 1e3); - (tempI64 = [ - stat.ino >>> 0, - ((tempDouble = stat.ino), - +Math.abs(tempDouble) >= 1 - ? tempDouble > 0 - ? +Math.floor(tempDouble / 4294967296) >>> 0 - : ~~+Math.ceil( - (tempDouble - +(~~tempDouble >>> 0)) / - 4294967296 - ) >>> 0 - : 0), - ]), - (HEAP32[(buf + 88) >> 2] = tempI64[0]), - (HEAP32[(buf + 92) >> 2] = tempI64[1]); - checkInt64(stat.ino); - return 0; - }, - doMsync: function (addr, stream, len, flags, offset) { - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43); - } - if (flags & 2) { - return 0; - } - var buffer = HEAPU8.slice(addr, addr + len); - FS.msync(stream, buffer, offset, len, flags); - }, - varargs: undefined, - get() { - assert(SYSCALLS.varargs != undefined); - SYSCALLS.varargs += 4; - var ret = HEAP32[(SYSCALLS.varargs - 4) >> 2]; - return ret; - }, - getStr(ptr) { - var ret = UTF8ToString(ptr); - return ret; - }, - getStreamFromFD: function (fd) { - var stream = FS.getStreamChecked(fd); - return stream; - }, - }; - function ___syscall_fcntl64(fd, cmd, varargs) { - SYSCALLS.varargs = varargs; - try { - var stream = SYSCALLS.getStreamFromFD(fd); - switch (cmd) { - case 0: { - var arg = SYSCALLS.get(); - if (arg < 0) { - return -28; - } - var newStream; - newStream = FS.createStream(stream, arg); - return newStream.fd; - } - case 1: - case 2: - return 0; - case 3: - return stream.flags; - case 4: { - var arg = SYSCALLS.get(); - stream.flags |= arg; - return 0; - } - case 5: { - var arg = SYSCALLS.get(); - var offset = 0; - HEAP16[(arg + offset) >> 1] = 2; - checkInt16(2); - return 0; - } - case 6: - case 7: - return 0; - case 16: - case 8: - return -28; - case 9: - setErrNo(28); - return -1; - default: { - return -28; - } - } - } catch (e) { - if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) - throw e; - return -e.errno; - } - } - function ___syscall_fstat64(fd, buf) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - return SYSCALLS.doStat(FS.stat, stream.path, buf); - } catch (e) { - if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) - throw e; - return -e.errno; - } - } - function ___syscall_ioctl(fd, op, varargs) { - SYSCALLS.varargs = varargs; - try { - var stream = SYSCALLS.getStreamFromFD(fd); - switch (op) { - case 21509: { - if (!stream.tty) return -59; - return 0; - } - case 21505: { - if (!stream.tty) return -59; - if (stream.tty.ops.ioctl_tcgets) { - var termios = stream.tty.ops.ioctl_tcgets(stream); - var argp = SYSCALLS.get(); - HEAP32[argp >> 2] = termios.c_iflag || 0; - checkInt32(termios.c_iflag || 0); - HEAP32[(argp + 4) >> 2] = termios.c_oflag || 0; - checkInt32(termios.c_oflag || 0); - HEAP32[(argp + 8) >> 2] = termios.c_cflag || 0; - checkInt32(termios.c_cflag || 0); - HEAP32[(argp + 12) >> 2] = termios.c_lflag || 0; - checkInt32(termios.c_lflag || 0); - for (var i = 0; i < 32; i++) { - HEAP8[(argp + i + 17) >> 0] = - termios.c_cc[i] || 0; - checkInt8(termios.c_cc[i] || 0); - } - return 0; - } - return 0; - } - case 21510: - case 21511: - case 21512: { - if (!stream.tty) return -59; - return 0; - } - case 21506: - case 21507: - case 21508: { - if (!stream.tty) return -59; - if (stream.tty.ops.ioctl_tcsets) { - var argp = SYSCALLS.get(); - var c_iflag = HEAP32[argp >> 2]; - var c_oflag = HEAP32[(argp + 4) >> 2]; - var c_cflag = HEAP32[(argp + 8) >> 2]; - var c_lflag = HEAP32[(argp + 12) >> 2]; - var c_cc = []; - for (var i = 0; i < 32; i++) { - c_cc.push(HEAP8[(argp + i + 17) >> 0]); - } - return stream.tty.ops.ioctl_tcsets(stream.tty, op, { - c_iflag: c_iflag, - c_oflag: c_oflag, - c_cflag: c_cflag, - c_lflag: c_lflag, - c_cc: c_cc, - }); - } - return 0; - } - case 21519: { - if (!stream.tty) return -59; - var argp = SYSCALLS.get(); - HEAP32[argp >> 2] = 0; - checkInt32(0); - return 0; - } - case 21520: { - if (!stream.tty) return -59; - return -28; - } - case 21531: { - var argp = SYSCALLS.get(); - return FS.ioctl(stream, op, argp); - } - case 21523: { - if (!stream.tty) return -59; - if (stream.tty.ops.ioctl_tiocgwinsz) { - var winsize = stream.tty.ops.ioctl_tiocgwinsz( - stream.tty - ); - var argp = SYSCALLS.get(); - HEAP16[argp >> 1] = winsize[0]; - checkInt16(winsize[0]); - HEAP16[(argp + 2) >> 1] = winsize[1]; - checkInt16(winsize[1]); - } - return 0; - } - case 21524: { - if (!stream.tty) return -59; - return 0; - } - case 21515: { - if (!stream.tty) return -59; - return 0; - } - default: - return -28; - } - } catch (e) { - if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) - throw e; - return -e.errno; - } - } - function ___syscall_lstat64(path, buf) { - try { - path = SYSCALLS.getStr(path); - return SYSCALLS.doStat(FS.lstat, path, buf); - } catch (e) { - if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) - throw e; - return -e.errno; - } - } - function ___syscall_newfstatat(dirfd, path, buf, flags) { - try { - path = SYSCALLS.getStr(path); - var nofollow = flags & 256; - var allowEmpty = flags & 4096; - flags = flags & ~6400; - assert( - !flags, - `unknown flags in __syscall_newfstatat: ${flags}` - ); - path = SYSCALLS.calculateAt(dirfd, path, allowEmpty); - return SYSCALLS.doStat( - nofollow ? FS.lstat : FS.stat, - path, - buf - ); - } catch (e) { - if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) - throw e; - return -e.errno; - } - } - function ___syscall_openat(dirfd, path, flags, varargs) { - SYSCALLS.varargs = varargs; - try { - path = SYSCALLS.getStr(path); - path = SYSCALLS.calculateAt(dirfd, path); - var mode = varargs ? SYSCALLS.get() : 0; - return FS.open(path, flags, mode).fd; - } catch (e) { - if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) - throw e; - return -e.errno; - } - } - function ___syscall_stat64(path, buf) { - try { - path = SYSCALLS.getStr(path); - return SYSCALLS.doStat(FS.stat, path, buf); - } catch (e) { - if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) - throw e; - return -e.errno; - } - } - function ___throw_exception_with_stack_trace(ex) { - var e = new WebAssembly.Exception(getCppExceptionTag(), [ex], { - traceStack: true, - }); - e.message = getExceptionMessage(e); - if (e.stack) { - var arr = e.stack.split('\n'); - arr.splice(1, 1); - e.stack = arr.join('\n'); - } - throw e; - } - var structRegistrations = {}; - function runDestructors(destructors) { - while (destructors.length) { - var ptr = destructors.pop(); - var del = destructors.pop(); - del(ptr); - } - } - function simpleReadValueFromPointer(pointer) { - return this['fromWireType'](HEAP32[pointer >> 2]); - } - var awaitingDependencies = {}; - var registeredTypes = {}; - var typeDependencies = {}; - var InternalError = undefined; - function throwInternalError(message) { - throw new InternalError(message); - } - function whenDependentTypesAreResolved( - myTypes, - dependentTypes, - getTypeConverters - ) { - myTypes.forEach(function (type) { - typeDependencies[type] = dependentTypes; - }); - function onComplete(typeConverters) { - var myTypeConverters = getTypeConverters(typeConverters); - if (myTypeConverters.length !== myTypes.length) { - throwInternalError('Mismatched type converter count'); - } - for (var i = 0; i < myTypes.length; ++i) { - registerType(myTypes[i], myTypeConverters[i]); - } - } - var typeConverters = new Array(dependentTypes.length); - var unregisteredTypes = []; - var registered = 0; - dependentTypes.forEach((dt, i) => { - if (registeredTypes.hasOwnProperty(dt)) { - typeConverters[i] = registeredTypes[dt]; - } else { - unregisteredTypes.push(dt); - if (!awaitingDependencies.hasOwnProperty(dt)) { - awaitingDependencies[dt] = []; - } - awaitingDependencies[dt].push(() => { - typeConverters[i] = registeredTypes[dt]; - ++registered; - if (registered === unregisteredTypes.length) { - onComplete(typeConverters); - } - }); - } - }); - if (0 === unregisteredTypes.length) { - onComplete(typeConverters); - } - } - var __embind_finalize_value_object = function (structType) { - var reg = structRegistrations[structType]; - delete structRegistrations[structType]; - var rawConstructor = reg.rawConstructor; - var rawDestructor = reg.rawDestructor; - var fieldRecords = reg.fields; - var fieldTypes = fieldRecords - .map((field) => field.getterReturnType) - .concat(fieldRecords.map((field) => field.setterArgumentType)); - whenDependentTypesAreResolved( - [structType], - fieldTypes, - (fieldTypes) => { - var fields = {}; - fieldRecords.forEach((field, i) => { - var fieldName = field.fieldName; - var getterReturnType = fieldTypes[i]; - var getter = field.getter; - var getterContext = field.getterContext; - var setterArgumentType = - fieldTypes[i + fieldRecords.length]; - var setter = field.setter; - var setterContext = field.setterContext; - fields[fieldName] = { - read: (ptr) => - getterReturnType['fromWireType']( - getter(getterContext, ptr) - ), - write: (ptr, o) => { - var destructors = []; - setter( - setterContext, - ptr, - setterArgumentType['toWireType']( - destructors, - o - ) - ); - runDestructors(destructors); - }, - }; - }); - return [ - { - name: reg.name, - fromWireType: function (ptr) { - var rv = {}; - for (var i in fields) { - rv[i] = fields[i].read(ptr); - } - rawDestructor(ptr); - return rv; - }, - toWireType: function (destructors, o) { - for (var fieldName in fields) { - if (!(fieldName in o)) { - throw new TypeError( - `Missing field: "${fieldName}"` - ); - } - } - var ptr = rawConstructor(); - for (fieldName in fields) { - fields[fieldName].write(ptr, o[fieldName]); - } - if (destructors !== null) { - destructors.push(rawDestructor, ptr); - } - return ptr; - }, - argPackAdvance: 8, - readValueFromPointer: simpleReadValueFromPointer, - destructorFunction: rawDestructor, - }, - ]; - } - ); - }; - function __embind_register_bigint( - primitiveType, - name, - size, - minRange, - maxRange - ) {} - function getShiftFromSize(size) { - switch (size) { - case 1: - return 0; - case 2: - return 1; - case 4: - return 2; - case 8: - return 3; - default: - throw new TypeError(`Unknown type size: ${size}`); - } - } - function embind_init_charCodes() { - var codes = new Array(256); - for (var i = 0; i < 256; ++i) { - codes[i] = String.fromCharCode(i); - } - embind_charCodes = codes; - } - var embind_charCodes = undefined; - function readLatin1String(ptr) { - var ret = ''; - var c = ptr; - while (HEAPU8[c]) { - ret += embind_charCodes[HEAPU8[c++]]; - } - return ret; - } - var BindingError = undefined; - function throwBindingError(message) { - throw new BindingError(message); - } - function sharedRegisterType(rawType, registeredInstance, options = {}) { - var name = registeredInstance.name; - if (!rawType) { - throwBindingError( - `type "${name}" must have a positive integer typeid pointer` - ); - } - if (registeredTypes.hasOwnProperty(rawType)) { - if (options.ignoreDuplicateRegistrations) { - return; - } else { - throwBindingError(`Cannot register type '${name}' twice`); - } - } - registeredTypes[rawType] = registeredInstance; - delete typeDependencies[rawType]; - if (awaitingDependencies.hasOwnProperty(rawType)) { - var callbacks = awaitingDependencies[rawType]; - delete awaitingDependencies[rawType]; - callbacks.forEach((cb) => cb()); - } - } - function registerType(rawType, registeredInstance, options = {}) { - if (!('argPackAdvance' in registeredInstance)) { - throw new TypeError( - 'registerType registeredInstance requires argPackAdvance' - ); - } - return sharedRegisterType(rawType, registeredInstance, options); - } - function __embind_register_bool( - rawType, - name, - size, - trueValue, - falseValue - ) { - var shift = getShiftFromSize(size); - name = readLatin1String(name); - registerType(rawType, { - name: name, - fromWireType: function (wt) { - return !!wt; - }, - toWireType: function (destructors, o) { - return o ? trueValue : falseValue; - }, - argPackAdvance: 8, - readValueFromPointer: function (pointer) { - var heap; - if (size === 1) { - heap = HEAP8; - } else if (size === 2) { - heap = HEAP16; - } else if (size === 4) { - heap = HEAP32; - } else { - throw new TypeError( - 'Unknown boolean type size: ' + name - ); - } - return this['fromWireType'](heap[pointer >> shift]); - }, - destructorFunction: null, - }); - } - function ClassHandle_isAliasOf(other) { - if (!(this instanceof ClassHandle)) { - return false; - } - if (!(other instanceof ClassHandle)) { - return false; - } - var leftClass = this.$$.ptrType.registeredClass; - var left = this.$$.ptr; - var rightClass = other.$$.ptrType.registeredClass; - var right = other.$$.ptr; - while (leftClass.baseClass) { - left = leftClass.upcast(left); - leftClass = leftClass.baseClass; - } - while (rightClass.baseClass) { - right = rightClass.upcast(right); - rightClass = rightClass.baseClass; - } - return leftClass === rightClass && left === right; - } - function shallowCopyInternalPointer(o) { - return { - count: o.count, - deleteScheduled: o.deleteScheduled, - preservePointerOnDelete: o.preservePointerOnDelete, - ptr: o.ptr, - ptrType: o.ptrType, - smartPtr: o.smartPtr, - smartPtrType: o.smartPtrType, - }; - } - function throwInstanceAlreadyDeleted(obj) { - function getInstanceTypeName(handle) { - return handle.$$.ptrType.registeredClass.name; - } - throwBindingError( - getInstanceTypeName(obj) + ' instance already deleted' - ); - } - var finalizationRegistry = false; - function detachFinalizer(handle) {} - function runDestructor($$) { - if ($$.smartPtr) { - $$.smartPtrType.rawDestructor($$.smartPtr); - } else { - $$.ptrType.registeredClass.rawDestructor($$.ptr); - } - } - function releaseClassHandle($$) { - $$.count.value -= 1; - var toDelete = 0 === $$.count.value; - if (toDelete) { - runDestructor($$); - } - } - function downcastPointer(ptr, ptrClass, desiredClass) { - if (ptrClass === desiredClass) { - return ptr; - } - if (undefined === desiredClass.baseClass) { - return null; - } - var rv = downcastPointer(ptr, ptrClass, desiredClass.baseClass); - if (rv === null) { - return null; - } - return desiredClass.downcast(rv); - } - var registeredPointers = {}; - function getInheritedInstanceCount() { - return Object.keys(registeredInstances).length; - } - function getLiveInheritedInstances() { - var rv = []; - for (var k in registeredInstances) { - if (registeredInstances.hasOwnProperty(k)) { - rv.push(registeredInstances[k]); - } - } - return rv; - } - var deletionQueue = []; - function flushPendingDeletes() { - while (deletionQueue.length) { - var obj = deletionQueue.pop(); - obj.$$.deleteScheduled = false; - obj['delete'](); - } - } - var delayFunction = undefined; - function setDelayFunction(fn) { - delayFunction = fn; - if (deletionQueue.length && delayFunction) { - delayFunction(flushPendingDeletes); - } - } - function init_embind() { - Module['getInheritedInstanceCount'] = getInheritedInstanceCount; - Module['getLiveInheritedInstances'] = getLiveInheritedInstances; - Module['flushPendingDeletes'] = flushPendingDeletes; - Module['setDelayFunction'] = setDelayFunction; - } - var registeredInstances = {}; - function getBasestPointer(class_, ptr) { - if (ptr === undefined) { - throwBindingError('ptr should not be undefined'); - } - while (class_.baseClass) { - ptr = class_.upcast(ptr); - class_ = class_.baseClass; - } - return ptr; - } - function getInheritedInstance(class_, ptr) { - ptr = getBasestPointer(class_, ptr); - return registeredInstances[ptr]; - } - function makeClassHandle(prototype, record) { - if (!record.ptrType || !record.ptr) { - throwInternalError('makeClassHandle requires ptr and ptrType'); - } - var hasSmartPtrType = !!record.smartPtrType; - var hasSmartPtr = !!record.smartPtr; - if (hasSmartPtrType !== hasSmartPtr) { - throwInternalError( - 'Both smartPtrType and smartPtr must be specified' - ); - } - record.count = { value: 1 }; - return attachFinalizer( - Object.create(prototype, { $$: { value: record } }) - ); - } - function RegisteredPointer_fromWireType(ptr) { - var rawPointer = this.getPointee(ptr); - if (!rawPointer) { - this.destructor(ptr); - return null; - } - var registeredInstance = getInheritedInstance( - this.registeredClass, - rawPointer - ); - if (undefined !== registeredInstance) { - if (0 === registeredInstance.$$.count.value) { - registeredInstance.$$.ptr = rawPointer; - registeredInstance.$$.smartPtr = ptr; - return registeredInstance['clone'](); - } else { - var rv = registeredInstance['clone'](); - this.destructor(ptr); - return rv; - } - } - function makeDefaultHandle() { - if (this.isSmartPointer) { - return makeClassHandle( - this.registeredClass.instancePrototype, - { - ptrType: this.pointeeType, - ptr: rawPointer, - smartPtrType: this, - smartPtr: ptr, - } - ); - } else { - return makeClassHandle( - this.registeredClass.instancePrototype, - { ptrType: this, ptr: ptr } - ); - } - } - var actualType = this.registeredClass.getActualType(rawPointer); - var registeredPointerRecord = registeredPointers[actualType]; - if (!registeredPointerRecord) { - return makeDefaultHandle.call(this); - } - var toType; - if (this.isConst) { - toType = registeredPointerRecord.constPointerType; - } else { - toType = registeredPointerRecord.pointerType; - } - var dp = downcastPointer( - rawPointer, - this.registeredClass, - toType.registeredClass - ); - if (dp === null) { - return makeDefaultHandle.call(this); - } - if (this.isSmartPointer) { - return makeClassHandle( - toType.registeredClass.instancePrototype, - { - ptrType: toType, - ptr: dp, - smartPtrType: this, - smartPtr: ptr, - } - ); - } else { - return makeClassHandle( - toType.registeredClass.instancePrototype, - { ptrType: toType, ptr: dp } - ); - } - } - var attachFinalizer = function (handle) { - if ('undefined' === typeof FinalizationRegistry) { - attachFinalizer = (handle) => handle; - return handle; - } - finalizationRegistry = new FinalizationRegistry((info) => { - console.warn(info.leakWarning.stack.replace(/^Error: /, '')); - releaseClassHandle(info.$$); - }); - attachFinalizer = (handle) => { - var $$ = handle.$$; - var hasSmartPtr = !!$$.smartPtr; - if (hasSmartPtr) { - var info = { $$: $$ }; - var cls = $$.ptrType.registeredClass; - info.leakWarning = new Error( - `Embind found a leaked C++ instance ${ - cls.name - } <${ptrToString($$.ptr)}>.\n` + - "We'll free it automatically in this case, but this functionality is not reliable across various environments.\n" + - "Make sure to invoke .delete() manually once you're done with the instance instead.\n" + - 'Originally allocated' - ); - if ('captureStackTrace' in Error) { - Error.captureStackTrace( - info.leakWarning, - RegisteredPointer_fromWireType - ); - } - finalizationRegistry.register(handle, info, handle); - } - return handle; - }; - detachFinalizer = (handle) => - finalizationRegistry.unregister(handle); - return attachFinalizer(handle); - }; - function ClassHandle_clone() { - if (!this.$$.ptr) { - throwInstanceAlreadyDeleted(this); - } - if (this.$$.preservePointerOnDelete) { - this.$$.count.value += 1; - return this; - } else { - var clone = attachFinalizer( - Object.create(Object.getPrototypeOf(this), { - $$: { value: shallowCopyInternalPointer(this.$$) }, - }) - ); - clone.$$.count.value += 1; - clone.$$.deleteScheduled = false; - return clone; - } - } - function ClassHandle_delete() { - if (!this.$$.ptr) { - throwInstanceAlreadyDeleted(this); - } - if (this.$$.deleteScheduled && !this.$$.preservePointerOnDelete) { - throwBindingError('Object already scheduled for deletion'); - } - detachFinalizer(this); - releaseClassHandle(this.$$); - if (!this.$$.preservePointerOnDelete) { - this.$$.smartPtr = undefined; - this.$$.ptr = undefined; - } - } - function ClassHandle_isDeleted() { - return !this.$$.ptr; - } - function ClassHandle_deleteLater() { - if (!this.$$.ptr) { - throwInstanceAlreadyDeleted(this); - } - if (this.$$.deleteScheduled && !this.$$.preservePointerOnDelete) { - throwBindingError('Object already scheduled for deletion'); - } - deletionQueue.push(this); - if (deletionQueue.length === 1 && delayFunction) { - delayFunction(flushPendingDeletes); - } - this.$$.deleteScheduled = true; - return this; - } - function init_ClassHandle() { - ClassHandle.prototype['isAliasOf'] = ClassHandle_isAliasOf; - ClassHandle.prototype['clone'] = ClassHandle_clone; - ClassHandle.prototype['delete'] = ClassHandle_delete; - ClassHandle.prototype['isDeleted'] = ClassHandle_isDeleted; - ClassHandle.prototype['deleteLater'] = ClassHandle_deleteLater; - } - function ClassHandle() {} - var char_0 = 48; - var char_9 = 57; - function makeLegalFunctionName(name) { - if (undefined === name) { - return '_unknown'; - } - name = name.replace(/[^a-zA-Z0-9_]/g, '$'); - var f = name.charCodeAt(0); - if (f >= char_0 && f <= char_9) { - return `_${name}`; - } - return name; - } - function createNamedFunction(name, body) { - name = makeLegalFunctionName(name); - return { - [name]: function () { - return body.apply(this, arguments); - }, - }[name]; - } - function ensureOverloadTable(proto, methodName, humanName) { - if (undefined === proto[methodName].overloadTable) { - var prevFunc = proto[methodName]; - proto[methodName] = function () { - if ( - !proto[methodName].overloadTable.hasOwnProperty( - arguments.length - ) - ) { - throwBindingError( - `Function '${humanName}' called with an invalid number of arguments (${arguments.length}) - expects one of (${proto[methodName].overloadTable})!` - ); - } - return proto[methodName].overloadTable[ - arguments.length - ].apply(this, arguments); - }; - proto[methodName].overloadTable = []; - proto[methodName].overloadTable[prevFunc.argCount] = prevFunc; - } - } - function exposePublicSymbol(name, value, numArguments) { - if (Module.hasOwnProperty(name)) { - if ( - undefined === numArguments || - (undefined !== Module[name].overloadTable && - undefined !== Module[name].overloadTable[numArguments]) - ) { - throwBindingError( - `Cannot register public name '${name}' twice` - ); - } - ensureOverloadTable(Module, name, name); - if (Module.hasOwnProperty(numArguments)) { - throwBindingError( - `Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!` - ); - } - Module[name].overloadTable[numArguments] = value; - } else { - Module[name] = value; - if (undefined !== numArguments) { - Module[name].numArguments = numArguments; - } - } - } - function RegisteredClass( - name, - constructor, - instancePrototype, - rawDestructor, - baseClass, - getActualType, - upcast, - downcast - ) { - this.name = name; - this.constructor = constructor; - this.instancePrototype = instancePrototype; - this.rawDestructor = rawDestructor; - this.baseClass = baseClass; - this.getActualType = getActualType; - this.upcast = upcast; - this.downcast = downcast; - this.pureVirtualFunctions = []; - } - function upcastPointer(ptr, ptrClass, desiredClass) { - while (ptrClass !== desiredClass) { - if (!ptrClass.upcast) { - throwBindingError( - `Expected null or instance of ${desiredClass.name}, got an instance of ${ptrClass.name}` - ); - } - ptr = ptrClass.upcast(ptr); - ptrClass = ptrClass.baseClass; - } - return ptr; - } - function constNoSmartPtrRawPointerToWireType(destructors, handle) { - if (handle === null) { - if (this.isReference) { - throwBindingError(`null is not a valid ${this.name}`); - } - return 0; - } - if (!handle.$$) { - throwBindingError( - `Cannot pass "${embindRepr(handle)}" as a ${this.name}` - ); - } - if (!handle.$$.ptr) { - throwBindingError( - `Cannot pass deleted object as a pointer of type ${this.name}` - ); - } - var handleClass = handle.$$.ptrType.registeredClass; - var ptr = upcastPointer( - handle.$$.ptr, - handleClass, - this.registeredClass - ); - return ptr; - } - function genericPointerToWireType(destructors, handle) { - var ptr; - if (handle === null) { - if (this.isReference) { - throwBindingError(`null is not a valid ${this.name}`); - } - if (this.isSmartPointer) { - ptr = this.rawConstructor(); - if (destructors !== null) { - destructors.push(this.rawDestructor, ptr); - } - return ptr; - } else { - return 0; - } - } - if (!handle.$$) { - throwBindingError( - `Cannot pass "${embindRepr(handle)}" as a ${this.name}` - ); - } - if (!handle.$$.ptr) { - throwBindingError( - `Cannot pass deleted object as a pointer of type ${this.name}` - ); - } - if (!this.isConst && handle.$$.ptrType.isConst) { - throwBindingError( - `Cannot convert argument of type ${ - handle.$$.smartPtrType - ? handle.$$.smartPtrType.name - : handle.$$.ptrType.name - } to parameter type ${this.name}` - ); - } - var handleClass = handle.$$.ptrType.registeredClass; - ptr = upcastPointer( - handle.$$.ptr, - handleClass, - this.registeredClass - ); - if (this.isSmartPointer) { - if (undefined === handle.$$.smartPtr) { - throwBindingError( - 'Passing raw pointer to smart pointer is illegal' - ); - } - switch (this.sharingPolicy) { - case 0: - if (handle.$$.smartPtrType === this) { - ptr = handle.$$.smartPtr; - } else { - throwBindingError( - `Cannot convert argument of type ${ - handle.$$.smartPtrType - ? handle.$$.smartPtrType.name - : handle.$$.ptrType.name - } to parameter type ${this.name}` - ); - } - break; - case 1: - ptr = handle.$$.smartPtr; - break; - case 2: - if (handle.$$.smartPtrType === this) { - ptr = handle.$$.smartPtr; - } else { - var clonedHandle = handle['clone'](); - ptr = this.rawShare( - ptr, - Emval.toHandle(function () { - clonedHandle['delete'](); - }) - ); - if (destructors !== null) { - destructors.push(this.rawDestructor, ptr); - } - } - break; - default: - throwBindingError('Unsupporting sharing policy'); - } - } - return ptr; - } - function nonConstNoSmartPtrRawPointerToWireType(destructors, handle) { - if (handle === null) { - if (this.isReference) { - throwBindingError(`null is not a valid ${this.name}`); - } - return 0; - } - if (!handle.$$) { - throwBindingError( - `Cannot pass "${embindRepr(handle)}" as a ${this.name}` - ); - } - if (!handle.$$.ptr) { - throwBindingError( - `Cannot pass deleted object as a pointer of type ${this.name}` - ); - } - if (handle.$$.ptrType.isConst) { - throwBindingError( - `Cannot convert argument of type ${handle.$$.ptrType.name} to parameter type ${this.name}` - ); - } - var handleClass = handle.$$.ptrType.registeredClass; - var ptr = upcastPointer( - handle.$$.ptr, - handleClass, - this.registeredClass - ); - return ptr; - } - function RegisteredPointer_getPointee(ptr) { - if (this.rawGetPointee) { - ptr = this.rawGetPointee(ptr); - } - return ptr; - } - function RegisteredPointer_destructor(ptr) { - if (this.rawDestructor) { - this.rawDestructor(ptr); - } - } - function RegisteredPointer_deleteObject(handle) { - if (handle !== null) { - handle['delete'](); - } - } - function init_RegisteredPointer() { - RegisteredPointer.prototype.getPointee = - RegisteredPointer_getPointee; - RegisteredPointer.prototype.destructor = - RegisteredPointer_destructor; - RegisteredPointer.prototype['argPackAdvance'] = 8; - RegisteredPointer.prototype['readValueFromPointer'] = - simpleReadValueFromPointer; - RegisteredPointer.prototype['deleteObject'] = - RegisteredPointer_deleteObject; - RegisteredPointer.prototype['fromWireType'] = - RegisteredPointer_fromWireType; - } - function RegisteredPointer( - name, - registeredClass, - isReference, - isConst, - isSmartPointer, - pointeeType, - sharingPolicy, - rawGetPointee, - rawConstructor, - rawShare, - rawDestructor - ) { - this.name = name; - this.registeredClass = registeredClass; - this.isReference = isReference; - this.isConst = isConst; - this.isSmartPointer = isSmartPointer; - this.pointeeType = pointeeType; - this.sharingPolicy = sharingPolicy; - this.rawGetPointee = rawGetPointee; - this.rawConstructor = rawConstructor; - this.rawShare = rawShare; - this.rawDestructor = rawDestructor; - if (!isSmartPointer && registeredClass.baseClass === undefined) { - if (isConst) { - this['toWireType'] = constNoSmartPtrRawPointerToWireType; - this.destructorFunction = null; - } else { - this['toWireType'] = nonConstNoSmartPtrRawPointerToWireType; - this.destructorFunction = null; - } - } else { - this['toWireType'] = genericPointerToWireType; - } - } - function replacePublicSymbol(name, value, numArguments) { - if (!Module.hasOwnProperty(name)) { - throwInternalError('Replacing nonexistant public symbol'); - } - if ( - undefined !== Module[name].overloadTable && - undefined !== numArguments - ) { - Module[name].overloadTable[numArguments] = value; - } else { - Module[name] = value; - Module[name].argCount = numArguments; - } - } - var dynCallLegacy = (sig, ptr, args) => { - assert( - 'dynCall_' + sig in Module, - `bad function pointer type - dynCall function not found for sig '${sig}'` - ); - if (args && args.length) { - assert( - args.length === sig.substring(1).replace(/j/g, '--').length - ); - } else { - assert(sig.length == 1); - } - var f = Module['dynCall_' + sig]; - return args && args.length - ? f.apply(null, [ptr].concat(args)) - : f.call(null, ptr); - }; - var wasmTableMirror = []; - var getWasmTableEntry = (funcPtr) => { - var func = wasmTableMirror[funcPtr]; - if (!func) { - if (funcPtr >= wasmTableMirror.length) - wasmTableMirror.length = funcPtr + 1; - wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr); - } - assert( - wasmTable.get(funcPtr) == func, - 'JavaScript-side Wasm function table mirror is out of date!' - ); - return func; - }; - var dynCall = (sig, ptr, args) => { - if (sig.includes('j')) { - return dynCallLegacy(sig, ptr, args); - } - assert( - getWasmTableEntry(ptr), - `missing table entry in dynCall: ${ptr}` - ); - var rtn = getWasmTableEntry(ptr).apply(null, args); - return rtn; - }; - var getDynCaller = (sig, ptr) => { - assert( - sig.includes('j') || sig.includes('p'), - 'getDynCaller should only be called with i64 sigs' - ); - var argCache = []; - return function () { - argCache.length = 0; - Object.assign(argCache, arguments); - return dynCall(sig, ptr, argCache); - }; - }; - function embind__requireFunction(signature, rawFunction) { - signature = readLatin1String(signature); - function makeDynCaller() { - if (signature.includes('j')) { - return getDynCaller(signature, rawFunction); - } - return getWasmTableEntry(rawFunction); - } - var fp = makeDynCaller(); - if (typeof fp != 'function') { - throwBindingError( - `unknown function pointer with signature ${signature}: ${rawFunction}` - ); - } - return fp; - } - function extendError(baseErrorType, errorName) { - var errorClass = createNamedFunction(errorName, function (message) { - this.name = errorName; - this.message = message; - var stack = new Error(message).stack; - if (stack !== undefined) { - this.stack = - this.toString() + - '\n' + - stack.replace(/^Error(:[^\n]*)?\n/, ''); - } - }); - errorClass.prototype = Object.create(baseErrorType.prototype); - errorClass.prototype.constructor = errorClass; - errorClass.prototype.toString = function () { - if (this.message === undefined) { - return this.name; - } else { - return `${this.name}: ${this.message}`; - } - }; - return errorClass; - } - var UnboundTypeError = undefined; - function getTypeName(type) { - var ptr = ___getTypeName(type); - var rv = readLatin1String(ptr); - _free(ptr); - return rv; - } - function throwUnboundTypeError(message, types) { - var unboundTypes = []; - var seen = {}; - function visit(type) { - if (seen[type]) { - return; - } - if (registeredTypes[type]) { - return; - } - if (typeDependencies[type]) { - typeDependencies[type].forEach(visit); - return; - } - unboundTypes.push(type); - seen[type] = true; - } - types.forEach(visit); - throw new UnboundTypeError( - `${message}: ` + unboundTypes.map(getTypeName).join([', ']) - ); - } - function __embind_register_class( - rawType, - rawPointerType, - rawConstPointerType, - baseClassRawType, - getActualTypeSignature, - getActualType, - upcastSignature, - upcast, - downcastSignature, - downcast, - name, - destructorSignature, - rawDestructor - ) { - name = readLatin1String(name); - getActualType = embind__requireFunction( - getActualTypeSignature, - getActualType - ); - if (upcast) { - upcast = embind__requireFunction(upcastSignature, upcast); - } - if (downcast) { - downcast = embind__requireFunction(downcastSignature, downcast); - } - rawDestructor = embind__requireFunction( - destructorSignature, - rawDestructor - ); - var legalFunctionName = makeLegalFunctionName(name); - exposePublicSymbol(legalFunctionName, function () { - throwUnboundTypeError( - `Cannot construct ${name} due to unbound types`, - [baseClassRawType] - ); - }); - whenDependentTypesAreResolved( - [rawType, rawPointerType, rawConstPointerType], - baseClassRawType ? [baseClassRawType] : [], - function (base) { - base = base[0]; - var baseClass; - var basePrototype; - if (baseClassRawType) { - baseClass = base.registeredClass; - basePrototype = baseClass.instancePrototype; - } else { - basePrototype = ClassHandle.prototype; - } - var constructor = createNamedFunction( - legalFunctionName, - function () { - if ( - Object.getPrototypeOf(this) !== - instancePrototype - ) { - throw new BindingError( - "Use 'new' to construct " + name - ); - } - if ( - undefined === registeredClass.constructor_body - ) { - throw new BindingError( - name + ' has no accessible constructor' - ); - } - var body = - registeredClass.constructor_body[ - arguments.length - ]; - if (undefined === body) { - throw new BindingError( - `Tried to invoke ctor of ${name} with invalid number of parameters (${ - arguments.length - }) - expected (${Object.keys( - registeredClass.constructor_body - ).toString()}) parameters instead!` - ); - } - return body.apply(this, arguments); - } - ); - var instancePrototype = Object.create(basePrototype, { - constructor: { value: constructor }, - }); - constructor.prototype = instancePrototype; - var registeredClass = new RegisteredClass( - name, - constructor, - instancePrototype, - rawDestructor, - baseClass, - getActualType, - upcast, - downcast - ); - if (registeredClass.baseClass) { - if ( - registeredClass.baseClass.__derivedClasses === - undefined - ) { - registeredClass.baseClass.__derivedClasses = []; - } - registeredClass.baseClass.__derivedClasses.push( - registeredClass - ); - } - var referenceConverter = new RegisteredPointer( - name, - registeredClass, - true, - false, - false - ); - var pointerConverter = new RegisteredPointer( - name + '*', - registeredClass, - false, - false, - false - ); - var constPointerConverter = new RegisteredPointer( - name + ' const*', - registeredClass, - false, - true, - false - ); - registeredPointers[rawType] = { - pointerType: pointerConverter, - constPointerType: constPointerConverter, - }; - replacePublicSymbol(legalFunctionName, constructor); - return [ - referenceConverter, - pointerConverter, - constPointerConverter, - ]; - } - ); - } - function heap32VectorToArray(count, firstElement) { - var array = []; - for (var i = 0; i < count; i++) { - array.push(HEAPU32[(firstElement + i * 4) >> 2]); - } - return array; - } - function newFunc(constructor, argumentList) { - if (!(constructor instanceof Function)) { - throw new TypeError( - `new_ called with constructor type ${typeof constructor} which is not a function` - ); - } - var dummy = createNamedFunction( - constructor.name || 'unknownFunctionName', - function () {} - ); - dummy.prototype = constructor.prototype; - var obj = new dummy(); - var r = constructor.apply(obj, argumentList); - return r instanceof Object ? r : obj; - } - function craftInvokerFunction( - humanName, - argTypes, - classType, - cppInvokerFunc, - cppTargetFunc, - isAsync - ) { - var argCount = argTypes.length; - if (argCount < 2) { - throwBindingError( - "argTypes array size mismatch! Must at least get return value and 'this' types!" - ); - } - assert(!isAsync, 'Async bindings are only supported with JSPI.'); - var isClassMethodFunc = argTypes[1] !== null && classType !== null; - var needsDestructorStack = false; - for (var i = 1; i < argTypes.length; ++i) { - if ( - argTypes[i] !== null && - argTypes[i].destructorFunction === undefined - ) { - needsDestructorStack = true; - break; - } - } - var returns = argTypes[0].name !== 'void'; - var argsList = ''; - var argsListWired = ''; - for (var i = 0; i < argCount - 2; ++i) { - argsList += (i !== 0 ? ', ' : '') + 'arg' + i; - argsListWired += (i !== 0 ? ', ' : '') + 'arg' + i + 'Wired'; - } - var invokerFnBody = `\n return function ${makeLegalFunctionName( - humanName - )}(${argsList}) {\n if (arguments.length !== ${ - argCount - 2 - }) {\n throwBindingError('function ${humanName} called with ${ - arguments.length - } arguments, expected ${argCount - 2} args!');\n }`; - if (needsDestructorStack) { - invokerFnBody += 'var destructors = [];\n'; - } - var dtorStack = needsDestructorStack ? 'destructors' : 'null'; - var args1 = [ - 'throwBindingError', - 'invoker', - 'fn', - 'runDestructors', - 'retType', - 'classParam', - ]; - var args2 = [ - throwBindingError, - cppInvokerFunc, - cppTargetFunc, - runDestructors, - argTypes[0], - argTypes[1], - ]; - if (isClassMethodFunc) { - invokerFnBody += - 'var thisWired = classParam.toWireType(' + - dtorStack + - ', this);\n'; - } - for (var i = 0; i < argCount - 2; ++i) { - invokerFnBody += - 'var arg' + - i + - 'Wired = argType' + - i + - '.toWireType(' + - dtorStack + - ', arg' + - i + - '); // ' + - argTypes[i + 2].name + - '\n'; - args1.push('argType' + i); - args2.push(argTypes[i + 2]); - } - if (isClassMethodFunc) { - argsListWired = - 'thisWired' + - (argsListWired.length > 0 ? ', ' : '') + - argsListWired; - } - invokerFnBody += - (returns || isAsync ? 'var rv = ' : '') + - 'invoker(fn' + - (argsListWired.length > 0 ? ', ' : '') + - argsListWired + - ');\n'; - if (needsDestructorStack) { - invokerFnBody += 'runDestructors(destructors);\n'; - } else { - for ( - var i = isClassMethodFunc ? 1 : 2; - i < argTypes.length; - ++i - ) { - var paramName = - i === 1 ? 'thisWired' : 'arg' + (i - 2) + 'Wired'; - if (argTypes[i].destructorFunction !== null) { - invokerFnBody += - paramName + - '_dtor(' + - paramName + - '); // ' + - argTypes[i].name + - '\n'; - args1.push(paramName + '_dtor'); - args2.push(argTypes[i].destructorFunction); - } - } - } - if (returns) { - invokerFnBody += - 'var ret = retType.fromWireType(rv);\n' + 'return ret;\n'; - } else { - } - invokerFnBody += '}\n'; - args1.push(invokerFnBody); - return newFunc(Function, args1).apply(null, args2); - } - function __embind_register_class_constructor( - rawClassType, - argCount, - rawArgTypesAddr, - invokerSignature, - invoker, - rawConstructor - ) { - assert(argCount > 0); - var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); - invoker = embind__requireFunction(invokerSignature, invoker); - whenDependentTypesAreResolved( - [], - [rawClassType], - function (classType) { - classType = classType[0]; - var humanName = `constructor ${classType.name}`; - if ( - undefined === classType.registeredClass.constructor_body - ) { - classType.registeredClass.constructor_body = []; - } - if ( - undefined !== - classType.registeredClass.constructor_body[argCount - 1] - ) { - throw new BindingError( - `Cannot register multiple constructors with identical number of parameters (${ - argCount - 1 - }) for class '${ - classType.name - }'! Overload resolution is currently only performed using the parameter count, not actual type info!` - ); - } - classType.registeredClass.constructor_body[argCount - 1] = - () => { - throwUnboundTypeError( - `Cannot construct ${classType.name} due to unbound types`, - rawArgTypes - ); - }; - whenDependentTypesAreResolved( - [], - rawArgTypes, - function (argTypes) { - argTypes.splice(1, 0, null); - classType.registeredClass.constructor_body[ - argCount - 1 - ] = craftInvokerFunction( - humanName, - argTypes, - null, - invoker, - rawConstructor - ); - return []; - } - ); - return []; - } - ); - } - function __embind_register_class_function( - rawClassType, - methodName, - argCount, - rawArgTypesAddr, - invokerSignature, - rawInvoker, - context, - isPureVirtual, - isAsync - ) { - var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); - methodName = readLatin1String(methodName); - rawInvoker = embind__requireFunction(invokerSignature, rawInvoker); - whenDependentTypesAreResolved( - [], - [rawClassType], - function (classType) { - classType = classType[0]; - var humanName = `${classType.name}.${methodName}`; - if (methodName.startsWith('@@')) { - methodName = Symbol[methodName.substring(2)]; - } - if (isPureVirtual) { - classType.registeredClass.pureVirtualFunctions.push( - methodName - ); - } - function unboundTypesHandler() { - throwUnboundTypeError( - `Cannot call ${humanName} due to unbound types`, - rawArgTypes - ); - } - var proto = classType.registeredClass.instancePrototype; - var method = proto[methodName]; - if ( - undefined === method || - (undefined === method.overloadTable && - method.className !== classType.name && - method.argCount === argCount - 2) - ) { - unboundTypesHandler.argCount = argCount - 2; - unboundTypesHandler.className = classType.name; - proto[methodName] = unboundTypesHandler; - } else { - ensureOverloadTable(proto, methodName, humanName); - proto[methodName].overloadTable[argCount - 2] = - unboundTypesHandler; - } - whenDependentTypesAreResolved( - [], - rawArgTypes, - function (argTypes) { - var memberFunction = craftInvokerFunction( - humanName, - argTypes, - classType, - rawInvoker, - context, - isAsync - ); - if (undefined === proto[methodName].overloadTable) { - memberFunction.argCount = argCount - 2; - proto[methodName] = memberFunction; - } else { - proto[methodName].overloadTable[argCount - 2] = - memberFunction; - } - return []; - } - ); - return []; - } - ); - } - function handleAllocatorInit() { - Object.assign(HandleAllocator.prototype, { - get(id) { - assert( - this.allocated[id] !== undefined, - `invalid handle: ${id}` - ); - return this.allocated[id]; - }, - has(id) { - return this.allocated[id] !== undefined; - }, - allocate(handle) { - var id = this.freelist.pop() || this.allocated.length; - this.allocated[id] = handle; - return id; - }, - free(id) { - assert(this.allocated[id] !== undefined); - this.allocated[id] = undefined; - this.freelist.push(id); - }, - }); - } - function HandleAllocator() { - this.allocated = [undefined]; - this.freelist = []; - } - var emval_handles = new HandleAllocator(); - function __emval_decref(handle) { - if ( - handle >= emval_handles.reserved && - 0 === --emval_handles.get(handle).refcount - ) { - emval_handles.free(handle); - } - } - function count_emval_handles() { - var count = 0; - for ( - var i = emval_handles.reserved; - i < emval_handles.allocated.length; - ++i - ) { - if (emval_handles.allocated[i] !== undefined) { - ++count; - } - } - return count; - } - function init_emval() { - emval_handles.allocated.push( - { value: undefined }, - { value: null }, - { value: true }, - { value: false } - ); - emval_handles.reserved = emval_handles.allocated.length; - Module['count_emval_handles'] = count_emval_handles; - } - var Emval = { - toValue: (handle) => { - if (!handle) { - throwBindingError( - 'Cannot use deleted val. handle = ' + handle - ); - } - return emval_handles.get(handle).value; - }, - toHandle: (value) => { - switch (value) { - case undefined: - return 1; - case null: - return 2; - case true: - return 3; - case false: - return 4; - default: { - return emval_handles.allocate({ - refcount: 1, - value: value, - }); - } - } - }, - }; - function __embind_register_emval(rawType, name) { - name = readLatin1String(name); - registerType(rawType, { - name: name, - fromWireType: function (handle) { - var rv = Emval.toValue(handle); - __emval_decref(handle); - return rv; - }, - toWireType: function (destructors, value) { - return Emval.toHandle(value); - }, - argPackAdvance: 8, - readValueFromPointer: simpleReadValueFromPointer, - destructorFunction: null, - }); - } - function embindRepr(v) { - if (v === null) { - return 'null'; - } - var t = typeof v; - if (t === 'object' || t === 'array' || t === 'function') { - return v.toString(); - } else { - return '' + v; - } - } - function floatReadValueFromPointer(name, shift) { - switch (shift) { - case 2: - return function (pointer) { - return this['fromWireType'](HEAPF32[pointer >> 2]); - }; - case 3: - return function (pointer) { - return this['fromWireType'](HEAPF64[pointer >> 3]); - }; - default: - throw new TypeError('Unknown float type: ' + name); - } - } - function __embind_register_float(rawType, name, size) { - var shift = getShiftFromSize(size); - name = readLatin1String(name); - registerType(rawType, { - name: name, - fromWireType: function (value) { - return value; - }, - toWireType: function (destructors, value) { - if (typeof value != 'number' && typeof value != 'boolean') { - throw new TypeError( - `Cannot convert ${embindRepr(value)} to ${ - this.name - }` - ); - } - return value; - }, - argPackAdvance: 8, - readValueFromPointer: floatReadValueFromPointer(name, shift), - destructorFunction: null, - }); - } - function __embind_register_function( - name, - argCount, - rawArgTypesAddr, - signature, - rawInvoker, - fn, - isAsync - ) { - var argTypes = heap32VectorToArray(argCount, rawArgTypesAddr); - name = readLatin1String(name); - rawInvoker = embind__requireFunction(signature, rawInvoker); - exposePublicSymbol( - name, - function () { - throwUnboundTypeError( - `Cannot call ${name} due to unbound types`, - argTypes - ); - }, - argCount - 1 - ); - whenDependentTypesAreResolved([], argTypes, function (argTypes) { - var invokerArgsArray = [argTypes[0], null].concat( - argTypes.slice(1) - ); - replacePublicSymbol( - name, - craftInvokerFunction( - name, - invokerArgsArray, - null, - rawInvoker, - fn, - isAsync - ), - argCount - 1 - ); - return []; - }); - } - function integerReadValueFromPointer(name, shift, signed) { - switch (shift) { - case 0: - return signed - ? function readS8FromPointer(pointer) { - return HEAP8[pointer]; - } - : function readU8FromPointer(pointer) { - return HEAPU8[pointer]; - }; - case 1: - return signed - ? function readS16FromPointer(pointer) { - return HEAP16[pointer >> 1]; - } - : function readU16FromPointer(pointer) { - return HEAPU16[pointer >> 1]; - }; - case 2: - return signed - ? function readS32FromPointer(pointer) { - return HEAP32[pointer >> 2]; - } - : function readU32FromPointer(pointer) { - return HEAPU32[pointer >> 2]; - }; - default: - throw new TypeError('Unknown integer type: ' + name); - } - } - function __embind_register_integer( - primitiveType, - name, - size, - minRange, - maxRange - ) { - name = readLatin1String(name); - if (maxRange === -1) { - maxRange = 4294967295; - } - var shift = getShiftFromSize(size); - var fromWireType = (value) => value; - if (minRange === 0) { - var bitshift = 32 - 8 * size; - fromWireType = (value) => (value << bitshift) >>> bitshift; - } - var isUnsignedType = name.includes('unsigned'); - var checkAssertions = (value, toTypeName) => { - if (typeof value != 'number' && typeof value != 'boolean') { - throw new TypeError( - `Cannot convert "${embindRepr(value)}" to ${toTypeName}` - ); - } - if (value < minRange || value > maxRange) { - throw new TypeError( - `Passing a number "${embindRepr( - value - )}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!` - ); - } - }; - var toWireType; - if (isUnsignedType) { - toWireType = function (destructors, value) { - checkAssertions(value, this.name); - return value >>> 0; - }; - } else { - toWireType = function (destructors, value) { - checkAssertions(value, this.name); - return value; - }; - } - registerType(primitiveType, { - name: name, - fromWireType: fromWireType, - toWireType: toWireType, - argPackAdvance: 8, - readValueFromPointer: integerReadValueFromPointer( - name, - shift, - minRange !== 0 - ), - destructorFunction: null, - }); - } - function __embind_register_memory_view(rawType, dataTypeIndex, name) { - var typeMapping = [ - Int8Array, - Uint8Array, - Int16Array, - Uint16Array, - Int32Array, - Uint32Array, - Float32Array, - Float64Array, - ]; - var TA = typeMapping[dataTypeIndex]; - function decodeMemoryView(handle) { - handle = handle >> 2; - var heap = HEAPU32; - var size = heap[handle]; - var data = heap[handle + 1]; - return new TA(heap.buffer, data, size); - } - name = readLatin1String(name); - registerType( - rawType, - { - name: name, - fromWireType: decodeMemoryView, - argPackAdvance: 8, - readValueFromPointer: decodeMemoryView, - }, - { ignoreDuplicateRegistrations: true } - ); - } - var stringToUTF8 = (str, outPtr, maxBytesToWrite) => { - assert( - typeof maxBytesToWrite == 'number', - 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!' - ); - return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite); - }; - function __embind_register_std_string(rawType, name) { - name = readLatin1String(name); - var stdStringIsUTF8 = name === 'std::string'; - registerType(rawType, { - name: name, - fromWireType: function (value) { - var length = HEAPU32[value >> 2]; - var payload = value + 4; - var str; - if (stdStringIsUTF8) { - var decodeStartPtr = payload; - for (var i = 0; i <= length; ++i) { - var currentBytePtr = payload + i; - if (i == length || HEAPU8[currentBytePtr] == 0) { - var maxRead = currentBytePtr - decodeStartPtr; - var stringSegment = UTF8ToString( - decodeStartPtr, - maxRead - ); - if (str === undefined) { - str = stringSegment; - } else { - str += String.fromCharCode(0); - str += stringSegment; - } - decodeStartPtr = currentBytePtr + 1; - } - } - } else { - var a = new Array(length); - for (var i = 0; i < length; ++i) { - a[i] = String.fromCharCode(HEAPU8[payload + i]); - } - str = a.join(''); - } - _free(value); - return str; - }, - toWireType: function (destructors, value) { - if (value instanceof ArrayBuffer) { - value = new Uint8Array(value); - } - var length; - var valueIsOfTypeString = typeof value == 'string'; - if ( - !( - valueIsOfTypeString || - value instanceof Uint8Array || - value instanceof Uint8ClampedArray || - value instanceof Int8Array - ) - ) { - throwBindingError( - 'Cannot pass non-string to std::string' - ); - } - if (stdStringIsUTF8 && valueIsOfTypeString) { - length = lengthBytesUTF8(value); - } else { - length = value.length; - } - var base = _malloc(4 + length + 1); - var ptr = base + 4; - HEAPU32[base >> 2] = length; - checkInt32(length); - if (stdStringIsUTF8 && valueIsOfTypeString) { - stringToUTF8(value, ptr, length + 1); - } else { - if (valueIsOfTypeString) { - for (var i = 0; i < length; ++i) { - var charCode = value.charCodeAt(i); - if (charCode > 255) { - _free(ptr); - throwBindingError( - 'String has UTF-16 code units that do not fit in 8 bits' - ); - } - HEAPU8[ptr + i] = charCode; - } - } else { - for (var i = 0; i < length; ++i) { - HEAPU8[ptr + i] = value[i]; - } - } - } - if (destructors !== null) { - destructors.push(_free, base); - } - return base; - }, - argPackAdvance: 8, - readValueFromPointer: simpleReadValueFromPointer, - destructorFunction: function (ptr) { - _free(ptr); - }, - }); - } - var UTF16Decoder = - typeof TextDecoder != 'undefined' - ? new TextDecoder('utf-16le') - : undefined; - var UTF16ToString = (ptr, maxBytesToRead) => { - assert( - ptr % 2 == 0, - 'Pointer passed to UTF16ToString must be aligned to two bytes!' - ); - var endPtr = ptr; - var idx = endPtr >> 1; - var maxIdx = idx + maxBytesToRead / 2; - while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx; - endPtr = idx << 1; - if (endPtr - ptr > 32 && UTF16Decoder) - return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr)); - var str = ''; - for (var i = 0; !(i >= maxBytesToRead / 2); ++i) { - var codeUnit = HEAP16[(ptr + i * 2) >> 1]; - if (codeUnit == 0) break; - str += String.fromCharCode(codeUnit); - } - return str; - }; - var stringToUTF16 = (str, outPtr, maxBytesToWrite) => { - assert( - outPtr % 2 == 0, - 'Pointer passed to stringToUTF16 must be aligned to two bytes!' - ); - assert( - typeof maxBytesToWrite == 'number', - 'stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!' - ); - if (maxBytesToWrite === undefined) { - maxBytesToWrite = 2147483647; - } - if (maxBytesToWrite < 2) return 0; - maxBytesToWrite -= 2; - var startPtr = outPtr; - var numCharsToWrite = - maxBytesToWrite < str.length * 2 - ? maxBytesToWrite / 2 - : str.length; - for (var i = 0; i < numCharsToWrite; ++i) { - var codeUnit = str.charCodeAt(i); - HEAP16[outPtr >> 1] = codeUnit; - checkInt16(codeUnit); - outPtr += 2; - } - HEAP16[outPtr >> 1] = 0; - checkInt16(0); - return outPtr - startPtr; - }; - var lengthBytesUTF16 = (str) => str.length * 2; - var UTF32ToString = (ptr, maxBytesToRead) => { - assert( - ptr % 4 == 0, - 'Pointer passed to UTF32ToString must be aligned to four bytes!' - ); - var i = 0; - var str = ''; - while (!(i >= maxBytesToRead / 4)) { - var utf32 = HEAP32[(ptr + i * 4) >> 2]; - if (utf32 == 0) break; - ++i; - if (utf32 >= 65536) { - var ch = utf32 - 65536; - str += String.fromCharCode( - 55296 | (ch >> 10), - 56320 | (ch & 1023) - ); - } else { - str += String.fromCharCode(utf32); - } - } - return str; - }; - var stringToUTF32 = (str, outPtr, maxBytesToWrite) => { - assert( - outPtr % 4 == 0, - 'Pointer passed to stringToUTF32 must be aligned to four bytes!' - ); - assert( - typeof maxBytesToWrite == 'number', - 'stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!' - ); - if (maxBytesToWrite === undefined) { - maxBytesToWrite = 2147483647; - } - if (maxBytesToWrite < 4) return 0; - var startPtr = outPtr; - var endPtr = startPtr + maxBytesToWrite - 4; - for (var i = 0; i < str.length; ++i) { - var codeUnit = str.charCodeAt(i); - if (codeUnit >= 55296 && codeUnit <= 57343) { - var trailSurrogate = str.charCodeAt(++i); - codeUnit = - (65536 + ((codeUnit & 1023) << 10)) | - (trailSurrogate & 1023); - } - HEAP32[outPtr >> 2] = codeUnit; - checkInt32(codeUnit); - outPtr += 4; - if (outPtr + 4 > endPtr) break; - } - HEAP32[outPtr >> 2] = 0; - checkInt32(0); - return outPtr - startPtr; - }; - var lengthBytesUTF32 = (str) => { - var len = 0; - for (var i = 0; i < str.length; ++i) { - var codeUnit = str.charCodeAt(i); - if (codeUnit >= 55296 && codeUnit <= 57343) ++i; - len += 4; - } - return len; - }; - var __embind_register_std_wstring = function (rawType, charSize, name) { - name = readLatin1String(name); - var decodeString, encodeString, getHeap, lengthBytesUTF, shift; - if (charSize === 2) { - decodeString = UTF16ToString; - encodeString = stringToUTF16; - lengthBytesUTF = lengthBytesUTF16; - getHeap = () => HEAPU16; - shift = 1; - } else if (charSize === 4) { - decodeString = UTF32ToString; - encodeString = stringToUTF32; - lengthBytesUTF = lengthBytesUTF32; - getHeap = () => HEAPU32; - shift = 2; - } - registerType(rawType, { - name: name, - fromWireType: function (value) { - var length = HEAPU32[value >> 2]; - var HEAP = getHeap(); - var str; - var decodeStartPtr = value + 4; - for (var i = 0; i <= length; ++i) { - var currentBytePtr = value + 4 + i * charSize; - if (i == length || HEAP[currentBytePtr >> shift] == 0) { - var maxReadBytes = currentBytePtr - decodeStartPtr; - var stringSegment = decodeString( - decodeStartPtr, - maxReadBytes - ); - if (str === undefined) { - str = stringSegment; - } else { - str += String.fromCharCode(0); - str += stringSegment; - } - decodeStartPtr = currentBytePtr + charSize; - } - } - _free(value); - return str; - }, - toWireType: function (destructors, value) { - if (!(typeof value == 'string')) { - throwBindingError( - `Cannot pass non-string to C++ string type ${name}` - ); - } - var length = lengthBytesUTF(value); - var ptr = _malloc(4 + length + charSize); - HEAPU32[ptr >> 2] = length >> shift; - encodeString(value, ptr + 4, length + charSize); - if (destructors !== null) { - destructors.push(_free, ptr); - } - return ptr; - }, - argPackAdvance: 8, - readValueFromPointer: simpleReadValueFromPointer, - destructorFunction: function (ptr) { - _free(ptr); - }, - }); - }; - function __embind_register_value_object( - rawType, - name, - constructorSignature, - rawConstructor, - destructorSignature, - rawDestructor - ) { - structRegistrations[rawType] = { - name: readLatin1String(name), - rawConstructor: embind__requireFunction( - constructorSignature, - rawConstructor - ), - rawDestructor: embind__requireFunction( - destructorSignature, - rawDestructor - ), - fields: [], - }; - } - function __embind_register_value_object_field( - structType, - fieldName, - getterReturnType, - getterSignature, - getter, - getterContext, - setterArgumentType, - setterSignature, - setter, - setterContext - ) { - structRegistrations[structType].fields.push({ - fieldName: readLatin1String(fieldName), - getterReturnType: getterReturnType, - getter: embind__requireFunction(getterSignature, getter), - getterContext: getterContext, - setterArgumentType: setterArgumentType, - setter: embind__requireFunction(setterSignature, setter), - setterContext: setterContext, - }); - } - function __embind_register_void(rawType, name) { - name = readLatin1String(name); - registerType(rawType, { - isVoid: true, - name: name, - argPackAdvance: 0, - fromWireType: function () { - return undefined; - }, - toWireType: function (destructors, o) { - return undefined; - }, - }); - } - function __emval_incref(handle) { - if (handle > 4) { - emval_handles.get(handle).refcount += 1; - } - } - function requireRegisteredType(rawType, humanName) { - var impl = registeredTypes[rawType]; - if (undefined === impl) { - throwBindingError( - humanName + ' has unknown type ' + getTypeName(rawType) - ); - } - return impl; - } - function __emval_take_value(type, arg) { - type = requireRegisteredType(type, '_emval_take_value'); - var v = type['readValueFromPointer'](arg); - return Emval.toHandle(v); - } - function convertI32PairToI53Checked(lo, hi) { - assert(lo == lo >>> 0 || lo == (lo | 0)); - assert(hi === (hi | 0)); - return (hi + 2097152) >>> 0 < 4194305 - !!lo - ? (lo >>> 0) + hi * 4294967296 - : NaN; - } - function __mmap_js( - len, - prot, - flags, - fd, - offset_low, - offset_high, - allocated, - addr - ) { - var offset = convertI32PairToI53Checked(offset_low, offset_high); - try { - if (isNaN(offset)) return 61; - var stream = SYSCALLS.getStreamFromFD(fd); - var res = FS.mmap(stream, len, offset, prot, flags); - var ptr = res.ptr; - HEAP32[allocated >> 2] = res.allocated; - checkInt32(res.allocated); - HEAPU32[addr >> 2] = ptr; - return 0; - } catch (e) { - if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) - throw e; - return -e.errno; - } - } - function __munmap_js( - addr, - len, - prot, - flags, - fd, - offset_low, - offset_high - ) { - var offset = convertI32PairToI53Checked(offset_low, offset_high); - try { - if (isNaN(offset)) return 61; - var stream = SYSCALLS.getStreamFromFD(fd); - if (prot & 2) { - SYSCALLS.doMsync(addr, stream, len, flags, offset); - } - FS.munmap(stream); - } catch (e) { - if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) - throw e; - return -e.errno; - } - } - var _abort = () => { - abort('native code called abort()'); - }; - var _emscripten_memcpy_big = (dest, src, num) => - HEAPU8.copyWithin(dest, src, src + num); - var getHeapMax = () => 2147483648; - var _emscripten_get_now; - _emscripten_get_now = () => performance.now(); - var growMemory = (size) => { - var b = wasmMemory.buffer; - var pages = (size - b.byteLength + 65535) >>> 16; - try { - wasmMemory.grow(pages); - updateMemoryViews(); - return 1; - } catch (e) { - err( - `growMemory: Attempted to grow heap from ${b.byteLength} bytes to ${size} bytes, but got error: ${e}` - ); - } - }; - var _emscripten_resize_heap = (requestedSize) => { - var oldSize = HEAPU8.length; - requestedSize >>>= 0; - assert(requestedSize > oldSize); - var maxHeapSize = getHeapMax(); - if (requestedSize > maxHeapSize) { - err( - `Cannot enlarge memory, asked to go up to ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!` - ); - return false; - } - var alignUp = (x, multiple) => - x + ((multiple - (x % multiple)) % multiple); - for (var cutDown = 1; cutDown <= 4; cutDown *= 2) { - var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); - overGrownHeapSize = Math.min( - overGrownHeapSize, - requestedSize + 100663296 - ); - var newSize = Math.min( - maxHeapSize, - alignUp(Math.max(requestedSize, overGrownHeapSize), 65536) - ); - var t0 = _emscripten_get_now(); - var replacement = growMemory(newSize); - var t1 = _emscripten_get_now(); - out( - `Heap resize call from ${oldSize} to ${newSize} took ${ - t1 - t0 - } msecs. Success: ${!!replacement}` - ); - if (replacement) { - return true; - } - } - err( - `Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!` - ); - return false; - }; - var ENV = {}; - var getExecutableName = () => thisProgram || './this.program'; - var getEnvStrings = () => { - if (!getEnvStrings.strings) { - var lang = - ( - (typeof navigator == 'object' && - navigator.languages && - navigator.languages[0]) || - 'C' - ).replace('-', '_') + '.UTF-8'; - var env = { - USER: 'web_user', - LOGNAME: 'web_user', - PATH: '/', - PWD: '/', - HOME: '/home/web_user', - LANG: lang, - _: getExecutableName(), - }; - for (var x in ENV) { - if (ENV[x] === undefined) delete env[x]; - else env[x] = ENV[x]; - } - var strings = []; - for (var x in env) { - strings.push(`${x}=${env[x]}`); - } - getEnvStrings.strings = strings; - } - return getEnvStrings.strings; - }; - var stringToAscii = (str, buffer) => { - for (var i = 0; i < str.length; ++i) { - assert(str.charCodeAt(i) === (str.charCodeAt(i) & 255)); - HEAP8[buffer++ >> 0] = str.charCodeAt(i); - checkInt8(str.charCodeAt(i)); - } - HEAP8[buffer >> 0] = 0; - checkInt8(0); - }; - var _environ_get = (__environ, environ_buf) => { - var bufSize = 0; - getEnvStrings().forEach(function (string, i) { - var ptr = environ_buf + bufSize; - HEAPU32[(__environ + i * 4) >> 2] = ptr; - checkInt32(ptr); - stringToAscii(string, ptr); - bufSize += string.length + 1; - }); - return 0; - }; - var _environ_sizes_get = (penviron_count, penviron_buf_size) => { - var strings = getEnvStrings(); - HEAPU32[penviron_count >> 2] = strings.length; - checkInt32(strings.length); - var bufSize = 0; - strings.forEach(function (string) { - bufSize += string.length + 1; - }); - HEAPU32[penviron_buf_size >> 2] = bufSize; - checkInt32(bufSize); - return 0; - }; - function _fd_close(fd) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - FS.close(stream); - return 0; - } catch (e) { - if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) - throw e; - return e.errno; - } - } - var doReadv = (stream, iov, iovcnt, offset) => { - var ret = 0; - for (var i = 0; i < iovcnt; i++) { - var ptr = HEAPU32[iov >> 2]; - var len = HEAPU32[(iov + 4) >> 2]; - iov += 8; - var curr = FS.read(stream, HEAP8, ptr, len, offset); - if (curr < 0) return -1; - ret += curr; - if (curr < len) break; - if (typeof offset !== 'undefined') { - offset += curr; - } - } - return ret; - }; - function _fd_read(fd, iov, iovcnt, pnum) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var num = doReadv(stream, iov, iovcnt); - HEAPU32[pnum >> 2] = num; - checkInt32(num); - return 0; - } catch (e) { - if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) - throw e; - return e.errno; - } - } - function _fd_seek(fd, offset_low, offset_high, whence, newOffset) { - var offset = convertI32PairToI53Checked(offset_low, offset_high); - try { - if (isNaN(offset)) return 61; - var stream = SYSCALLS.getStreamFromFD(fd); - FS.llseek(stream, offset, whence); - (tempI64 = [ - stream.position >>> 0, - ((tempDouble = stream.position), - +Math.abs(tempDouble) >= 1 - ? tempDouble > 0 - ? +Math.floor(tempDouble / 4294967296) >>> 0 - : ~~+Math.ceil( - (tempDouble - +(~~tempDouble >>> 0)) / - 4294967296 - ) >>> 0 - : 0), - ]), - (HEAP32[newOffset >> 2] = tempI64[0]), - (HEAP32[(newOffset + 4) >> 2] = tempI64[1]); - checkInt64(stream.position); - if (stream.getdents && offset === 0 && whence === 0) - stream.getdents = null; - return 0; - } catch (e) { - if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) - throw e; - return e.errno; - } - } - var doWritev = (stream, iov, iovcnt, offset) => { - var ret = 0; - for (var i = 0; i < iovcnt; i++) { - var ptr = HEAPU32[iov >> 2]; - var len = HEAPU32[(iov + 4) >> 2]; - iov += 8; - var curr = FS.write(stream, HEAP8, ptr, len, offset); - if (curr < 0) return -1; - ret += curr; - if (typeof offset !== 'undefined') { - offset += curr; - } - } - return ret; - }; - function _fd_write(fd, iov, iovcnt, pnum) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var num = doWritev(stream, iov, iovcnt); - HEAPU32[pnum >> 2] = num; - checkInt32(num); - return 0; - } catch (e) { - if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) - throw e; - return e.errno; - } - } - var isLeapYear = (year) => - year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0); - var arraySum = (array, index) => { - var sum = 0; - for (var i = 0; i <= index; sum += array[i++]) {} - return sum; - }; - var MONTH_DAYS_LEAP = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; - var MONTH_DAYS_REGULAR = [ - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, - ]; - var addDays = (date, days) => { - var newDate = new Date(date.getTime()); - while (days > 0) { - var leap = isLeapYear(newDate.getFullYear()); - var currentMonth = newDate.getMonth(); - var daysInCurrentMonth = ( - leap ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR - )[currentMonth]; - if (days > daysInCurrentMonth - newDate.getDate()) { - days -= daysInCurrentMonth - newDate.getDate() + 1; - newDate.setDate(1); - if (currentMonth < 11) { - newDate.setMonth(currentMonth + 1); - } else { - newDate.setMonth(0); - newDate.setFullYear(newDate.getFullYear() + 1); - } - } else { - newDate.setDate(newDate.getDate() + days); - return newDate; - } - } - return newDate; - }; - var writeArrayToMemory = (array, buffer) => { - assert( - array.length >= 0, - 'writeArrayToMemory array must have a length (should be an array or typed array)' - ); - HEAP8.set(array, buffer); - }; - var _strftime = (s, maxsize, format, tm) => { - var tm_zone = HEAP32[(tm + 40) >> 2]; - var date = { - tm_sec: HEAP32[tm >> 2], - tm_min: HEAP32[(tm + 4) >> 2], - tm_hour: HEAP32[(tm + 8) >> 2], - tm_mday: HEAP32[(tm + 12) >> 2], - tm_mon: HEAP32[(tm + 16) >> 2], - tm_year: HEAP32[(tm + 20) >> 2], - tm_wday: HEAP32[(tm + 24) >> 2], - tm_yday: HEAP32[(tm + 28) >> 2], - tm_isdst: HEAP32[(tm + 32) >> 2], - tm_gmtoff: HEAP32[(tm + 36) >> 2], - tm_zone: tm_zone ? UTF8ToString(tm_zone) : '', - }; - var pattern = UTF8ToString(format); - var EXPANSION_RULES_1 = { - '%c': '%a %b %d %H:%M:%S %Y', - '%D': '%m/%d/%y', - '%F': '%Y-%m-%d', - '%h': '%b', - '%r': '%I:%M:%S %p', - '%R': '%H:%M', - '%T': '%H:%M:%S', - '%x': '%m/%d/%y', - '%X': '%H:%M:%S', - '%Ec': '%c', - '%EC': '%C', - '%Ex': '%m/%d/%y', - '%EX': '%H:%M:%S', - '%Ey': '%y', - '%EY': '%Y', - '%Od': '%d', - '%Oe': '%e', - '%OH': '%H', - '%OI': '%I', - '%Om': '%m', - '%OM': '%M', - '%OS': '%S', - '%Ou': '%u', - '%OU': '%U', - '%OV': '%V', - '%Ow': '%w', - '%OW': '%W', - '%Oy': '%y', - }; - for (var rule in EXPANSION_RULES_1) { - pattern = pattern.replace( - new RegExp(rule, 'g'), - EXPANSION_RULES_1[rule] - ); - } - var WEEKDAYS = [ - 'Sunday', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday', - ]; - var MONTHS = [ - 'January', - 'February', - 'March', - 'April', - 'May', - 'June', - 'July', - 'August', - 'September', - 'October', - 'November', - 'December', - ]; - function leadingSomething(value, digits, character) { - var str = - typeof value == 'number' ? value.toString() : value || ''; - while (str.length < digits) { - str = character[0] + str; - } - return str; - } - function leadingNulls(value, digits) { - return leadingSomething(value, digits, '0'); - } - function compareByDay(date1, date2) { - function sgn(value) { - return value < 0 ? -1 : value > 0 ? 1 : 0; - } - var compare; - if ( - (compare = sgn( - date1.getFullYear() - date2.getFullYear() - )) === 0 - ) { - if ( - (compare = sgn(date1.getMonth() - date2.getMonth())) === - 0 - ) { - compare = sgn(date1.getDate() - date2.getDate()); - } - } - return compare; - } - function getFirstWeekStartDate(janFourth) { - switch (janFourth.getDay()) { - case 0: - return new Date(janFourth.getFullYear() - 1, 11, 29); - case 1: - return janFourth; - case 2: - return new Date(janFourth.getFullYear(), 0, 3); - case 3: - return new Date(janFourth.getFullYear(), 0, 2); - case 4: - return new Date(janFourth.getFullYear(), 0, 1); - case 5: - return new Date(janFourth.getFullYear() - 1, 11, 31); - case 6: - return new Date(janFourth.getFullYear() - 1, 11, 30); - } - } - function getWeekBasedYear(date) { - var thisDate = addDays( - new Date(date.tm_year + 1900, 0, 1), - date.tm_yday - ); - var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4); - var janFourthNextYear = new Date( - thisDate.getFullYear() + 1, - 0, - 4 - ); - var firstWeekStartThisYear = - getFirstWeekStartDate(janFourthThisYear); - var firstWeekStartNextYear = - getFirstWeekStartDate(janFourthNextYear); - if (compareByDay(firstWeekStartThisYear, thisDate) <= 0) { - if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) { - return thisDate.getFullYear() + 1; - } - return thisDate.getFullYear(); - } - return thisDate.getFullYear() - 1; - } - var EXPANSION_RULES_2 = { - '%a': (date) => WEEKDAYS[date.tm_wday].substring(0, 3), - '%A': (date) => WEEKDAYS[date.tm_wday], - '%b': (date) => MONTHS[date.tm_mon].substring(0, 3), - '%B': (date) => MONTHS[date.tm_mon], - '%C': (date) => { - var year = date.tm_year + 1900; - return leadingNulls((year / 100) | 0, 2); - }, - '%d': (date) => leadingNulls(date.tm_mday, 2), - '%e': (date) => leadingSomething(date.tm_mday, 2, ' '), - '%g': (date) => getWeekBasedYear(date).toString().substring(2), - '%G': (date) => getWeekBasedYear(date), - '%H': (date) => leadingNulls(date.tm_hour, 2), - '%I': (date) => { - var twelveHour = date.tm_hour; - if (twelveHour == 0) twelveHour = 12; - else if (twelveHour > 12) twelveHour -= 12; - return leadingNulls(twelveHour, 2); - }, - '%j': (date) => - leadingNulls( - date.tm_mday + - arraySum( - isLeapYear(date.tm_year + 1900) - ? MONTH_DAYS_LEAP - : MONTH_DAYS_REGULAR, - date.tm_mon - 1 - ), - 3 - ), - '%m': (date) => leadingNulls(date.tm_mon + 1, 2), - '%M': (date) => leadingNulls(date.tm_min, 2), - '%n': () => '\n', - '%p': (date) => { - if (date.tm_hour >= 0 && date.tm_hour < 12) { - return 'AM'; - } - return 'PM'; - }, - '%S': (date) => leadingNulls(date.tm_sec, 2), - '%t': () => '\t', - '%u': (date) => date.tm_wday || 7, - '%U': (date) => { - var days = date.tm_yday + 7 - date.tm_wday; - return leadingNulls(Math.floor(days / 7), 2); - }, - '%V': (date) => { - var val = Math.floor( - (date.tm_yday + 7 - ((date.tm_wday + 6) % 7)) / 7 - ); - if ((date.tm_wday + 371 - date.tm_yday - 2) % 7 <= 2) { - val++; - } - if (!val) { - val = 52; - var dec31 = (date.tm_wday + 7 - date.tm_yday - 1) % 7; - if ( - dec31 == 4 || - (dec31 == 5 && isLeapYear((date.tm_year % 400) - 1)) - ) { - val++; - } - } else if (val == 53) { - var jan1 = (date.tm_wday + 371 - date.tm_yday) % 7; - if ( - jan1 != 4 && - (jan1 != 3 || !isLeapYear(date.tm_year)) - ) - val = 1; - } - return leadingNulls(val, 2); - }, - '%w': (date) => date.tm_wday, - '%W': (date) => { - var days = date.tm_yday + 7 - ((date.tm_wday + 6) % 7); - return leadingNulls(Math.floor(days / 7), 2); - }, - '%y': (date) => (date.tm_year + 1900).toString().substring(2), - '%Y': (date) => date.tm_year + 1900, - '%z': (date) => { - var off = date.tm_gmtoff; - var ahead = off >= 0; - off = Math.abs(off) / 60; - off = (off / 60) * 100 + (off % 60); - return (ahead ? '+' : '-') + String('0000' + off).slice(-4); - }, - '%Z': (date) => date.tm_zone, - '%%': () => '%', - }; - pattern = pattern.replace(/%%/g, '\0\0'); - for (var rule in EXPANSION_RULES_2) { - if (pattern.includes(rule)) { - pattern = pattern.replace( - new RegExp(rule, 'g'), - EXPANSION_RULES_2[rule](date) - ); - } - } - pattern = pattern.replace(/\0\0/g, '%'); - var bytes = intArrayFromString(pattern, false); - if (bytes.length > maxsize) { - return 0; - } - writeArrayToMemory(bytes, s); - return bytes.length - 1; - }; - var _strftime_l = (s, maxsize, format, tm, loc) => - _strftime(s, maxsize, format, tm); - var FSNode = function (parent, name, mode, rdev) { - if (!parent) { - parent = this; - } - this.parent = parent; - this.mount = parent.mount; - this.mounted = null; - this.id = FS.nextInode++; - this.name = name; - this.mode = mode; - this.node_ops = {}; - this.stream_ops = {}; - this.rdev = rdev; - }; - var readMode = 292 | 73; - var writeMode = 146; - Object.defineProperties(FSNode.prototype, { - read: { - get: function () { - return (this.mode & readMode) === readMode; - }, - set: function (val) { - val ? (this.mode |= readMode) : (this.mode &= ~readMode); - }, - }, - write: { - get: function () { - return (this.mode & writeMode) === writeMode; - }, - set: function (val) { - val ? (this.mode |= writeMode) : (this.mode &= ~writeMode); - }, - }, - isFolder: { - get: function () { - return FS.isDir(this.mode); - }, - }, - isDevice: { - get: function () { - return FS.isChrdev(this.mode); - }, - }, - }); - FS.FSNode = FSNode; - FS.createPreloadedFile = FS_createPreloadedFile; - FS.staticInit(); - Module['FS_createPath'] = FS.createPath; - Module['FS_createDataFile'] = FS.createDataFile; - Module['FS_createPreloadedFile'] = FS.createPreloadedFile; - Module['FS_unlink'] = FS.unlink; - Module['FS_createLazyFile'] = FS.createLazyFile; - Module['FS_createDevice'] = FS.createDevice; - if (ENVIRONMENT_IS_NODE) { - NODEFS.staticInit(); - } - ERRNO_CODES = { - EPERM: 63, - ENOENT: 44, - ESRCH: 71, - EINTR: 27, - EIO: 29, - ENXIO: 60, - E2BIG: 1, - ENOEXEC: 45, - EBADF: 8, - ECHILD: 12, - EAGAIN: 6, - EWOULDBLOCK: 6, - ENOMEM: 48, - EACCES: 2, - EFAULT: 21, - ENOTBLK: 105, - EBUSY: 10, - EEXIST: 20, - EXDEV: 75, - ENODEV: 43, - ENOTDIR: 54, - EISDIR: 31, - EINVAL: 28, - ENFILE: 41, - EMFILE: 33, - ENOTTY: 59, - ETXTBSY: 74, - EFBIG: 22, - ENOSPC: 51, - ESPIPE: 70, - EROFS: 69, - EMLINK: 34, - EPIPE: 64, - EDOM: 18, - ERANGE: 68, - ENOMSG: 49, - EIDRM: 24, - ECHRNG: 106, - EL2NSYNC: 156, - EL3HLT: 107, - EL3RST: 108, - ELNRNG: 109, - EUNATCH: 110, - ENOCSI: 111, - EL2HLT: 112, - EDEADLK: 16, - ENOLCK: 46, - EBADE: 113, - EBADR: 114, - EXFULL: 115, - ENOANO: 104, - EBADRQC: 103, - EBADSLT: 102, - EDEADLOCK: 16, - EBFONT: 101, - ENOSTR: 100, - ENODATA: 116, - ETIME: 117, - ENOSR: 118, - ENONET: 119, - ENOPKG: 120, - EREMOTE: 121, - ENOLINK: 47, - EADV: 122, - ESRMNT: 123, - ECOMM: 124, - EPROTO: 65, - EMULTIHOP: 36, - EDOTDOT: 125, - EBADMSG: 9, - ENOTUNIQ: 126, - EBADFD: 127, - EREMCHG: 128, - ELIBACC: 129, - ELIBBAD: 130, - ELIBSCN: 131, - ELIBMAX: 132, - ELIBEXEC: 133, - ENOSYS: 52, - ENOTEMPTY: 55, - ENAMETOOLONG: 37, - ELOOP: 32, - EOPNOTSUPP: 138, - EPFNOSUPPORT: 139, - ECONNRESET: 15, - ENOBUFS: 42, - EAFNOSUPPORT: 5, - EPROTOTYPE: 67, - ENOTSOCK: 57, - ENOPROTOOPT: 50, - ESHUTDOWN: 140, - ECONNREFUSED: 14, - EADDRINUSE: 3, - ECONNABORTED: 13, - ENETUNREACH: 40, - ENETDOWN: 38, - ETIMEDOUT: 73, - EHOSTDOWN: 142, - EHOSTUNREACH: 23, - EINPROGRESS: 26, - EALREADY: 7, - EDESTADDRREQ: 17, - EMSGSIZE: 35, - EPROTONOSUPPORT: 66, - ESOCKTNOSUPPORT: 137, - EADDRNOTAVAIL: 4, - ENETRESET: 39, - EISCONN: 30, - ENOTCONN: 53, - ETOOMANYREFS: 141, - EUSERS: 136, - EDQUOT: 19, - ESTALE: 72, - ENOTSUP: 138, - ENOMEDIUM: 148, - EILSEQ: 25, - EOVERFLOW: 61, - ECANCELED: 11, - ENOTRECOVERABLE: 56, - EOWNERDEAD: 62, - ESTRPIPE: 135, - }; - InternalError = Module['InternalError'] = class InternalError extends ( - Error - ) { - constructor(message) { - super(message); - this.name = 'InternalError'; - } - }; - embind_init_charCodes(); - BindingError = Module['BindingError'] = class BindingError extends ( - Error - ) { - constructor(message) { - super(message); - this.name = 'BindingError'; - } - }; - init_ClassHandle(); - init_embind(); - init_RegisteredPointer(); - UnboundTypeError = Module['UnboundTypeError'] = extendError( - Error, - 'UnboundTypeError' - ); - handleAllocatorInit(); - init_emval(); - function checkIncomingModuleAPI() { - ignoredModuleProp('fetchSettings'); - } - var wasmImports = { - __assert_fail: ___assert_fail, - __handle_stack_overflow: ___handle_stack_overflow, - __syscall_fcntl64: ___syscall_fcntl64, - __syscall_fstat64: ___syscall_fstat64, - __syscall_ioctl: ___syscall_ioctl, - __syscall_lstat64: ___syscall_lstat64, - __syscall_newfstatat: ___syscall_newfstatat, - __syscall_openat: ___syscall_openat, - __syscall_stat64: ___syscall_stat64, - __throw_exception_with_stack_trace: - ___throw_exception_with_stack_trace, - _embind_finalize_value_object: __embind_finalize_value_object, - _embind_register_bigint: __embind_register_bigint, - _embind_register_bool: __embind_register_bool, - _embind_register_class: __embind_register_class, - _embind_register_class_constructor: - __embind_register_class_constructor, - _embind_register_class_function: __embind_register_class_function, - _embind_register_emval: __embind_register_emval, - _embind_register_float: __embind_register_float, - _embind_register_function: __embind_register_function, - _embind_register_integer: __embind_register_integer, - _embind_register_memory_view: __embind_register_memory_view, - _embind_register_std_string: __embind_register_std_string, - _embind_register_std_wstring: __embind_register_std_wstring, - _embind_register_value_object: __embind_register_value_object, - _embind_register_value_object_field: - __embind_register_value_object_field, - _embind_register_void: __embind_register_void, - _emval_decref: __emval_decref, - _emval_incref: __emval_incref, - _emval_take_value: __emval_take_value, - _mmap_js: __mmap_js, - _munmap_js: __munmap_js, - abort: _abort, - emscripten_memcpy_big: _emscripten_memcpy_big, - emscripten_resize_heap: _emscripten_resize_heap, - environ_get: _environ_get, - environ_sizes_get: _environ_sizes_get, - fd_close: _fd_close, - fd_read: _fd_read, - fd_seek: _fd_seek, - fd_write: _fd_write, - strftime_l: _strftime_l, - }; - var asm = createWasm(); - var ___wasm_call_ctors = createExportWrapper('__wasm_call_ctors'); - var _malloc = createExportWrapper('malloc'); - var _fflush = (Module['_fflush'] = createExportWrapper('fflush')); - var _free = (Module['_free'] = createExportWrapper('free')); - var ___errno_location = createExportWrapper('__errno_location'); - var ___getTypeName = createExportWrapper('__getTypeName'); - var __embind_initialize_bindings = (Module[ - '__embind_initialize_bindings' - ] = createExportWrapper('_embind_initialize_bindings')); - var ___funcs_on_exit = createExportWrapper('__funcs_on_exit'); - var _emscripten_builtin_memalign = createExportWrapper( - 'emscripten_builtin_memalign' - ); - var ___trap = function () { - return (___trap = Module['asm']['__trap']).apply(null, arguments); - }; - var setTempRet0 = createExportWrapper('setTempRet0'); - var _emscripten_stack_init = function () { - return (_emscripten_stack_init = - Module['asm']['emscripten_stack_init']).apply(null, arguments); - }; - var _emscripten_stack_get_free = function () { - return (_emscripten_stack_get_free = - Module['asm']['emscripten_stack_get_free']).apply( - null, - arguments - ); - }; - var _emscripten_stack_get_base = function () { - return (_emscripten_stack_get_base = - Module['asm']['emscripten_stack_get_base']).apply( - null, - arguments - ); - }; - var _emscripten_stack_get_end = function () { - return (_emscripten_stack_get_end = - Module['asm']['emscripten_stack_get_end']).apply( - null, - arguments - ); - }; - var stackSave = createExportWrapper('stackSave'); - var stackRestore = createExportWrapper('stackRestore'); - var stackAlloc = createExportWrapper('stackAlloc'); - var _emscripten_stack_get_current = function () { - return (_emscripten_stack_get_current = - Module['asm']['emscripten_stack_get_current']).apply( - null, - arguments - ); - }; - var ___cxa_decrement_exception_refcount = (Module[ - '___cxa_decrement_exception_refcount' - ] = createExportWrapper('__cxa_decrement_exception_refcount')); - var ___cxa_increment_exception_refcount = (Module[ - '___cxa_increment_exception_refcount' - ] = createExportWrapper('__cxa_increment_exception_refcount')); - var ___thrown_object_from_unwind_exception = (Module[ - '___thrown_object_from_unwind_exception' - ] = createExportWrapper('__thrown_object_from_unwind_exception')); - var ___get_exception_message = (Module['___get_exception_message'] = - createExportWrapper('__get_exception_message')); - var ___set_stack_limits = (Module['___set_stack_limits'] = - createExportWrapper('__set_stack_limits')); - var dynCall_jiji = (Module['dynCall_jiji'] = - createExportWrapper('dynCall_jiji')); - var dynCall_viijii = (Module['dynCall_viijii'] = - createExportWrapper('dynCall_viijii')); - var dynCall_iiiiij = (Module['dynCall_iiiiij'] = - createExportWrapper('dynCall_iiiiij')); - var dynCall_iiiiijj = (Module['dynCall_iiiiijj'] = - createExportWrapper('dynCall_iiiiijj')); - var dynCall_iiiiiijj = (Module['dynCall_iiiiiijj'] = - createExportWrapper('dynCall_iiiiiijj')); - function intArrayFromBase64(s) { - if ( - typeof ENVIRONMENT_IS_NODE != 'undefined' && - ENVIRONMENT_IS_NODE - ) { - var buf = Buffer.from(s, 'base64'); - return new Uint8Array( - buf['buffer'], - buf['byteOffset'], - buf['byteLength'] - ); - } - try { - var decoded = atob(s); - var bytes = new Uint8Array(decoded.length); - for (var i = 0; i < decoded.length; ++i) { - bytes[i] = decoded.charCodeAt(i); - } - return bytes; - } catch (_) { - throw new Error('Converting base64 string to bytes failed.'); - } - } - Module['addRunDependency'] = addRunDependency; - Module['removeRunDependency'] = removeRunDependency; - Module['FS_createPath'] = FS.createPath; - Module['FS_createDataFile'] = FS.createDataFile; - Module['FS_createLazyFile'] = FS.createLazyFile; - Module['FS_createDevice'] = FS.createDevice; - Module['FS_unlink'] = FS.unlink; - Module['FS_createPreloadedFile'] = FS.createPreloadedFile; - Module['FS'] = FS; - var missingLibrarySymbols = [ - 'writeI53ToI64', - 'writeI53ToI64Clamped', - 'writeI53ToI64Signaling', - 'writeI53ToU64Clamped', - 'writeI53ToU64Signaling', - 'readI53FromI64', - 'readI53FromU64', - 'convertI32PairToI53', - 'convertU32PairToI53', - 'exitJS', - 'ydayFromDate', - 'inetPton4', - 'inetNtop4', - 'inetPton6', - 'inetNtop6', - 'readSockaddr', - 'writeSockaddr', - 'getHostByName', - 'traverseStack', - 'getCallstack', - 'emscriptenLog', - 'convertPCtoSourceLocation', - 'readEmAsmArgs', - 'jstoi_q', - 'jstoi_s', - 'listenOnce', - 'autoResumeAudioContext', - 'handleException', - 'runtimeKeepalivePush', - 'runtimeKeepalivePop', - 'callUserCallback', - 'maybeExit', - 'safeSetTimeout', - 'asmjsMangle', - 'getNativeTypeSize', - 'STACK_SIZE', - 'STACK_ALIGN', - 'POINTER_SIZE', - 'ASSERTIONS', - 'getCFunc', - 'ccall', - 'cwrap', - 'uleb128Encode', - 'sigToWasmTypes', - 'generateFuncType', - 'convertJsFunctionToWasm', - 'getEmptyTableSlot', - 'updateTableMap', - 'getFunctionAddress', - 'addFunction', - 'removeFunction', - 'reallyNegative', - 'unSign', - 'strLen', - 'reSign', - 'formatString', - 'intArrayToString', - 'AsciiToString', - 'stringToNewUTF8', - 'stringToUTF8OnStack', - 'registerKeyEventCallback', - 'maybeCStringToJsString', - 'findEventTarget', - 'findCanvasEventTarget', - 'getBoundingClientRect', - 'fillMouseEventData', - 'registerMouseEventCallback', - 'registerWheelEventCallback', - 'registerUiEventCallback', - 'registerFocusEventCallback', - 'fillDeviceOrientationEventData', - 'registerDeviceOrientationEventCallback', - 'fillDeviceMotionEventData', - 'registerDeviceMotionEventCallback', - 'screenOrientation', - 'fillOrientationChangeEventData', - 'registerOrientationChangeEventCallback', - 'fillFullscreenChangeEventData', - 'registerFullscreenChangeEventCallback', - 'JSEvents_requestFullscreen', - 'JSEvents_resizeCanvasForFullscreen', - 'registerRestoreOldStyle', - 'hideEverythingExceptGivenElement', - 'restoreHiddenElements', - 'setLetterbox', - 'softFullscreenResizeWebGLRenderTarget', - 'doRequestFullscreen', - 'fillPointerlockChangeEventData', - 'registerPointerlockChangeEventCallback', - 'registerPointerlockErrorEventCallback', - 'requestPointerLock', - 'fillVisibilityChangeEventData', - 'registerVisibilityChangeEventCallback', - 'registerTouchEventCallback', - 'fillGamepadEventData', - 'registerGamepadEventCallback', - 'registerBeforeUnloadEventCallback', - 'fillBatteryEventData', - 'battery', - 'registerBatteryEventCallback', - 'setCanvasElementSize', - 'getCanvasElementSize', - 'jsStackTrace', - 'stackTrace', - 'checkWasiClock', - 'wasiRightsToMuslOFlags', - 'wasiOFlagsToMuslOFlags', - 'createDyncallWrapper', - 'setImmediateWrapped', - 'clearImmediateWrapped', - 'polyfillSetImmediate', - 'getPromise', - 'makePromise', - 'idsToPromises', - 'makePromiseCallback', - 'setMainLoop', - 'getSocketFromFD', - 'getSocketAddress', - '_setNetworkCallback', - 'heapObjectForWebGLType', - 'heapAccessShiftForWebGLHeap', - 'webgl_enable_ANGLE_instanced_arrays', - 'webgl_enable_OES_vertex_array_object', - 'webgl_enable_WEBGL_draw_buffers', - 'webgl_enable_WEBGL_multi_draw', - 'emscriptenWebGLGet', - 'computeUnpackAlignedImageSize', - 'colorChannelsInGlTextureFormat', - 'emscriptenWebGLGetTexPixelData', - '__glGenObject', - 'emscriptenWebGLGetUniform', - 'webglGetUniformLocation', - 'webglPrepareUniformLocationsBeforeFirstUse', - 'webglGetLeftBracePos', - 'emscriptenWebGLGetVertexAttrib', - '__glGetActiveAttribOrUniform', - 'writeGLArray', - 'registerWebGlEventCallback', - 'runAndAbortIfError', - 'SDL_unicode', - 'SDL_ttfContext', - 'SDL_audio', - 'GLFW_Window', - 'ALLOC_NORMAL', - 'ALLOC_STACK', - 'allocate', - 'writeStringToMemory', - 'writeAsciiToMemory', - 'registerInheritedInstance', - 'unregisterInheritedInstance', - 'enumReadValueFromPointer', - 'validateThis', - 'getStringOrSymbol', - 'craftEmvalAllocator', - 'emval_get_global', - 'emval_lookupTypes', - 'emval_allocateDestructors', - 'emval_addMethodCaller', - ]; - missingLibrarySymbols.forEach(missingLibrarySymbol); - var unexportedSymbols = [ - 'run', - 'addOnPreRun', - 'addOnInit', - 'addOnPreMain', - 'addOnExit', - 'addOnPostRun', - 'FS_createFolder', - 'FS_createLink', - 'out', - 'err', - 'callMain', - 'abort', - 'keepRuntimeAlive', - 'wasmMemory', - 'stackAlloc', - 'stackSave', - 'stackRestore', - 'getTempRet0', - 'setTempRet0', - 'writeStackCookie', - 'checkStackCookie', - 'convertI32PairToI53Checked', - 'ptrToString', - 'zeroMemory', - 'getHeapMax', - 'growMemory', - 'ENV', - 'setStackLimits', - 'MONTH_DAYS_REGULAR', - 'MONTH_DAYS_LEAP', - 'MONTH_DAYS_REGULAR_CUMULATIVE', - 'MONTH_DAYS_LEAP_CUMULATIVE', - 'isLeapYear', - 'arraySum', - 'addDays', - 'ERRNO_CODES', - 'ERRNO_MESSAGES', - 'setErrNo', - 'DNS', - 'Protocols', - 'Sockets', - 'initRandomFill', - 'randomFill', - 'timers', - 'warnOnce', - 'UNWIND_CACHE', - 'readEmAsmArgsArray', - 'getExecutableName', - 'dynCallLegacy', - 'getDynCaller', - 'dynCall', - 'asyncLoad', - 'alignMemory', - 'mmapAlloc', - 'handleAllocatorInit', - 'HandleAllocator', - 'freeTableIndexes', - 'functionsInTableMap', - 'setValue', - 'getValue', - 'PATH', - 'PATH_FS', - 'UTF8Decoder', - 'UTF8ArrayToString', - 'UTF8ToString', - 'stringToUTF8Array', - 'stringToUTF8', - 'lengthBytesUTF8', - 'intArrayFromString', - 'stringToAscii', - 'UTF16Decoder', - 'UTF16ToString', - 'stringToUTF16', - 'lengthBytesUTF16', - 'UTF32ToString', - 'stringToUTF32', - 'lengthBytesUTF32', - 'writeArrayToMemory', - 'JSEvents', - 'specialHTMLTargets', - 'currentFullscreenStrategy', - 'restoreOldWindowedStyle', - 'demangle', - 'demangleAll', - 'ExitStatus', - 'getEnvStrings', - 'doReadv', - 'doWritev', - 'promiseMap', - 'getExceptionMessageCommon', - 'getCppExceptionTag', - 'getCppExceptionThrownObjectFromWebAssemblyException', - 'incrementExceptionRefcount', - 'decrementExceptionRefcount', - 'getExceptionMessage', - 'Browser', - 'wget', - 'SYSCALLS', - 'preloadPlugins', - 'FS_modeStringToFlags', - 'FS_getMode', - 'FS_stdin_getChar_buffer', - 'FS_stdin_getChar', - 'MEMFS', - 'TTY', - 'PIPEFS', - 'SOCKFS', - 'tempFixedLengthArray', - 'miniTempWebGLFloatBuffers', - 'miniTempWebGLIntBuffers', - 'GL', - 'emscripten_webgl_power_preferences', - 'AL', - 'GLUT', - 'EGL', - 'GLEW', - 'IDBStore', - 'SDL', - 'SDL_gfx', - 'GLFW', - 'allocateUTF8', - 'allocateUTF8OnStack', - 'InternalError', - 'BindingError', - 'throwInternalError', - 'throwBindingError', - 'registeredTypes', - 'awaitingDependencies', - 'typeDependencies', - 'tupleRegistrations', - 'structRegistrations', - 'sharedRegisterType', - 'whenDependentTypesAreResolved', - 'embind_charCodes', - 'embind_init_charCodes', - 'readLatin1String', - 'getTypeName', - 'heap32VectorToArray', - 'requireRegisteredType', - 'UnboundTypeError', - 'PureVirtualError', - 'init_embind', - 'throwUnboundTypeError', - 'ensureOverloadTable', - 'exposePublicSymbol', - 'replacePublicSymbol', - 'extendError', - 'createNamedFunction', - 'embindRepr', - 'registeredInstances', - 'getBasestPointer', - 'getInheritedInstance', - 'getInheritedInstanceCount', - 'getLiveInheritedInstances', - 'registeredPointers', - 'registerType', - 'getShiftFromSize', - 'integerReadValueFromPointer', - 'floatReadValueFromPointer', - 'simpleReadValueFromPointer', - 'runDestructors', - 'newFunc', - 'craftInvokerFunction', - 'embind__requireFunction', - 'genericPointerToWireType', - 'constNoSmartPtrRawPointerToWireType', - 'nonConstNoSmartPtrRawPointerToWireType', - 'init_RegisteredPointer', - 'RegisteredPointer', - 'RegisteredPointer_getPointee', - 'RegisteredPointer_destructor', - 'RegisteredPointer_deleteObject', - 'RegisteredPointer_fromWireType', - 'runDestructor', - 'releaseClassHandle', - 'finalizationRegistry', - 'detachFinalizer_deps', - 'detachFinalizer', - 'attachFinalizer', - 'makeClassHandle', - 'init_ClassHandle', - 'ClassHandle', - 'ClassHandle_isAliasOf', - 'throwInstanceAlreadyDeleted', - 'ClassHandle_clone', - 'ClassHandle_delete', - 'deletionQueue', - 'ClassHandle_isDeleted', - 'ClassHandle_deleteLater', - 'flushPendingDeletes', - 'delayFunction', - 'setDelayFunction', - 'RegisteredClass', - 'shallowCopyInternalPointer', - 'downcastPointer', - 'upcastPointer', - 'char_0', - 'char_9', - 'makeLegalFunctionName', - 'emval_handles', - 'emval_symbols', - 'init_emval', - 'count_emval_handles', - 'Emval', - 'emval_newers', - 'emval_methodCallers', - 'emval_registeredMethods', - 'NODEFS', - ]; - unexportedSymbols.forEach(unexportedRuntimeSymbol); - var calledRun; - dependenciesFulfilled = function runCaller() { - if (!calledRun) run(); - if (!calledRun) dependenciesFulfilled = runCaller; - }; - function stackCheckInit() { - _emscripten_stack_init(); - writeStackCookie(); - } - function run() { - if (runDependencies > 0) { - return; - } - stackCheckInit(); - preRun(); - if (runDependencies > 0) { - return; - } - function doRun() { - if (calledRun) return; - calledRun = true; - Module['calledRun'] = true; - if (ABORT) return; - initRuntime(); - readyPromiseResolve(Module); - if (Module['onRuntimeInitialized']) - Module['onRuntimeInitialized'](); - assert( - !Module['_main'], - 'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]' - ); - postRun(); - } - if (Module['setStatus']) { - Module['setStatus']('Running...'); - setTimeout(function () { - setTimeout(function () { - Module['setStatus'](''); - }, 1); - doRun(); - }, 1); - } else { - doRun(); - } - checkStackCookie(); - } - if (Module['preInit']) { - if (typeof Module['preInit'] == 'function') - Module['preInit'] = [Module['preInit']]; - while (Module['preInit'].length > 0) { - Module['preInit'].pop()(); - } - } - run(); - return moduleArg.ready; - }; + return moduleRtn; +} +); })(); export default privateer_module; diff --git a/webapp/src/wasm/privateer.wasm b/webapp/src/wasm/privateer.wasm index 1f733e473d8923c3454c0435ae08cb2c4f074536..8592b90f995174d8b96d1b31c8b0b38f5d86279b 100755 GIT binary patch literal 1994616 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%0Dm2-irCpn3zib5AZ%eYT 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

tHh%%P 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

J6z3aLoq>CSZ^K)_booJBw@?RG_2KY+z;j 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 z z`$n+a!~3W|xC`1xb-qU6nvKVK0JypFAGaPvd;QSAH0}oiMJniJ865;p$+^K#7Q2+h zyoyFyvKs^}8t2n?9VR?+WJg?B!14=&QC|~2UIv3xz1;L_KH96}xwm)t~T~orEtpd3__mb?JNaLo(V+9MwnMc%Mrv^P|08xPK$TJ^pjl z$~d%_II<(I+P!^Cs>8oOx$Y=%>2(f8G=qj7c5>uL17|Nyyt@zFAg((G+{ptYoVK97 z#8G|3?b){C{Z-ig0-q@^V}YgfuHBo0_7X>S#J!js)3518oa1thU%<%>w=X%NuDQIu zPp^1*&g6aLZM_z2kX-qxy*JH2nH6O#?X`AI;X zmGdu@ekpL_oTHa@Uc)9Fkb_GH1{WB=`#JKh0V+EgpqFt8$*{Y|{aXsIA6|GWi?|R+y2PDx z9XK-#WeaovmVuk-uHCr~{t-uZ#5G%cePPs5Tss4Dflo_KdcT?DdQ z1JH|4-H~_Ub8s!V8Ef`B#iMK)&aDF%Rj~4eT8QauK#u%+U}2Ms&lh7{_2%Ph1GtJ$ z%8WS=?i07$2=2F_c7{#h>T$bG;I4#p*9-&az`4!f5)FQf2ViWJFU`OK__yWk0 z-w*U2cQ-u^d2h~Tg4=7~IIBPM^*DC`T=3EdAMT*P$8qi;xcU=iDK1^paX{ z^W%^wPRY6PZpx0sQC7jrV(740haV1{kM-4$ zmpumV-16BajK~v5Wr@3)?sumj%GTs%kArK}I;z}l-mwG%DJ=P&JJp2*8^NM z=g`&6tJcw0hf#@=)4nu^6Z<(}n1Gw>=!;bZL-*0Gu`X2G|hat>% z-}v3NHMozQ!_;Ql0hf}4z`f!emL9g_herPIQD2F&LZ4&lVTF3fyOw}mIX>2|fvY?H z*_|b@D-UDdxU`}5W$73jXL)^h!F9a%)=z`_h@<+5D|&y+utuF+0kgr_;jgQ#!rn#rA<}Q(@Tw-Vu04*JtH2v$0cn$Y4bzb*x&WnVqgpPb7JS7e zAQK-rPz5Yt^c2(y*~!?;7D09u5(P-SUH=of*A&V>W oZ9n19b|uuSs;*bHFT`BTe+wFa7Mju%^!R~UpepLB2Bhcv9}Y5aEC2ui literal 1978727 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 k>S_IMnNy^`4; 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 z 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%0A?fTvGthNvL@I2fWp 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 z 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

ES$U!@w7#Ac!cGpwxvH z^iMLOAEC>v_5eosQpO}sJl6QlPIqR3A!V+fYD)32ZgQn^ULgpe|xim+ngmPZM=pw22<8E+ZM&Rh-)j% zuv2=z#Ub3Vt6aIHj1}AQ;E3!y5?O+MC-$KcDADY@2>Xua&Awx=fgCc3oGF%HR&X9V z2$Nr?D>^8MeP@=im4c3feTVt&Cua}*8%+kt9d;(j!{GTaE*Q1%ECd_uJA|1R#ex*p z@RDTT8PLNB7>U#}f>5=xq9&^WWkg8MNMeHqu3i^Vidwj*4grr-158<3e#3|~`v%Fi z`K9t{2yy__EfWO)Y9--ug}GNBoW6t{LisZiwf4QGr)G!>fQ>4#(tQ+}V=N$?;HH{0 z15bLMbO+!wH6$Y9!Ww}Nx@&=ad4>*xzkM)h42@3bpI-;-Ag==fN68uj)-mWD+BqO# zx-k0i@RKwiLUBOAGQ-4u;Wk$V&zKQ?1c7Fri5)d*o=E}$qlPy|2V^i=-HUXN+ZfNJ zB4EOoa!@=hA_A_WdnQW7%oPDA6CIQq_~gLrK)`H(7eXOmp*J`vwTgg|3q-rtIw&~6 z!OyeK1i7)TeXJ#5A|%E&B4GP&=#qnCSYx?E1Z+SDwp?q)UgpUU%y0GAjxp@ zMk3siFrCTu8lMEn+R${|3YTptOaaA-ih|+6wZPy%WFg?i>Y8mlJj5z=k4QzJ){_MZ z4p~JC$ngesLSUO#3aW!^0=d1YQs1UfD~FkqU8aE#sa|=>I^i^^UOO&;C1FVrQ@z;Y zSmG$-4XU^0su%Kv4J>Bj)!+{cetI=gD(RaNIw&gv;i*Xq+e zPI&@a0HS&|ovwOKqng|^)k_OO^_p_6Wgq%zbh%}! z(DS4@-XCqLx=3i5uHb=~qKPW^jtg$;a|2SsPMi~X2}SP)Ga^aE?R5uB8K^W9NObSSjjoklX_XD8buD=BPT^{69EI11gsW&G%>)Y9 z5$Jd#M&U9pACJNZdPF+|MFKK;6e$szM@%nGZyfbD74^&qG?v^{Idg8r?P zHx9O}&tY^CJI<_&$~v)?7Kwyt_Gq6Y0qbdh!{v}G2}AfiFfiasfYJh3h2Gp2~& z+m17G6T~(#7vb6p`U0`7;Sw~mj))yHH7q6bN#3L(60D$$E5i0;r{uRtM{UwP8?t+AEJaIV!Z7qK4r7p7y-^xF0W~|Vy}?s{FNXjX$RuKC>}cAtup0$c zfYvQAs)R2Vcxnep3o=tzy@8t$i?np!u-eR|B>CHky*3DHsec*W(pgQ3IJbASibnGa zT#aoRgnQ@4O=cEp9?g809q(-iv2E=lt<{IO%V3iQZz2SC$Mz!XadtK2S?E}ZMDqp9 zS|k#xCe_eGSu5n=X^dL*6sL>OT+Nw&6%HWCL`NyrB_jY3Lj=nT09i^iwZW`)@u>Ka zB}5qIkYW|V60&P((t>lx%sV1C4J{^-voQ$K9t0r>C)=v9R|8a%z^$4E%SFIIXAD56 z9)z$d&nDp*mfh$Y19S&bFa8FZq$AcwS{P>4wvGufJQpr~#| zQKa6A9flNTgt4-=@X z?E4h4!XbZ(~$iI6Pd&Aa8&KYY4(ZLgLhzAFi^* zdo8NNGdaef{6IB*Jd!LlHRThb5R?EI6teEt6@s-SCgB~m2W^BaY9-TCP@}A1U}h$g zK|A!Vgd*UPzmHjM!k7VQ(#*-Njt>bgg%d_xxDY)Zx^UzIJ+2Ff*kA9$4XUkm;po(@T!TAU zxdw^3o=kxRmnyq~Yu`YeyKqCnr5mN)Gc&t`!*;6>!i9Qp*5Zf< zH>O3Um^rY3r!ycV+Zd}Y}J_gq2C6c zrHTwFu5^srp)qW-NiCM_slHplH<8wTyIK zP=W-w$meqdMVq(wI1~*=+5=+Kt$gy18r*{%21IFL4YYe_}X^48W+G-KVM zish}1P_&|$N+^^Zt*BN))o20Du-03vsF^D3NqtaBdd#V3m;)kh7;-@5ttq;-HV4GL zwZwBkL=^xt;6YIh6s#N&K9FMWi_jwv&0A9lZet2a;wuH{3tuS!*;du}*oyP3D3UuF zqrMu~H;wbv#7Hy(jSezFXx>%|l90M3&4;=~!w-Em%LGwsmK+V&`j6wQVFbFv?41en zFm_=Ai8652EVgQ{8iGq^TEG&DNH~jRI?g%FLY;6%awsO^kC&q{2kpXsQ` zEF2Y?>8Qx;V!E$RwBi8ATNNct7K-?K(i+y@-Bu5~ZFNP`k?K2#*4 zNP__&8a#}JTfgCqIy`)srj3JER$8~}_D`+{y%nf0znz(hPaHoEAlewq4A%IqagNeFnAYg%5#L>E6PNQECb#XoH?{f4pr^9mZr0IHWO;izU^NmBIS7Uu zPXbnPEp<&9Ak-G0E%;I<6dK`kKtvqVuB$|gx~AH6lg?a%7;D#_;r3Lh|IFbK0^-?~ zKvXv(_7hAG%R!DI(bG7>VQE+h{TNfgRtwZc9ty( z&hnCy8vr)_F8z^c)e{kLdYh&S6&gz2sAn$-rL5gyDVxV^H4N^Udz%{vSCOZNb0c#- z1Uw9`LWIUOI`*}gcz%^yR39Bw;)4Rf1f&+pcPWr0@tcH!1audP29a2g!`F(gr`ZED zN&VQ24kkT^b2s*+62NvSk*pXW!ymfwrFL5wlk*dijDeJus7My5peu9jo>b$t zA7(Q!CNw{|KGiR;TUG8c+l%%8%=H}B@k5xWu6>#V?b8g`x!#+w+14()65|f0RtKm0 zMOdgg;K%g2zTcuHF2pqL*z%SNmL|#G4UOHMKpr%9HW6uYCmE1r6-uJx{jG~LQg7dM z;y8LavKMC`c;_qs4(^kR(1EVhI+-kCLeR{e$q~K`p0CgvPwzmk->xqw6J6)3dcYm( z+O;Vy#8QD7GM>ic8_ygb zz`7DIEyiGT*bpZsD7h3?JgO#M+Mi+=Y+&d6iMXGKF|8O(hvB%7eF{T#+hTEo9%e@7 zjyoD}@9)&}+R^?NBsf23^%E1L*mmO?{!XKlY4#Orb4vIva{eAZd{|?hQd!QWrt2+~ zo2Gbha6w6a>3Oai z)5W%`oo$q-8tAeH)pyPb6tjyulz`s1@OX#S8uUkcPOd|;zqm9RP(okstITSZuAii@T|rs zWFgG(Pb7xkSZ7`&Tc<0= zN6ch0Gk0hcsUK`1Kpix-&zgF%HTAu~I%oJ2k-*zTWEKmaz%*B;{lhe}-9^~S(h#!#-TDNCH@YAg!E6|xTN zvLJz8LtkJ#d|cI^GF}fCa_&**JT5>C5ZK7}F=QiL%p+lnUyKOLN!A>#En>}D8}@_r zIsKSolHf9#Ry9p;dLxt1ccz?2TV*0_ecn7jkn);6gf-=d+TsSf0ghY+`JC$~`i3q( z;DuF(8u0&yIv5OAhhUSw)w~XssZ(@OFe9c`S9Tpl!V1!OyY5tyq(_smp>?d9XXZF< zYOSSJjbx>Dq@v2tI$b7<&$=DlC5yEa0rHiVXZa1m)o%`$`fh1YFPRQYN*~)r+=)C( zi=5-JL1F3X7nyGWvz&erPlS^E2DWCG-{kYIQ`rrlqjw0u`eBy*syl?WfKXjyJwPhW z9J}?nqiE70+u7;3+6vEkAZb65`=12&Kau;N;Qs6CWM%U>)aH`vz=Y&w%CP5dWR%g1 z`pL+h$D@G0WhJJV$p0{wvj!KgH)c$_9+~?pWM!I-t`PEssr(TcopCrz{zAaSG#6y? ziwGly+n5s_nJx$jK18>bf-H8(a7lPs!GhaBFmN&~>)ZwCSnk3Jj3d%Rhwegf6L1*J zaX=)1iK2F*hj|2GBksayJC!|pKT(*mggPQjkRmj*)&#{B3$%Lqt^F>f)I*{VY|xEH zDfu~%u>y2~M(Mzyfrf7wnm7E~V3gXei~kg(v@mL`Y{&i!ZOlz%Ko1k8?M11Z7)NuJr1NrCqN#2ESRT*eT8OQS$R}yAC7=9 z+?J7Q#*A^Nly@=edIq)J-wMzPKcjA02eNqNx>;0YIqx>2D`Q@fLxHJ zfCY}hK~vZ^vQx|u$$_DEypLJ31KXfWxg2w)a4FitG`6}lSk!ojjfGva^Dxsxu$_ZP zxPIv|E_6{82FgE*-ISSmQY+@n7D=s1VhmCeX1P#cYq6b|QyPatCT=@&2GLPdJ%WKr zbVw6}l+p2pp6SCI+E&bB@#JQ<0C2E)Fr;i?6jw2fv|#!hsaMmr;MFh~>;k*%Pf`C)3Cpu#jixCs`F@&&OmVt}k8O{4P40KuLpWk0aw z$gvr8X-0&0`Cz{g{Adi!2u4_hUzhE!^n@XC)(4I6a}o2LbnMJ#uOF^ z6nm11B7;QJ(Bru2fl%$Z)+5q6L7TjsfRBnpOth0?YNyPp$WR~9AirgeLid`4@HIY4 zv;vdXsZ=#kX>iM+Fu>@cddL3>)zs$g=;0_^_R~?(wBtp*0+c`lVGMC|o9?#)w=x0D zr)qiYrtW3LO&H-nqzM=2%JeBFToIEjgpp}<3O!VI&+5vvj)2=hzK{KObVO&##*2i$ zqQz%f)XNWz4QPoLZwc_WWcnn7pR3VfkBC=|t*k6?>j$k=2TdrZnbl)Q)0;O9f6dPazb&;fEPi7?eLA1|4)Sf>In{4Zc#S z-p5`IoVc!TRpG_0Many^^b{<~%Q&kA{CC%rrR+2 zgD~9c<@gQN4BWF?P5!PEr$vF{UJwpnSeaH>kZFZA72;Y5dM@*nj;xh}OTR?9YLZ|% zOw5!cX2{@BIryAL2OXM$G5X6Jju+`4CGZ#*=FrZg&4X4|-ydm8_*C-?z|3!H0?FpL zR{rRtHovkhC(SQ=a>`pC_4$Q7HQOxt)NFpSQ8|WP{nL*OR{h~btZH(P_YMBZNJ%93 zeV}Ww5Mg4*N`I3*m}-K@?@4f>blQ;liUS9KGyBtS+z39+giFB@;;i^}ndGSaW3A$s zCqLCH&wZLB5|lOcJ9dPqgH#?SDw+RoD`LJFc~pKNehIF}2jZK^dtseWwaSy9Rn3-a z>bK5O^nLDHJmrDT?y-TC^o?OKy#zVUJZO;$Cc8DKED}=$|6&YZYULo}+z1lkY)sD%pE}H!6YbL+Cc=D?~lV5$~_qI*m{l+Hmeshy|gu^G|>^+;j``u06>BRKmyi4vb^$?;a0=0`@no$xG z35)Rd)6oK%prWKxhNW5UETy$*QX+ic{(i*$A_!V-?UgJ?|3uonE+c2W!B`~O2V*}Y zf0BKQL7^a#tdKNVA*rm8R3Rc#U+-=8;uJ$s#$x_^Ec#-bNDZOfkma_eTV_^rvoc2+ zCubwRj3opmBeMRJ|2`oV`=}*M)d+t$@|)< z7c~|d3uP<+m8o7lN8G3UqnZ5CF0r9UK5h4U$GvFR*P;QhE~3yyq%I=5AgOn%4e~gm z;WO9H7Aerbc^Njt#AI9}(E&jtu1~-~{=9_IQ`F--4`~mb~*A3cl9_`tp64e1A z>8hQGD6<%1ArTic(}~eWDVq>@J-fz8K}0-0fCxbO``U61L{JmUa3Wo{&s@1)+E@Sx z*fjt1)^5>Hdi4h0$ltBZ?r8?Yzgip1&$XExPFsAMJ!AN~l>yQ?CX-25eDYi<7MBaB z5!cD&f6>ZXJSVU2fY<(u;jD4q(70K{3?>IHSpY!0bAv|b2!!x)QNN+ZXyEat^^E_X zz9kkE^2sD%m?C}nZGg1C)dr`dG^EZ;8bsKE*$}{c+9fziMTlP6i@v{B**P zP!mvzZ3pev4A7BBo_+!*Q?SMWuab-#t;3`IqdI?b?L%Ckf}Ka$x7W><@*k0O@uiXA1Uu^s=AYr1Af3{`=0zC;uCNzhU98s+;!jb~e{0Rvz#yWx z2O*3r319xk)cQX2&$lNwoWEmg!aL)5dZPqrt^m-NiI~e6QTgi6P3LDj*$m%B$n1hU zm_O9ccI)?=sQ_n|gqm43bSx!Iz~>LPMGI}tS$&zkgsSt;wpO!mKwdF(T-j!418aFh zzBIa+5(VF)D@nAEDtT^F zPU1x(rK%*YTEzRaXNSrx9IBs-yq_2usGs~NL1ir@)`AW>(>b|}9Wkj>g;j3u3Ih@> zvL_^WT%CK!Q2a>ha)H>`c)5@$WtJ_SC7Yq5{BMM>`K3#vNJr&BB;o<@WFRyGJLgOJ z=baT{_(*ICSBnB+OC@JZIx3kxz*tqM%tfdM^3+WqGWlCtk!h6iB7ts9BtXw_+E}>} zL(kxaOzMl+ilFTSBt0Acf}8_epKIB0);uO*oVWx*fp<+2#hDXG3sH=Bhwftc@wKq_UEyis)-9p?JobCJ~BTKR>N4aqd5i<+q?1 z#3(@t=qvo@dO&(@E$vp?lUe*C>^6Z)p*#v0qf}oZxxkfch`wLXALSMb-c~G%y@S>? zY17@(K^lmUY3(s|6Vh*#k;-~dKx3G}gvD9~v>C%rP(WiFzAz3HKe-0nOm!pdO_$v7 z^6_V4ByfT;s$o7Se@J&8+E?F8ANf>{`MJV2Vlr7acQ!8)pPeYX>z_b%YiAg?*ljcUKZXwT6@1kH+3D|J zwv3qjUqVK_>7T$+U*(^x56YZTSc$Bv3$>swSbqPff0=Xhj{LTNPT@u%WUMuuPWJBp zIhE^J>jvejvjWzssA9{`DEpVnQ2#5;nSAEN%pMl@WnklE=6_2BLiUghaXXPC%T5oY z9%HBff{a@{MMA1^{==LVJ=Vsof*fP1wKDMrL5{CP8`J$R3_|z26uK*0%lWI?8$)+I zv&i17+KTK|C0{+JB+o2xe)6Glf%Df^!F3CqkCxdaaQ?YrVD$pR;UOThX*iq}fG;5; z{<^jsp;|z(MH3|y+E+QiV9%VBb-{65;!^uZbRIEiCP*9fqalgc&LawG~8J z|0sV0C;1W>v#`RKBbfS@_CU@c@cst`Q{Tb>CwqwQ$sYG$Y7TbtPbez-36F|Om_R-G zn}aa1}1&T+?6na8LGc7@QBxRi_93=Fo5oM=G4Fg>JqxbaAmo^pI^rkd}&w ztzj;)Cv}~wwKbmMjP28ml_t5gsy99!5#_(Y^luVRu=QBZn+TuX?8ux~o0l zJAS>ro!p>YhP|Ea?*^BjSeC9>>{}UKj>EwJ-aAS zZ^T+Ujq=#guihh5zL$dK=ArCQoMtTxV0_#>Sy1(TeTHWnsi9*%*sHteVtr%XVsF3{ zheh&+Ne3gp)YgI&SZS%6!N6`WErF!vboF|(pwn=Y$L|E9orws)axmTFGb~wq*39K^ zWk3DIR#-fFe;lVF$T@a7)*AWCHYul{)oM9ud7!JFf5>U6E;@tYO(Oq@Oand3|4QHL`Cqp)rCx9>FZe?wi^fQ?KtA2h%s?EFJohZZvTti=^9-%*^kQdc1_2*)Dw<%d(mH;exHip* z{2z-B*cv|g_nr=9|BhE8aE;I|SG1oZ@MOWk)fE#~2wtYp)s@h&Wh^s_gc{&sCiN%R z?Hc;wtMb~EpWP8}+70kn4ZD}a6ez#jY3mo?Q6ABCUrXMCahZ^4#vgik=ds$?Q(9(lBTZd#4kzopdmwT7;-{24@ zF-t`YJ~8l;S_ew_u)a)LpB?oZui{_oi1K7Jb@g~@EF$~g_ccgl-gp%T)hmtVCz2#S zma@A~$d@=?E2tNb^;!w?q?|j@=QK#FaLOv_1atd!G=s|b>x>GP@lh?`#l=FJWh$l9 zX%fXG>F5Szk(y|nKP?J1g=W56pR@J=x@+iiVved~3k^rD&;iG)ynqiiU`I_PI_yLl z7;4Lo=|&zKi>WQ6U3+WY_@Cr7$q^NTRa&+6#I(;vnp#BAX^Dv<=~>c4OW9Jk81nkH z>+wv~MOp=aJp9Lqk_*KDlb|L6;KU#r6FKl-zJ;WriEq1lyNkNz*}n~LFI08Q6dEFb zUs%2TEpwei?tpea!mQ}A(E1L~|H}8vzg8xgJn{VlPy0P>vl9%M%Kg~C(M_kA>gEU3 zif*V~Q{lkI3cnxx`ghdEX6(G9wz0~4Jx>m}4fw0FKOCyr@%mbsX1zMr0;~Ju6>-YF z5<-0bel#nrCRK{r$^4>uKEN|x@+;5(n9wBdwY79@j-a`Jbo(wBz^< zJuLR??7U5^h6Gbtj`!ruO6DxU;FjgE?>}?k$LDhfGf<0#5OhBsJqRQzMz3Oo1{9{d${vE18ik~ntdAy#RAtIE835VOaTJ{uH6qTZh zAc^z;YB@J!GBJHExo31HoxH;K305?5Y@Jfl(79$lew9wIH{Yzy52hD*1LaQQY=e{=gntM66y zIyW$Xn{uNVlZ;-zUtx`M!F!F^w zPsXe@6a>n`IdiN}QRbFR>?Jm8S*7qQ_vd0kh(Joq2kp{7%&zkDY5t+6eup3pYPDQ_ zU6%hHK?kZJtmUvJG6FU>tQMI;{7LZ(>1>+{j~b3>zplOJL;{ulD}nGL(_JByOQS)y6yr7>IKt*Q z*OvG@ka*cG!VHFIk}S|FxwcHD95&J{$j+;dy5}dMXS2}rPtt$*E$iHL_+Hetogbw; zW-Mh`kzt|IqKAbfAKa#H%YUy6)ai?SzaC~+lAVbMvVOdJjPm!l`qY00(?H(3k`Evs zPwTi-=C;1)??k9+UdE(6djU-e=E!bHV)#Hpa1S`7@r(75zpH&&q$mJ%I5vKhT^9mn zfTC<4ROX+<(GjOy#Rs=j zKF8%Zn6rd36j99sNmlu1|K5#Ix0>JVR`Wto>E)Y0F-@Xd`KeFY$9aCep0D7P0;Gx4sD(`G7i_yvEGjxe(<;*S``WAiNTedl+r~Hwv`P=JEwi&ijetReT zrIZsk?D&vLDWA!LnEC0_Bt$l}f&yy^3717rcO>ld5EUShZ)z5#yu4R+qycM)7XH76 zZ8xS?5w@n3B$7VeWD|~EP-?YOj^7k}!mnrr+Qeg0*WW_d#6T{M<}QnNdRN?jR!6j9!5`mc+jcWcf5aN0VlYcgb$a;FZuw4CvK6wa7Vqnf-hwNNyrRxposQ!Eb* zv{ay_xE`s1@|cl;8p0y@bo>i)n;||2_ncB}DmMU@h8qZq{0pdX_AYURhS_Av-e@NY zxz9-U(VBm^0VDo^D3RSfR^AwCgTf$RPZVSn{=FJC0>i|y@bn{imYm!6?mN>C6 zapf*-VO?(kBIgv1QyMF3O|^Bc2QP#+BD=Fi3f5G0fHF349qak+*HZ0JoFtC$HW^Ft z<9ecEnhV^}BD*N4YLwR3^GopYpAx@KTCQO~liJx^<3U>ISlP|o=&B3j2%5Us)4BKX zxP|}3hi+f7US>(3;wpOdqP;9*Q+f8C(-It2U*voflK+`0(cd(y?yz`yOiEpt{6rJ` zHmnPcC#xj;Khb>Dhf?-RxhB-*f4DZ$d~tz@Voy~%dO$!}Wu$mIqezFMsYB+qT^T&2 zwn6blwxcs^+0Q19nn`4<^${R(+64KG8&ce9pc!O4xuSt)L!;QZQ?_ASgr=2Aom^cY z9_*(QS7CfRaawp*tvw)EkMUHEepQk*?A5l6QpI9yu(eW`rf4{$eSroYg9Dnc72(pM z28h*T-=X0OEKYJ)0lB$^v+N2UB!@z2FdD(jp71*<4;wl&8UI>~R0J7+OXo|I@juqd ze(qn4jNcov4l?_t%XoGP{Ikh;hvji)ywCW00gr@pDaDs3DB78@H-33VJ4_-TgUg0I z5tJkd9CC&zl%HQwlKtx=Y=e5@tX1 z#D$qTS%_JaWwT2q!l7#O0%Y0jzd%{`I|+M=z~v+7Ik{=xuG^97vxRWG3sYB`u;9u~ z&~krwLzgmC5?}IDxT;@U?WfwKwNS9p2m;W}S@NBtE2(z&gSyX){}e$0nO97urk61# z%E#_W<>i%%&8VgF-Lf>we}#`ob!{QPtu22VDV@j&!2pu_l`8WJSg3Y2W4=uJ-7n|J zt%D_ZUq`4#X3lQ{T8Z_taq~f1HX!R3-3hQ_*8nTF;W97`+V9)A8s(}EZqW^Gs0XiR zcfRcs(8suoKtWY~Kbn0<1Y)%B!+Dny-2nmtLw19lMJ@2y|LY}tGlc8+wR30Shv`I8W&$?FDJbo?r&c_8Q%beMb}&& z-rMR;w|oQhQ25UqiY_`=306rjFQXn#PI;D75S!zjSMBtA4m0il>KB*kvRo^l-hW65 zq?&tZg0&CXOS4t^)ao%~xbFEYTV{cCo{#wraui}73SOPs`MMURk6ELrXWD+T{11hy zl@)-OP9N&4p1+>G;GrJiFcMCedZ`^0?#0bS1<%&X-sQXW{uRZ}!-sqFO2SCgT={io zIsgYSeWP82TYeq(Km`y}Hz+m)j!oeM;4~BqSd0QkVA;VF=zcJgP=)O{zM`M4qjAad zQjfk0J~}Kl02#||1)b4zr>2;@b}=(G)fGYVR)5wGwn%9iD+vDKh#t!8N*czLAMXd~QRJTkq4X1nUiv0AcljC6B--?!}FROL=w^r-&PpUs%e)}K$ z^tZKIRAVc?7px_`sdW<$Z50#C$Q6zrjQ00q1*4C$!H6$3ySBimssbs3&I)jEVobRt zD_vd!JV7%ioC2sTjWsTx#+ADJ`;B=GfewpF$Uqzr)U?d&MHMY{)xDoFN;c=<>^!P@r?Kzy9`d1j7Ev7d`OhA zu6|;q#2kn;8o`m`A<)LQNf&W+sia?0{v{I+fzZsA(2HF?N&1U^_Sww-Tw!(O_feg* z2tUXhWG(_#SyKdqNZ+#dBnHY$d$EJ4dlo+|+RL654@b9@E!u$Gy(!3Fvb>irM!oI);Na`t4n8~l zzs1GR*74`XF)rxwO8#7Yol-zd4PS)nWmKs&2n(GxVmo}81~IqJsJ#}bJ(UI_2g!uA zC=7%?MRBH>c!;^$NP;fEQYi+tavuWr2|!hT&jCms zy>!8Kh&sSE^mNOu?Ing-=62=VKqn$0zzDNx3=G0yR8gr`%zRFOwgctCwu45noOD85 z5CP+w7~>TawC>m#ab5E?B9mU*Xj%KeKmw~x`@lEuoUUz-B{p{$N*T$Lt+~Tp@UP$Lg zv`)L~|GKGg>4XHM5;6v8Bj+Y2N$QC~M4h5>lMXuiy}y3wnHqPPNo&mp&oH-(uR3%s zOzeOaw--BfkZkA7;$!ix{at{1BX{IpDE))*xnh?vF*56Y+D|xlb_a5CJA}eX>RVaM zBWuM@bBfEIHoQ>(3nRzaS%n5 z(=Je_&GODdn42CSiRPK}Sa;e-5AhG;F-=q!3nW)B=vE+tx=~m?aKDKQSzWGOCVrEAK{@IcF~SpaLM%%1Pvk z*xEKHY%^ER=TC?RJpR{bjsKYjH2}?w+KMBlsK_2Jr4aTg_ks8=W=O^79h4_3N^8jh zj-)k2k1}v-JjFK9tefx89XYZggi~>Ek-0xj06497SHzeLQ(2Sy_oce-iOpFc7k&nAW5JXx=z{d?d{W!mkr0XJG=4DNK9zTYpQf}Jw>!A6?b;DTr zH$drp01ZWSK{BpMwkIm0a_(mStUQ`>-SW)``Pw>Uzx3wNK^|Z~WS>zu6lBY-fZ6`x z)k*$n6P^f9KrpAA+*F?X;r7zH7v-mae0|yS_#4um{8dvxkLDzyQKB~b=KC1DDws|V+B#8^eS;~&_Ui=JEC@|UOy2x67Qa7{e zPDZ?U=jqIk4Hk?w$Vf3qPJvsdWnzwXk2$6=p*m#QuOYL>GJFY_sl0~~<=e?3$Av%x zqEf1|I%|!^%1w%lXj@m%mPQ@p zbp?*9*sUTqbxVh$^SW@zwS>(y5QYuHdgwO=JFn}0-9TE_btkNiEtWu-G^m)lH$XL` z3>~JH2(xdb?MSTgj5uwV*(XrRPam`}LCBy6!k7<3=ID@>*KIJFBq-|E{2IyQD#Cx z?n%YMd&0nA)W`|rQ9}w->O3PAcK+OSsR%a(jacha&OU?TQ2{rtMVMHasf$Lr3%)}6 zz)OP$#k^)?(>kgU&Z8Oil-O3p!0A0E6z$ByL3!sNPcwT;IGgt>REYI-|9tj;pmtQB zK3GsT0+BgHP4-9dBGIb2j%XvvM2QRi=2bi(e#7ZptT=d#8AiakSh666g&$d~mkogH zL%$k8{`vauYyp`G5+ds{*^j*!5l*L3V5{AXXtX5QV+Ww7xkE*YW_+1o@RrF+$!@Tn zg(PrDauYOQiLuYIW9ckgNj-NBON&Tu$gI$_r;i>W&E~i88bPx8yzqW3s`7d=Q zf`KE2<=KGuMB!z3nN1z`KuUzvK{cw(GqIn(@D9c$GyAO=7ZY0D*phM(;ku%+UlB-9 zIoFFfmSXUPDJL2$nF!%Mp6eHqyXCrRy*i4jbZ>uhk)Ev7<4op~1a7O}7DcoJMYKf` zZ76~Tk!K{j!H1n!9WIM$mA9g8@Q$$bN?wa}f2G6KR$NiN)B_vI0Gr z;v)`E<<8KC*)7FP{VO=aKI2xIteCoe%(}NP?_{PHi#C&4Qj-|>bj>P_Iq>K}QBu(+JzLqxWPBi%% z9YeY$wIk2RoXF=1xD^w-@a<~T1;dN9)0ah(mcIUS`-&>b7H0cmkoYSsh>z7Q0D~R* zFc=b0kH7)>f9_~kXUQr0i2A7f0y^(EI()gCFF!@DHvr>`4>ks;EIz%xqcr!osTG-_ zZjK^dTj@dqHp@q7D=HtR0XzK|@F{D1Ig=#?()6{*6Z=A3N?VS{^ zF32mnVSv9(I_GkK0VoW3LBdzq`|PQ9{*I39I6+dKwQP_vN}){eQ0n-usHM%JWx=?4QqapmvqXeviLR3cw3e^bA7xnq$Vw?eAo- ziXV?bz$T342kSbI+|}vF`6oIOIG`*4q-oMkHXvwt#$2fK$sCitF&$WM9Vwu zrVfe;{IcI>XsSTR2;K522qxQD(eD;*61QbDU&=GS?<%?;89~BmwU`=32HZ$4u+*r? zKpCybnjZQG{P){zGB$D`kA~lRO!!y10ufPXdD_%Bvm7N+?p{Jjb9%xDI&4Pnx67T^ zC_7gFLP{+y$t5z7;-bw9*+W`ZgVNgNj;r`^L)p!HD4WxAu901j*q88S;Vm)1YVL|) zmV|*cXaFKt97qFF(uKDbg#zkfSfHXU!-87W5HvJzSc(QwHo^4Hz7UUGP&#&NqAvh5 zW+*}vfRiND)y-QH%6MVh6Vv=$C;v=Wj(#X)L<*u|IVOv#d=F91Ix1Q3-Kq1pWXMYe znOzA+{hNXs48CEPWxYZhmK$~rRa2Xm8>bm&DCqn7cpLF%w{P>y3;~-A{H|EhNQqcm z1VAw@mvv2>#qdyE`RlBGO4nK?VMdkcRGykiirDub;q-&y?5m>x%Psov;Z8$Mo)o3)ny)0$ z|MAD?(gl-C|4ckuBfz+kN3qm5@aQ6ey&)$W4|0*QHrU!f{&wU7Jq|EHT1>R98egUK zFE^$CR_9;GU%8b2I^Qwu@uE%jkwmU(Bz-|w5>UKU+E-e#uQz-T2NTigw24{^f!~A&(ibX<=rEw8v=^a__;Rzu?|elYLtl)m`*&Fl7_TCZ z${70Zs~`p@(;5Xa-ei(n<7#1146uk&IAZH!rV*4eJJCRDWj3QpQ!I%lwBr8N1k6sr`a-_4d?I?CMY)8hW0oE})lO`>o#8Qd!?zcerTixe`zael zFMQ-hoskOyEv+QwIg28}PIb!mv5Bc=wlVRHx3q*LA0VHO$!gp-Rw86o0M&3tunUrR zoKb_Zs&4~NhPP1990dS?X}gBlDOA^AOX0KbtzBT7L}z}O&1lDxBkl%_jqe9c0mJy9 zl){p|1|g~4oA?rd&SWEZ-o$;Hx_g{IEwV{j2%0Q|2X2Bge6)HjUxS4n9hgXji+Ima zzH9aeu`Vym@=GQC3p&~?a9Vs-+JD7J`#&jk0ZFGqh9$O94Eg%(W=4~s+{|ctHF*gGqbU?- z1ScmhvBl)nB<*80(GOWQ<6VmdDV~CcN7RnVc#kUC;h6tFdv60R$5q|=R#kuAuI_tF zA4ZB~pt}(>0_5OXRI$M(uvGZSC142BpG zu?d10EQ0|<1PEdWg%}WEK!7j;1SsHu0D)y}umA&2F!B5S_c_&FeQ#CY4+{eGg7EEA zRp)b`efHPcXP>rThZS-c4*PZHVbC2jrwRw2LC06r(xzD}NLejOSuLb2oE2cAiPj=# zBceeMKC43#0&u6_6S#HWd04*X*7QYY`XsE#j4#quk#hGDT-tGeV9Shz6>0ZpZBkXF ztv<>JLCyzl^|4JK;inlz#8wBK_pq%aovZ*qEE=d7XAjqpS)5MdG4u4>9y#;WJ(MB8 zF;D-sKgWovTu5hwjno_H5;$7Ehnl`MNSdorp2GTXHnoHm%G7U|DxFKrA46icMTXQ| z5ppY(#^q^q!lr5AF{WtPjIY+gR=F9!R-#hejCV{3UCTG)Fno}>4%_%)Am3?Kj=-Y=47y)Ri%^{6#$uTNK)0AK}}+4!AC5!iIkDS~CB z!D%X#U35zUPv9VH{dKKqOZws(=V;ui@6MhVu?g=^epmaUbEzj9Njd6C92eoJp$404 zgB|RN+{aEP?yo_~HXJPm5}Aq9L-I*+|5ml{TLEQHUhf)b@pF-4{}#vqHy|CtPQ~t?JL5E%zN$uyX^HI#HlU<5{u+Oy}1lU(1Mt+b`MYq zy9>TTKU?0OuLR2;p10@c{z<$&U%4`G&(AOK?K!SVJ}_0@p5t6A@%B9Gy*+Hyomw0l%YNqJP$+fgA_vHL@{PKc7DFVz-(v$Oq*)rtGIrib?3SExA z$(`!|uMV8rJT>n_F{kwEIu0^0wPVvYsUty?Ix2TIybW98mJ;u?FHE`~-j0&-MO1=Z z+F6V1;Zakej!@IS8TIxoxE@kv_A30sB)N>F9o2lhUX0yAWLa)zcY1@e3W2TIvQlu! zvgHaB_MjoG05&pKl;r(0#qqE;-SMzE=!frkcr+<>JUoV0RIY_2=?mi#mn}V=0n?V* zJ-;&?_WDY5P;(ND37l?1ak8tQ1nnTdqSeazlL2{>U-)l%EAg6K8b9Y<8cn{TGiS@C z@imxc!|B9w{R&KH%9EY?XYP9imqwYRe@FV`c>|mowqPA%~h+#1=?sc>uL3&<}Ud9&cP zC==-tx5i?IU{&^o&6+Lmi2;hBDcZ}pHU2a4`sop`sjhSXGH_fa)P-3Nf=y3g92X&BhpnMUCCtrwhW ziojTYUq~IAW(B^txGxkk)8?5e`$9L5HK2-39ce&CXPTe^d1sotuq%3}7}G}XHdCN? zrkT`B9=1S7`~M11kMpOiDr0+`Yb3XOTwJZK6H5lkqj;fge`kz@-)nzQ=bTXn!Ks|_sOOB!yHPx7obiDIXQb#_Ipa~|j8y44 zW6_PmCT4qbuW`oH;*6fzFLI+`v{~Scs;0;p$v@_dYjLAsV9U5sjJs5DqbNdXd3LE@ zPGgr37TIOU3@{c5$yT*bmhZD4o-S7%3fOa-uxHvnd%>LOP0QY-Sh8DI*jPWi`|P(F z)*UKf9eeU?#X7&wPL*KYO7_`<)ma4seyx36(w3wd zMSu*oytTvrLjLeJB89NqraHfc_}FC=KRkY$M_h6wfHrUk$nKMWfcE9i#n5jBSl!5C zERBZTzm$`1?}(!8g?2++W#0l-Fc3RQqM<&M)sK zZmPTIBWPhZ$JzHf@>juS%}4x-+!LgcJYl!%0deJLO!s%}mEz(h+4nm-A}-g0F!NS~ z$eg?!`^%UbMSPtfRJjOQ6#*Yq8%gkNtP6o_{&vwy6<+Sr27?HGl7;_Nj&thh= z{iE?TAr!+Vn^P8YNw0|f1F+@WrhU~ji^QTpXJK~Ngo|c1fMg&(PA4}v< zafRR%$)L+_PMiO5TC@O}gvPMIjbvh!=2)P-axmbCx#^MytB#MuB;@tMI|xm6YX@?s z83<$LW(6!P%FxwVQIibLNMmSuyLJyanxV_+>50f7P}15~OG8|YtmJIJr;<(Kcay+J z{Iq?bB|@Cd>{=RI%O)*QOodd#^T@^lRk4_Wz5`?+QH7o9p2X9^Gf~yzHoEm+z%=&r zM7Tctp)$hdV;LM{%MW>pjGGyr70GEAFGs{neto*ID|c*EG4t7l)bnZVG0Y8K)2J7p zJvUQzIrUN%5>5HTt)8HApk8O9>J_>c;_Vmp{|dx=Z8)%W{6F6~z*=VINXW{5)Jb32 zh+F21LU6lMx9omh{QL;|k~*$A=Ez3zk_2igL z4~8?^Z8ur$QNL!_XwVNYa1=X3ZgocGuSby{btU_;`r-3iXR^gPATDG|iH2|mtc_rO z3QR>{)#SnhrI3{d^<3ym zl&Nn)1ih5DNa$kRh*wq@{;ilc-G?Lh4d!nvOp^mB#BWp@?}_(E?kh@@e-G{($YDsm zcj=AfFnjxq^d-qCR#*ABSymFqz&?p%iiFA^?@}w5E+(Qqh^HQa@D()l)5iA7dTBI-4(5ut{ZD8Ehp()%iYj63h2 zG~>=lkSjmqutbpSA;^K3^5NFfVS*6NB%d`W53>p3JAq+jwPiljWoTMS)gP{xn`M(<;S__PmBJ3d?6neLYEt95orVXogV8 zUNU5_Y%CcTM8d8Y0DS;1FY5KfyMjNUqsErGY)n^wc($xK;NlH-!l+-9w%+KsxDJ>1lz~BmNUD~<#(sr9thy)Few`nR z{Z>gvF=H`m6&0giP}eX$LVg;K9VKz<8DDP5%o(R{y1=RFnmBKB)IYV7`8G8cI;U!6 zI39Iv%&>W-&h>rgwlB^oAwzsySJ{vFHeJ~+*ub|f;dLn111r_@ZBalC0`pe3z8*AGC|WsQ8uPv{ z1QkD7rEPgR3kIo)mBq#WxQ$eO$Ky?vB4oSXBO@SsAVx{e!VovorQnN1#%@&|S5jtR zAyyQU(tZu?`9YFH@sBO#{~)gkjUqat+bJOpjf=Jd#e!mWa*AU0leTtpsN*MX?Yxr1 zfUGqExx(7{$}(%G7|spTt(}z9JeX-|4^j1z?s%AD?c4xPx1})+Ar;DdaR$hVLMpDGk(7zmM^oz}rDpqBWd_m<|x?qI# z$T`Ix`9dyqqyu}Al*@;hr0-pcIgCR^BXbyj5>w1!cd@vGIZS|GjYaI935%GIV}V7? zFL3zzDlB4CstOjdDLGbc5z|0LD7haIyySNcMlnBJjA9z@GDb1_UNDOJk{HEQ^5GiA zY$%ZXmD|N$lW^oRoP{nwrjQ_H!^aTeEF2|TNY|{3qK&M*85eO?1sumb-Y*}{Wc!Km zi-;zchN%t%=w%YI#gf|3}D3o zi6zu4s!)JtdA%bo`TFg>6q?v2mk(q0Nr7_Fdg=Za6cZgG=u;Scs#a2(qB3?EL2_96 z5;Q8Kz~H$YHqCB$QdC7QU%_rD87u60@Nz_D7TXO~%(xRolkyXG!)a7zWp=|rWvb8X zCTk_OOn?N^?=9Z<`FSO_Ys7}7VDJ{ipI2-!Yk{{QUXzY2h;sF;uxm(F!PT?w@Vb<$ zvebgeCiaENZHbA6(=CYP3>HKxqe_JPMHa-xIZTC_v>@I>B?zBI3nHb4tF|C&%U||3 z>&jRm;g#&3vLH_6sJ0+7bZB;B__(0SoUO= zTDb)gN^>?Xi1I5f$2e0$Ub7Md(<0GmOIK`TD#}`GFf-*+<*dNGjF|~|70gV&BxWX+Txw?W@gw>ZW+o~1 zW@eI1Z1db@o`+_O;D(s7yrz8svj@>+!5)-%)(Ql(owoB;mCOw?<`dj3oZ?)@L=?I} z0c5FMGA|ggRxkOXP>oGaFB_Yj_T!jXuG%+5$M?zKdS9)=UT#g)oUPQb>SobZ*m zZTr=loH#0hfyfj336qm2^ra>z+FH5E$gecZt!7chjs+aE#Sjoz#{r2bi58ozfLD$?^PY`n3!;$^C_^cDaS8 zF=>4Y;`y;DMu0CSaWg1!TmdwA3 zz9n@o8{O{bH7RrUZx379S9BGT-eq4^D$c%!Y{6B#)Ay^)|EOi|bOe=bvn8R6T-lX@ zMvB1J@G4PcTL^EsL(8_M%0tqaR)^Lor4N-}8)&*O&~~9pOE9qPS20FeWUg}exM&4u z^uu{{>A>v$F$SrfprLl*^zymvSD*-SU#*;}-cBeUdt{SCSL^xLxO$mgECDOZHO;kl zgbPl~JMtHtG4~yTtF5LZudk162G#fBSy&*u7O#tw4~l*W?`2ovVYxMPW}AD}76&%7 z4Bm1ZlFXox0i8ZJJ`KrK^d@d%2V2`RSn8TRi~Yw7zq^*bB6W`y2N&ZdYy>3|D(ED_ zaOOuFQLjj`UVO+r_GWa&oI9WC>&sTg2B(mo)hV+uW#u7e9!;-E`8*?Xs;LD{86C4K z+-DJUc0PEnZd=zgkb;WZ)}yk-`Te}?UVjHW_7C5=rn-rz)}l;UD^hT2VtmXOwdfVW z38_dMhxVixgC2iIUvKH;eZHlW0|JqCl$|c+F~V53z?SyMuZqpmJ+}49li#wXVOv#I zxY}=~vf;7}_)Ed<$+mU%D6LaN`kzNmiRHAa`Ls9ez5C6d{^%Wl`WXTn+5%!A9==Uc zA+6TzIw^FvZp+Ow4TY4V1EZoob~RHa|72wLU|=3O(q5OQH^j?z&F`;UFY^02g?YN7 zQ}(LT3pSO(qqEA9q+1OIisWuh_A>x2K|jGY!BpG3l`xIdoskWvFqFuK0x!8479&kG z;zCV$35T-Y6hE7Zi}}|5udemqSU^AB5gK?o{;5t^9n5AKuN| z9DXwhI)vyi7l+LKLtE~#Yx)2rhH=mgMMrhI^1J2^vpS$5Fm6#17%d_hv@NcQKKiRa zWA?$oNMUOzOIOUBbzHn@#aW!<(+q}P&R4+pUFY|L^RmO9F|Gm!hQR$$9sTu}Q`}7A zbl>b~MV7nz!t2dt#ux+yHLS{(mSm*~xfRx`+NMqMruL>yGwG)8rrxG>)24OnH$GxS1zI^3AXZ-5 z-R$49b_(yWPrIAYF9BmIIn#j*_H>|R;SYDIK_7ujmu5711F5`WDPk)S;+fwXXDc*j zcmihnM{x(b1T9@74`&0{#E{s1b^fB#?m6_~X>a(#d*1wkdq4iCe{Vr&C;QZ*6)2o< zdZXoj=dEx4^jkmvr>B<7y+Ivqub`vc6ga(?>sMM6Lr#|)@;X&UK-mfS)k@&^Ep8y3 z-mgqm+12xlrverr{@b>xfWOZV6W=q$A3qt$QeiT9gDW|v4KxDAxkWd5+W^wIB>5Zih!PZtmAQ}C9;Fmo^k=V+Y3{Nw5AT#Xsp2M z+Ma9UQv`mh2k)4fms}G>6N8H|)|~mt0f&_no!AAG3C|b{XaD0(tp&Z@DImqNH)j3bMd>%S>XYNKqeqI)OnhU#OE^Rz+gwe-xPZY}?HC~0Ywc!hy`Ai^F;oCmWT@?& zZQ7;kXau$g=!Mx4#;g?mVW*y67M1|)6cOAn0;wFJ4=fJ_gQbu!6ytgxP5b_8ZoX8l z0wxYgP?EuvjmdiY@O3ck7-wGxQ}95R63PDz<^*?isIx zL9&Am=Fgi#q3j+~&jYG-FbfI#uywEtq=W4V0&;)8e7hfb?0ek|@yMT4+e~_INN1$4 z4ryG~+(Jl8Rv449CSNdp-sqLHN)Mk#dckD50+}yS&ScG@&b8}jp!&np&)&E)>3%1~ z5&lycO^JT?`JaS-wuTW->Ss5vb%Z7QSw6zEs-LZLgp2jFx2$Y@6Z+X-hzkES^)pe= zqJH)&PB-%3?9 zclC`q`EI#|kj{`M9zbFhS?5vY7wIcXOe({e{~0g|uqh8`4v2E2?-? z2f8X1Z)#1eRq;lZ)k@&MIu&nJl}+WtR`DjQTZ9=aQ}K4JTE#Px;#IsL>A>qpaWaAs zTq2rO3%3(09vwPcD&FVMnu>Su#u>LG`$kLd=ZgfJ9TGycE=;RCbE9r?yO66ETJCgV zEu5UP7VyXOHJFAsbxv2L;T0q`7U4)zYZW9lNWe%^TdH!7mU>YG9Q7+MSp`2m4X{8X z$4X${x9lyGN?`sTtE#7*Yfu7Lwm=pufq`dxC6HwzooB2B{`rho0t0JZl@hqaD}m=% zm`nQg^zAi&qHsYrBi$0TG!8iCJI<8IMru-Ng5JriuFT8qpJZ>-z7$p|j3(NDs86*4 z$w1d42dYDb>GPsiHjE%~M9(tm1sJj0ko}^0T`838lJxQ%O$k^dZYWGb31-KhH+Br?XJBU?(1^ zqJjESAm_rQc`n^eEZ?NJBqhBH9UGfvGTl#HH+n37pG zMJ*HVQkJU(I1GfjD9S$G9-u{e4C9&^F8K7QRX#6Fy(*~*S8CLxJ8By8TqLk!hehzZ z&Y-F7yV|aPE$l|ubV9mDR~z9xt9~gAf|a9hb6B(EWp4isadvA1rvl+tO+-wRuRp|5 z-o4c=!1h`eAXvVF1&E_sVF9)Z3lNi(PWb>axjM=P?yN09XoK)}VgZ()243j`l%r6U zGe;wG4@GI42_a_Qmh=lcWIhFT{HM|dknD7E_9b1_5|O}BhW$2~pA$1{^6JY(MA@C4 z!~z82*a9-k`(qf(QO45dD5J9GDC1&xUUp@V;t&9Nu&|$-a5;1K1u78QmD}ZO`c#Tm zoU@{5&ws%}|3cPtn{o5MmVc|ZUY>3#-0@T~#D1I|nBnjTJyr|_;RmV5CDD`ohJ?Mg zKlSV?%=gyQD%fAy@SAyitItwsm*Hw7N8tj=S7IE45V(Ejt+n6&vir|j(%4Rr+PZ?_ zSX?lBuv3AQ0E{mawZ4XJV{eq%OKEmm{Bf<9@c@{~Kr{*d?jZu)U#B*kH@%`}R{j_2 z>uX+7Gc*4J=1U$S?)-hR{ry2?rwAiEB`Wu>ww%gQ;H`hk4F{~-QBhF$y4dz0=H1sK zqEo1{!aEv2*p_3U78>x@p-~ykMcN4ZKrEz}#T2T$^F*WBY^7qnPF1u?u(VZCygH`$s0LrAD;A9{>s7y%>ExA8xwn`!UYb|VPSHsYvWYoJ0>@S>jVFAyrf z3Ck>}bcx4zr~Ry-?ufGNWj(F*BHDJFp=>LqGlh1w3puLm>AhBIW!mCMcJ^oU0IakO zKF+eydTR%*3k=7VPP?eyi=^oZ(kw(+MO^%>t%P=HsfylY6}{>z2;Dg27|k#yyT*OdS3L~E_%krPw!EPE7g5$ zNDq)yGUN|%0#teLJd;8)|4%w5_fOucfTBloOn@TfCUhh%2)eo-P3nwyyXjY-k<%+yP!dbCV9x5tHc0=V%W7DDp(@c zhhj@Qhvp9Z28SIcjEPX!Q9@|^>bf@c&{FB`)sV&8*plR<__8!nuYT40#z!U1iLk9R zghvp-&Mpl5kNINZiMy(XKxupOJF0h%T2C1dISH3|51`_^kD=0m2#c368+6=7Yzp|L zCOi`E`I^LZ> zWaW7!3-$^Zangb}Fu?4c?V$;De6et0*?p}oa)4IQ7xmX{ODMz=dXVB8*+;-n37M=n zs(_WWEVzgaTaP6w#`USIyV{d&d6yj;66q?F_a&JjPH zlA?&71Iyku5Hf=FrDG7Epai|XuO*{L97uf3$X?0>z{b;;2V>D0^z?Fdo)#`lPTM4K zEhW>@HcRzLZMM{6)6t3PrlaFkrlU_TZ;?4B_QeDeq{k94p|RpspwJm zF*6-O#Iske&~!w*x#=i4ipX??zQ3q4F~Fo~I^s%u1>`YIJbh z`Rvo)WOQZvlQ0>nA22N`Ya^4J*0oL(e)7l8j;r3Mn4 z3Pf)Mh5yXl5dGP4jItDgEJ_ zi3)>9m_w@UWGA#%OCc~a5ovDJ0T&}dFEtT$*;5(41wvS5y@{w>X(AFM?io9twZC2a zyH*p?a<#3%M08HX%|B_%KI6VDYyhAk=CR7-|tFsWuf1EPGLU3Cx z7xb$w1P5zD%3r;OK#Gwp1kBGTv@2e)5XcHI3jv1k@M$#`f_r9Q%HBdiu%X2kf;tug zql>v^0O;nHfl&YrZy7jhmH~kwa)%h`asv0mv<%!7Zc(w0#~cA#6?Ae`q6eCiDvH+zG||6InPF|w(cAw#ufpX1CY%V)9Q z3$rh)o*?44(qsYAFcNjS6rp`j_WPdvKg;x_!nC645yx7Ib>)4{IMwQzMob&t!>*}g zUJ*p#m?C!_l~PQKy(f3=r}dh3|6;;ylag8de11<5GD%-hH?ger3SY3e6uy9G?j%Nl zjydYIsFLtP3c^HXeOjlEKCSDN?f!b++K9S;$)L*Vb`P7oTzfA(lU;HYe(VpkUVbI9iX9_scc8|5!TO+=)*BS9w;ro6WM1WbSjQ{P=ETi{<#FE zGWu25JL^=Lj#Jx~YTIAiu7Vs?cZx&U6y_qGAj4JY>>y?>T)x4)A zFQL!YMvJtgovu#U>FQ{wtFw(DL7GdZFu|Qh&K!N2+d9xQ-r!qPlUioJHR0U{}-PbKf>8Ye{eiumd`<)wu?f^ zdk&-@56%zkT9t2iY>O!Sym}!MzOF&cxcQJWaX-_2h<^VPChfDFQ`uA9nmGOk8a%># z{zP#tsk5kAm#lKy(Unl62bgAGSMFu>Oy7rd&=HMhuAj-_1zOqT_Cw^Dk*iH*UR;K{ zSkIJ& z%KOuRS)|rz6Mb`IGK6ei{8mWgrl7EBpr~QrIoeFnldd6K& zh1WoHz-hWMeC8Gp87)y`6}Sd-rcm~|Bam6*2A~v_=Jg}&^~A2wcI^ticDyH7D&pC; zxcS?245VCst=XO}lIsaM-J@W^cQ)(KxsaPr6CIF)7=z|?ZzV5VvAk?+6aniCU2}Ot zAk(TTKjncGERjqRKxkuQcAUc=_?OcO>M@mzBOWz4Va53sY*$_MljoI5{}>WAs*n+JkHkjHD3lhXuc6L^%YuHk?a65ljCcirlXUDQ7(D zh=o2S{TVNlGq z$?N655Svhf#FE1FUGuFVZ_xh=b)er!j|2&Qf4h2nbFqYeum$Zqpcy7LO+v>VtssXN zCG>@fFPb)-c~&B!A80Kjp&ziFT<`}yWxA05AU225;^2WjSTCd>XpM#RyGn%g11)&L zNJv*T+__+X@3+5a?C&XRywMBkCw$U044>4r93lCI<%IMjwPl2KYJrLxsn&`a3F&%2 zO-LVuXL>{F2reM0FeL_T+wu-1g*5Z7ixEsbya*6V(YEyLM4shQ4+%8%|vmCaP;1 zm)VXj6V(?r!sPghCPel9#D6K(s{5-I)jzpP36~8fpTwpIp`*w0xkv2QF$>>Itr{%MKAS9-}cyR#^< zW8Cr*d#glZ-?(y#{hSp`>=<$}0^}0A-=3JWEAJLb?6!YUnKzf%Tm45!VsG)^NMfHD zsmY_c#J))qdn-unt&zko&$F=Ss1tt{0~(3l*AJCS-V9jX{RL z2g!S}{H_YHmfGLr_V<|mz1@o<9X=lNNy+aAd{WZg%_K(x%2fIN=GvqHe{-!`f~Qt+ zL`Xj=!t4Ds8GbCVtXzyYsl`k3Hva9&ag$n(VHe9K`J0PUOF@)JYFWD|FM-1D1?w*_ z%4<$1MEOO9nF*hT#L3F7s)mAEUy*iX&Bi&LL$%i=(R6>}#^_8f=TE|!+Q#@ytq!HI z@52v1YQCn@XbTBs3Br{4X#LRuU5SUkHBaP7;ruz+q&rwKdh5d|Za)>v-Pg94-A*9G1n)G-Y$O7Zuyc#gF>n!( zvX^P|@5^1kr_6cntY+yFTjzD-5*Gk7ohz=xfFA?$Sc}tv zlcpJ9m(tE3T~~3L--^>ycB-5H3;P;z)SVan&AuW$^Xc&BF4o7l62G;J`KT1obQG{< z{Ok*7)i`k8)qYXzHVUZz{JCHm38(-#Unk`TE1=5~6}F9{g@ESZ!YN1%V^84omPfZY z04cHq6qZ&E)9zPhfJ`I%2O;?tG}et=kv7rqN{5mB^1*#hoM-ok9p{?8V*-GoZM|Do zjS>_;rE`m19}Zju*s^P7>e+X6<*#YO*|+c~(jE^MXV^=At3K_(Wq(mWl3-1QNL<Y^F)OrWpX*Zq_OGo9#R)pUe{4Ru_nw$xR65*!~Yh-{zbFLQ4* z`(k%kSItd`4hV+#`Q^;`zh)AA)U2M*2hl(R&QL2ENx%eiU2$~X`5apFXaQ(A=TG;M;WbfQA`a@M+* zpBPrdu-r2z&8NtJ;80Bs$sD+HCRHm5pc7|z2PUPI?|v!JC7Q-opOy!t-}ZN=0o|`h zFlYs@9A+GzRx zD|S$9;gmBIkb}(~wQea3u_Z3Xc*T4(i_!(dDi6KEZ0KGY6T-^tXRWJpA}f(q_$e=G zI?7!}wyR(l5a*cN6JM6JEZUHKW6pqGgFNu$C2|2{1!~aCBUNYXY2sn5@W=W*f&SePV?RCnM-? zYY_V;${`*@Tiv4|rlN-sIM!Lrl5>v|Eu#|1m;$n?Lc<@a5+G}=2>{nU9f9B@69INp zCd#Fi7FB-TIC~ix(Ll0qh`BQ+{QJ3a$-m*ZN(y0ci6RHNkDW}ir!sWzTEtsWc)>Ix zQQXa8<{t~(?)JYDtF!{VafiP%n|(9Q?n&J~|NWGGS9N?nGWxpTzUt0t1!&_(>pOP0 zdBz*NGfHTIk?>e<+llBYu^@KyUsy(qGeKZ3dP*L5`>4d#|7fcse%jj> z78VXSo@8J?mKS1Y(-$I}J315qr6Ji8;KuUC7Lr63~1nmhJc%M`l@-(!iIJMi96jEwHg2u%AXirt?V+jBS+ zyTvD1a};|ZFQx_1-05!ig>6&+TV2uYD%5vp-XEH$j9bWi9qKu>@_MfMV5o;O?&`cA zcf@LN*L)&;<=Gt@eLd#C?ztm;<=LIczpC3MmntLkjkny&zPFIaS=JTB`QlE0mu4Q) zHM!z5BA6U*CBb{W<0s92kZuuo@*m+&;!FC-4?>eFFLC4z78#SDh8AP2Dg7}@M{fPH zF-X9-x3Y`DcBFZoOVTZTk16<`7@;&l6F$YYif57Q(s_28217RfAJi!^n#9GIiJwW* z8_)=JBEA?ATVh;4l5ivEDpl~<2$5YP&qI-phf91GH8wejoBpC_C}X+{&8~)2i+8u* zh=7e+Wy5+XC>QX&U~t?r&Z7Vm##>E5O46NCZ71?E3db|loOPQjo`nf6Dpb*ri6}&K z_@ty*Wh7*wZOMk?qGTssp#tweRH#CL8~4Jhi1MPg88E2971KwF%i3_=zN@9=@Q4&| zKp~r>hZ?EGzt|5_!4QGYC_7n4CCo={a*Txr_FuQE2J-C7H1PP)MNNh#f}IiJk_j<_ zHwvM@AtOm=86Cii-9o%;>*4g5iY1{1G&Iy)f^mG8FH|^?JTYmHGsQlz>tv_U3X`bz zv9OGBq=q)6>E^2M3uMpI3#x|K|5^cZc75a+*oO@t3eaXG!)USyuL{6c7bgZdZX*ZY zD%!}4EYrqfcq6E)9|%}z-jm%SnxsXWbzDWq?H%JqgP`wciVicvXHEjUFk|bP11UgA z>?V4;noO$x73u#Jc`3A1rtXtba=)fDnU^S|h_L)Y)_t$n=XpR5EH7R6ri-uSri(k9 zaW9-MnH!d?Y>6(TO?J{=TLzihKmkuJa*)tM8os@e94R?Ej6+5A&o5(b`!^MXY0ld$ zYeX-`VZI?HgY0MKFP;SS>)DsvwlEP&#Q6$@Sa6=pk zeLWk?H7k0QX-TB&Jm(zo7k4-@Zyn4sk=hbRDV=roU0ZbqFUsE99(H{++beKiWMf%= zYqPE<3rn{@`z)?Qo$)63R{2)+6RC{@a|pBS5*Y&Zjk&m!+@H_YbG z<{HmGdaVgV;U#4=lwH>ywgCojO^;;qv7czl1MwCG_E;S^EKw!Tr}EeOnfzrCxMFjop#q_YZAX6(zb$57N8@JeeJ z6q`4do|We#!I&a$CP!O*hS+(B)Dzr^wX>&KX#uTmOTqUQ76nHeaOh{QdU^HWWVYGg zFi!To7_#cov0Q6q4GW9SW@BgMz+!v{`y#h*ZF@zgOb1NDOzW4@mCHR&U*3-ALKil! zZh-?^zrcZ?k8!+ofnTv?fpeT+8+aUM(c&g{m|xr>JZD$Noo+DhbYQWowPI zK3Lq{{sw`itHs?7i+clLkwbT9a1M*S1623oG1#l{i0K&u4{;VyDA9$apKYb?40msw za7nMv7lHS)7Bv8;W?gdmV1_Zxx+@jIkY${jFZN(Y?&a$#ZUlnG+D{=7=O|$Ix_-|q z`s+NQhz6Lh3G4{w66X%IRFRp=GD}bPb%q_bubp-n>_f*^b~9or;^Yn>M16oA zOGL}FXWi!f%Mf{-)3oAr3cw0IN_DV!9YdhNdeJHMwWDd`Wq;PFRmSqGTNOsIdd$Y| zVW#QL!t`dE-fUYWYSrB}IqRC_4FQMs%PcQPt@@qei~-mPR6xZMor0Y-{gjGg8CF3= zK_8zZ;M9} z$D37N=q4q>2O1!{g8H*oawY+oL3R#&G4%#?0yII)1(ta&U1c9MYG@#E?1mUc4)#KT zL=*C;X`cBfte#E2*f!gt;oxPt7}ZFx^ZVX|n&2YwB{(RQTl9dN7Mbh<{4r@o@Gq%--zQj`XbYUC?a1uV2@zHTyU(QpA4Il(_%dI3^u`3UxjU0OBZ2VTap}10n4?! z?K`vm)>a{%`S6w@U7P+2>GbQ7u5@3;$RhXI7%51Sm=aA9S5Zn)-hL{Pj6H)~U`W$n z4I7^0x$xGK!iv=WMTV zl$A@Z(HV zTIl!qV`%SPYR`r%b;#A9$w+}j0xw*6pho8o)ttzTtXzxr#_1U+S<`E;Am+l+JXp_yN$5m&Qy#9`SDVBzFHyE+{Kp!C@rn6quS<_ z(F!ciD59iZG(gf3VEot@4%c=uSrf2E|D2e+vjc01J5nuyi191h7gI|R7SxrtHivD$ zpM5Cl23qqTgDVBoBt6j>1w38F+F&=%*UZ{rsgoA+Ygs^w>>L61B#CSt`a5J1kY zR_d@1Tws_Smhl1op`Sb@2Cx8FgGk&5;$1=>_hq6eO52q{Ds-Y$49hr-t!#nVlIRA| z&!=8Y&gP}=FmvmxNkTREjf;c)Ry=_ys+K{lu2S$@vEO+-NqsT3ouuyl_}nB?hWz6K zkFmm&k6VT%%}jJ-M%_?f=n1uU!C&8(TIkFD2(b*1;oERn9sHgb$v2XpWB_$hx8Sb+ zAC;Vm=Vu#H0(C^jXefHW8C%YOZm%t=gEs*VEsupcSSEW~=qSQcpNLFq+a^MthQ!76 z8IA4mqlNliR^mw(0oQz7JWSkr2BMYtL5zmzi{!0e?rQqnzLea_rR1UAOL*~bE+*&U zhv?P1>JzT|NL&KQg91Z1O_Dm=e`NpWA zlVcv?VwWSFZ^|+z@*C02whZCofN;VrAzZ6~a3Ga`G~Cvl5@9GzF&YeqR>Omu^mr9J z;Z@A|Xp(uwlfV{>oGfV-OjTgHWGsAhW zlx7jMY%PLIG05W<7S2Q$Q<{aLHIbtd*v?`{STqzs9Q2Pi_YvGf{;T!${q>OywFvj`)$wSkeH0cVMmLLERM{9$u)8&XKFDe|J$gfaW_heyQzY} z-5P<|Gy<_%8+UV}BF5hWcYyo{PIt*Ad0#FSd&uQJ6n4=buEtp0C8L32Tm{YsDatt; z=0wkDJ?#B&7KyB%4oG6C%82Z2{7_!g@alxdzSh&J^ z%yFfh4}mEmcR-8@E(EC+Vi*U2MtiYG>_%LuImw0m zs?>1|%{Wh#)e}2Tk$c~#qwJ|6edaG_vbT2AAI76dD#*h|kak~^WcnnK7_sSNGD-#++jM-t2ki#CF{F?&nf>=m&bE z9iCU$voE#uY>otYRDFNe{e3q(*mc*FTIeZtGpR4xyIV+o!%~Myeb!P(NxjhWogj6_ z-kl*DIY~pp!0fKp7Qf9?iduak`eE@Dv%W##4Qp*-g0I z=CFN@!ItL$+x@h6v&XapYT73ck-XO@Zzs9u(}tDDNM7%gcal8dlcz}@_R0H69{0(G zAJJ!@yoThy&sYunNFMUZn@Ha2lLtvI9JdU&k=*N(M@a7X$>Sss`s7KHp%3?xJnY{- zK=PPR?qO&reR40!Gd_7e$%W5a6E~CG>yx*T-0zdX%mW*kIe;Qy^CMsbtTC`{neoAZ z{eN*LE{FB~Ijm2QVEtN8WN1Y0Td6xn>Q7#rXqxXN`Gpr*k{W!=)SxVCnIBu=#g=WF z`H;7~aKGjh`u$+u^3^}iXZZ$endi{*8Jauj2l^n%+kBE5e9P3}$YKcQTc+ruG4tJ8 zemvM`EsJ&Rp@z@&;KgpgU$ddcRA16gq#v>T^a((7RO&i%U2j~<-Dt)56gtW$72`*t zD^%>@sMt;9dc*Npt-a2Q@hKGJlZx?^w|00`>=tqz_N~3%it#BFq9SCMsG9vD8zY#WsqCxCAewBuAX9Tf? z+q9_0@{DnM&3HSuyn{MTC(EGCq~E?%Qb(fXtDf}#FaWog0v%S4AOSF=gTCfN?~CLQxDFL57BamGZ=Aq zdy6^CGAQjh;1yT5^MT`2c2Zd{Q%<@DD))xd@-cU|_3Yt(@|5mouw#j$gq0LogqGs{w!=dC6Ar3dL_tiS#wCL%3P7Z4b}p>U|*Hf=^Gk9AaubYH-g zJdG0%{(o0wf8GxIEU)e92`tP6aEd5v+fcJ)r%2^WMtSv!16g*AbR)gU-r37e_S}hk z@PNzyik2^;0tYdm3SFBQCp$GsMDQ9$z1SUpo}$eURc*9x#+wM2)&YU|Eh9IY1hI(h zyHJ!?G+^-dw2%ax zU>Ake3Kji>o;Dz)f#^0dcfJkqC_;0~4n5!e>ExE%A9h2+uAaQgRlGsnS>P@xcL*`#*B1BhUc2sLD z5Z-m$m(6j#;cowalxF|f)%d*=>@}aaa|KcQe~UtcV2qcx@RYYESqKUL%w+01^Rx9R zjw28wb~pSHIHui)*u6$c0GgPA-LTlKLm^Y@Cj{8Wz#qn#sz#oZF`oq>d zXuxSZQDghg-Fx`W;9aFC$;wC{AX_dqdQE*q48`7sXP`HPsWBgwgbjbna4Hys7+ti} zc2=czm;3tc5N)Zf!L6H^zz_;cBD`B`>4V;>Ner;mfrf?QLEGXEoe^BwWzXT-8pD-6 zqySe^0j`!$j#-m%Z5doShs*(Z9j6I!B}#dKYh9Zk9(Y7ww7Ur~AA<1nCBS1E1MpfN zc&bsrvq1V&AhX+6i3VRTve4d>qdAt>9R5MIoqa_afJUM_nsW@KY7mQgh}MVBBg>GhWBs7%SFp+3yJA!w?P7|^ zGJU|aN^J57`-L%5HY#SuOk+?(Z*UgHedo-O(-?-M;zULO^o9kGuZmV*EqkbIy%0YX zL4MX&Cn8gS?pBsM5KfeVG3$Z|(}i#h)cjldhS!B`Ca6rAbf+eLpb{o8Tfk9#$`Rj) zvF(b|e-9e?-hx~TdTeGz^qstQUT2@}$^%g7&WOl?8IX4D+1lX%kUB2bkiD>%zG+!_ zB}}Vtl}WYgmI4ZZ&@|JtVhCvXT9oSBN+6KlnvC$T$}`ZST11?{QH6}VE=3l&@dQC< z-(0XqqBVTl&AyM^Rr$jS>2Mfkx;S6=^bAr4Oi=s{)k)Y!h3zvT6$!uVo(BlO5md(; z6(MSr-Ua#`qDFDys-Tw$XP}nCFuYsPFsYyt;XxMuv&^Z z_<~+)W^)hvircIckAt^@%k;^lDGi5);cI>Y0KR&@k!3gg>iU1 z(bB8l=jli3i^qg-O7C39I2=}gk-g>nI@no1@5 zbyNY9PmN;)(k`)9)%bTl0vh55z3|}I@)nbc1o-@R=V}rzOsEAWQ$@YSM?pqUvjaU+ zXddAu3ujDL?51Mj{96ElCs0>1Dl$Q$W0|W0iMHhyNc1!^oc{T^cjd5$?wG|z-O*B0 zKcPH^Xp+4JTPTjGgr_(P*CMtd6s8+G0xKT{>u!BsEJd_J3}zm}&IDHy1FVDAW?v44 zM)Vjdu`?&u+KYPWnJ|XxAoP-3(91NGbNPwv(uR%9-np7W?h^kSRI|j75Y*93cRMR1V(ao7EJsQ4+qde+p~yd4{2B$am{Ttf@dhRL9u zlUY8o_n?XUQGS+c=%HYIY3W#@~=q9<5duHZe%m;UOgFSsc5Q=k^@90n`P-uC$>}}VD_#` z7*F>m{<;VBqjr@XfCwtuC`#GNb&GOjkV1h*OxUra2-fr>Se-aN3ClQi5M|oy9n7AW z!-i4z^%)kHNZrPWhx0BbJ%z@*h}@2 zNdH6@IiwsYZw2=NU1eW`gq~w9*o7M+npBRzFH>-ybVsBaj+r}Nqe3FQ02vTJyFtuN zMU7`<*W=q(9c$^|jWo(~8BL>2vbQ712s))Z4f#gQ)bWH4(UH~mP##CtiL2V_eWJ?( z3`2%_%sd-`=2t<9hU*I&m;C2>_o>Xwdd@{O%zKUa8*FL_wD&r ziD@YGqyV1@Q*W6vL@Qu48ejmwUe-DVqJpA5#$fI(v zvpb(_?uM5%^Xz-?DCXyh0zR7xyuK&ySaT1(|MO4ueR=4>S1lMHU)|w7zglREC(2Sn zhDXZYl$X8so;%ImRz(&*@cAbe%IJ|oK5Oy&jlTb*@33>RL2ZffBe&AjUvI;0X~H)N zZ|PGEVeGiEsI5B)gq>*g-?sh1CTutb4;h`1_U)TnIDrQSKP6#6Zb0i6a?k{UvKYz zB0g2ue~w^!c)NsScN>Q~rl>x{#?;rL_>Q@WyVrf;zRx!?B4*cf?ozK5&yBQskrQEF zY0iLw!mO0bpKBr+k^WdU^TQcE;z{e@wlDD;0B!Oq9K3#rC_k8~;Wdmfz{snhlQH3V+P|MwJhu8R^$_cI3 z+CpKVYcU6F#;ze$d?HQ)$A|Mt#*_cAKgwnvpU#D(6UBnw4P_40h!J+Rm!LXm*&VqN zWq|u5(YkoU@>DH-Ig0eb4%`)ZuM^azI(*v1cjoo6-(63#n|o;^a##Nf!B^ao=gs*B zmGT}7s?gnjZE9<1OXNN}%0enQH5?&Q{zt}Ia5={ayJ!hF1878v`?I&zv-jc~U6aVh z*ZPoAYC3i3mdK1OK(;poM(i(Nve@OdUHw|nXKT`DYtm=+*@tx+rA4k11rG240ryS2 z%HE6!hQ=#(pi(gT)K~#3Wy7`;m!Rj^TyX`|XSNXouf7=y3h}6CZ|iAOhVh{Z{TSEQ ziXB*=VH}RCggjDN7?)K>+P|UqN4{#?Q?zKKlx3(YY+}EbB24CzMJb`NA=Nb`>`c;` z#M{5G+cRX?d>6-;8J%R{Mm{=a9*wRnl9pu{kFG3BBOhI!*N5jSj7}8UcSQ(2Wq{Ic zA6JW>w(!SSK5gN12VQmmk!#=h!RR;AKdYILDX!$W-2%39j61x(!KDI2N@!yic6~qF zX<#Homi;%VijHFrVs|2J(eg=YcklCbSA_dE$sZG3kFZ~)PF^*a9qH-GXJ;R>wi6PF zl%{`ui+O>|>s50S)3jAb0IWG}e?~f1%KUMni>O(Bu!jf`=(9K>dmR*lH9w4X%#5!( zHFI$gxEuD)sSo2Cu}Zr$@2R<0JdWGU+_iWrb|4_ss^h1$6%As#(+qx7x}b< z6laGNuEX8})c)@5uY2B0f#j_{3mE+v4||Ua>T=?C>~>dVxAnwZMfVaPn7*H^!?8r* ztONjKz6DR+=ZV;oen$_+648eN%S7D~0o`c0{pibv(I574e$aR}x}yP``@Y+9Qp)tw z_zEtNh4IS=MD=Xnf;+k|C$z~khbjCkk;%kf12tBV;WrS*vfk6A(-GLIQa&wP4L#|{ zuw&Il2IASWb1}+*-lGf&s9eYZ+QwSj55-qLE&ff_=Z|bqeh1JTu#`X>+3^3e2lT0r zzT;&>z}VA0t{oCWOFD zHKTk}dyA14Fz4Cq+SwT`LaW8@^k*b3+R}dLq5pod994iF*?!%1%(5ob08fCsJ(AOK zgWnEfyu_g-`+*(AWriZ8hwR&}QClml1X`j>m{h{SZ%HM_?9=ff~m|i*+pX zn1yS8XGd{S5eP~J7g)#5_i)0PR+veWv?9-+x-jgxr#Q?EUEo6=z+(r1R(HTe)->17 zb9PCSXr6{+J<8qlC;;_7X_R?Yw3An+#bBi}cbI(iP+3i&h<5d(AP7YggdzkXb-~}* z48otd1FB1Qqv^hv7bbo8g7e4*Y0?L2acb4wdV|)1;q8C4J+wijIbq;oO$faJI#dvX zV{t=D+7I+z+O(&`fhgwW@pnd~Uh)x6Pwpc($SCr@UMm_PsFo2ufb;I2`_Xw}DAPzI z(TyVamKW7SR{3~H(LedTx!vh!Vla?r*f4O@yXRi4)d?@gPj1BO8!}th7`aYbdwP~L z?(8FIrQV8-iE|znXbgNetXPqmVtvxZkL;|kb3(F;P_ZCJum8;;sidL zj9tIT$gW1@EFet&9u@29>4yTD+F7w8Tx?b-Mq;%S5&?myZ{Zy|%zbJmJKFQX9%X-b zk-GriFOeH8`(=K(?StI{<3OIW$y3I(Z%9+*@`ZEmx+ak0dUR&VK#wMXRv;n{l;evA zf}Y!1K~(zn^ee$w&oIgf0nmtss1Ng6xJbILZ7EbR84UaWXS@G7-+rPe`6urD6+3}f zx!X@6iOXG$XOZZ9k>j=jSZW{>pfNas9f^m5=#Cj17%j}j>pL6Q8O}0OjG6JFhDtKa z^A>V$UYAD6PN69T5G^tm zGK6k0iU6|gSTk;{^x3C+XgyYXNJF%X^`PdY#U~eUE!Ntxo|sGO?^y#=y43~CM8;{) z59L@7;6z+=KqKk{?tjBN#+4dxM_J?*eW74x#wa%3q1|cvfri)V!0u)_@97EL@IqoliaLkygjmO9C`>t+?Vyeb804@InRIT7=XU&vewcGf3@ z9I10vg3O|p=ceha>*k2#hh8rdyw9Q3sIbigCLqy5o^9RvJ5`bFHB`uU7z49_xCb$W z@{&-=9ZuKF&>y2ewBHrE(K?lLb4@j3a?nA3c+yki3m`}$QjCixPayt?3Pt21@k=&G z=S3G7F#u;o*clB}6r+(Xtb_$3v3B%AYXXE&7(gEs(dkYNTPa&o;uK4e2PH4=d8muK z8s@>zUFeSiZR{zQ9`1Mb*RhK(G=koO9pvVaGcxMK)|KSa-fndLpdoA1$^TMIj!`nHq-Q3 zIqMp73&~{+RDh$jS-+bwD+QipP*Gr3*zV=wL=;M6SDul9B#0P^n5xRh3Q~!K5JGHV5B7??gN3>ZpAMds93S~bb((! zFj~KSKn9jQi<^SO&L!-RlM&Dk(@PWy$}cSiRV0)Ta!cFGE#yF0;d5HRZaBCE38M+n zfQ}Jxz0va5diNBEwu(*rh6%Vu)4t(;i>5(X)+1rSOc0{TjKvg-o?!z5se(uCB_&hsm;7*t9n$b;F;0Ectnra{R$kA}3P0C=)Ej}q zISqitF2yP6QTk}%gjNy35uiahN^m)yZQq+(XL?=sHEjL%C_|F-=Nk%j(1HCM(uH7H zk&Ah`ibG2Z$Raf_GLZwasHSznL^s)4_y-GE{Ewn@7ti+EQBtdS_+Q*;wmRZ4_*_p$lHcqp%$$<8wKuFkF;Wz56P0Bl>o*h+$FhFAr&u_ayw7&g3#EQ>NhuH|F9nL^ zrHseX?6(on6Lpzx)-OkJoUPZR#8e?7@HA3ZzwMzRnrMSe(mu=WupkXn0|vl@eX}24 zRd?_Gm+oDOd&y8HbHNGnC(5eugK8IkS-Ovg!0}X_p%Op`v55PQNG64ch!%z;R_zja ztDJN((Xv?OAzQ~FY8DyO)th~GfWcDN z-z9~w?hZ%9?zf}2)h!W_d0dMsY|8iYYMKcoj4GZM>mXTCkN8w*@N z`r|h-n+mKd2gU5P46o+IRIXdgsvs8pEygR`)M6vvPO!PZTb$eL-yEyQ5+WnJ(eZ84 z#La+YW~Flj&qCwa9x+2q5VLOBm2hLDXJ`{2eKe#by>ceWu1NmaoxW<$)F0~!5vV~? zY=pR`G|ML!_(*H$HyP%7?JEuWJ2FE4hFx68y2DT;C)*{qxEKopKr@E4xo=NMt9scU zFEe-QDsOT&Da5fyxmn^xY^DSmtAK%mWXeC6s`Bp$SuA*=GjK5B2o*%L0*&QhC6vPu zoQoUzsH0B0jdXUb}xDmFoLcDZppkGMRka9E-2}G*S_o361a=>d%zYM&K3w4*aV& zh`dd@^g>U&t)V5agEygCYMlY=mY=8LEC85&D<8X#B?koXwV-MZe~uXRx|gmmR2dBc zWuqmkRety3?9)LqCzxq%+K7u_)6|V2D-$Jy5QYE=+}lOa6HSrUsU{O&H=9YW4eBO{ zupUioh=+y+7~%KwT{LF2OIr99N=rLR?T#p`;=#Qib z%=$Hx2WVbwrhZX+J_)8sJV)~#@%Y5Z#}_+n7f_DBZscp4{=QL1w@*hjKq>^tg}yc% zsYJMaA&*MR3kF9^e=|c)z0_4c6BQ`gon0j_{iAtef1bDw9~b)s5x8nLeVkbY+3?y! zcIz{0vnYWUntIKSKATO*L7VyG`5-^|)UY3C8zbqS7=ujw$DTZwbC(3I&T6w3fRL&Tz`P45Ysqe*J`4o!EH^Pof zLpv@FxEi*Z2=c78DE15Ox_XwL)V0I%!r1|I$ZWd?wb#w+G>lBWPOy9Z?D*47A+7gH z4?4-tWM`BAfOwSsBP7oqkDdW}m1O&o=o!*JJvFH~Z~{TCsg7|CvC3)IRZ}l~^jXG# zX)acCv3q|sKRXk5nv(n4brE#;8D2H&$xPft^7F6^k#PY)wig&{`XGQZ&%-WaY7^E4 zx>r7tk=vNPeRcp%VWQmIUsBJ0WP}_rQ30e`?k$o&G`-nD!PE#w1=q#!#AyMt3(P*? zwmNs^xO1H~ckcL0AAaX#2Aa}2`OmKnaxZ$>!|xn&z_iZk_|)1ucgIl~g+ zYwX-DXJJ~)76dp4^+cJL9H7qG;(8v-n{@WWo}>f!jU%_Yo4(^!Q&xsH8h`RE%)5lrshG@)0k)_)ZxlZc>x|yoM!Z%HtMXxh|If|>K|{EW-ACcY5~7Rz zN@^Q~{LX8DfLfVLv_e{IP6ylWpmb6AWKwy?tbLadowU%vBe!H##H1;mziqpc@9 zv|B1DNUOoxcVU8(FK45gjG+o0V4&y6oHoE4$-Q^6GlAKI8L1I}z>~`zYC%XO zhHOKcluFIjOuEi%z{E=OQ@rAubR~<|p(8;z`@3=4=*~@X0!&n_E_5&Ebt)CL=I*~>%>ac0+kibC)7ce@8( zmLPMPm?b@5dmY(>J&DVthB18@H0gfih~x>c;sc-v;vSn|0)Y%cn|Eg~pS9+drlMx{ zr&1V9@38NA5U_GVkl;PyZn?}i>`Lmx<6hEy>}HBAj#%1n>WIpdS^bt7fB~9ZSgJ_U zV<`W2=3FD+nCvur2udSn5i^2mL|#V3F$Ikn@&bQgxB>&EHtLMz4*g-6*AjEvZP)e+ zJRR?W-Pv_wm7+-#5F1x&V2a0JqP)!o_9gXc1TGXyc{r6_Nz}<+F-sI5p`A=bi#t`; zBh2g+;>%uHfl94ZH9}|MM;nX&u!IpPxM4z3Y=Er}NnpiI4+jO*f1gh;K%WGHmKp4q zQVJw%m_C^&^b7MS}0`C@Bkm+Nxv`MTP$^?o@$aQQp zq3|{TF!L;BWwIHRjG%^cw1x8e{TUoqnaOLZSBHH9_67Z;)VGf;LH{uSqgdJpm8+xL zLG*VIMj8wCqkZslnmPEJ+mp^nbFDa^Zj{3i@!Vvm{`DII=-Kmak=au9I_qpgIdC!yjcyy6D(<&_u^>*ZlTD0x4+k~hxeTNT20=-1|v^yqo zs5&oo&ue0B9(FCKP|BkWZGQSC#3a_b`j@I?;?s9F`7i%s$(OHwF!G-syX4b%9^=0( zZRwlg3p)LxhE9hs5cWl1j&1O@4VHZQNce)~YEhZ1Hu^G;Uh<`&C707LwzY%k4>-}2 zAKZ|WY}#Np-X#s%!k<-?2abUDv*5v5*Jf5ZQvN^w#f)LVM)K5}j_X!mAjANfc#Nqs;HOQYXM{v37BD=eJHd0puF zc)jJHzMqeGye9Hbd)^XCjn_o}=}Im)FaVC%g#YA00ntUdmzZb(*~ei#jLNx&zm>Nf z)Ps0RB68gcO+IpuEXp@5Wv{#MeY=S{;`uB#+15W0U8I;%0spP}WG8is;EQeAA?51+ zNOX``^8fMnE&y^|SDklt_edVAWxJhtgNd_CN!S}XQR^|19Y>oGm86j^tk+5-Teg=S zdS+Uhv1X>n^N=)I9)fkiBmn{h2unypcmzlsU=v6nK%B>hBp5a<0RjXti#Hn}`>nr^ zKuieB{{H9OTU|ZVHInoAEKgU}t@}LpyzV*Y-ue-n9~@G{*NBQ^C!gz`l!nMjKC!QX z^#pSRe)z;*{i_vS-jm4cfSx6*!xy?e?~-c-lTx<2O)0KS4&@CCLhB)a!W z*m=%G;NTHdM{~+49mK%oV9yO929Zq><}yV*6;w^zR7ea&7ezRNK)Q%L$3*vbtvr}( z1n7b6$zKqP$WtQwC^{_eI^2Ek$FlZq>)`vZf>mK7*452q4Wg~fRu#K1tg+5B{NGjUwkktOuFB}%UrY`7$z&$%eWrpA&0qo9 z@HN+W>FY-Wi;>1>Gbd+kzw?f4YTjpS7c|GJRsb8j(-mn(jz=I+m?}(Qnko!cmHSO3xnpDD|Mf-hYy~d1BYE^{lG)dss@hVjvxZJgh(jYf>Twhc{d5y ziX~{OWso42uQ=oK2D|b+n3=aM*$l(rt51X#tQZURYbBW}yJpP#Z z2W;)f9@kVXoU@FKkG~<{S=X)L7RG>?@H;D}qvC8waF@SlIEjJ9=2|ZRFhXhMmF(eP zvXR5q3IE*K^$hf_UyF4xw~-S7&uj;JW9VJiblYdy3hPtX4DjKQy2d@d!d;$AekKdB*B+%@ zh=Li`&^zwP%NR$XDRE{jZ}7h@bPn+bPXd@`J!5Y%-GgVBJF0v2 zkKR_bdCz83g8q|Qq*BC067N1usaHIa&&d`mu%%l-q7K-f7UWglO@UGrvQH2|6eWOZ zwb(RWl5x^e5s74ky08I4r&~>f<4^5E`Ud z4=!5#O@GdY*ks_+5vtn8n!WkjIBZ2ONy}u|oEc&m{UMji6=3j3x>amf)bkEIAu#)U zlDm6>S%4+Z2(Q9@2RbF znnvsDRkscGsKUoA)YH~l&7WX%NxRIYcvV91NJYUTm78H;oU3V_fTko$diXxP9Of@o zxy*8V91AC;Ed#6>-*m_EI7gUnskxlEBT9XOBhf01ta=Dro%9ag0#0z~KM#i8@0>OB zehkt6v5W6A3%{~xi)p=SW>h-&YKdPfjpnC)~@qPLXd;iL{)EnK~l{yOI)(- z=D45$t}H3hTIf(KXtn7o+DK~jm39b7wAONWjx{45V){2-iT@~UnzEGa^%nk9t?7)A z^%!^+F1FruXw;G6Yly0WG1Z8=moANjgbOMa!y zPk5lK_lis^D;4@MMsGDsb;^6c7dVB&s%Q%8cYDC z2%1x0zFM1f627Aj(Fi^jq852qWv!sFKBhv$VZV?pTDtr?PAsY-(m)OY5zcR1Tlb(^ zMT<%gGDq|GvBb}84W+Xbt){S&=`X!;kHvXB19zaMY6#pz~c5X8Q1NE2%WX&)g)iv=Sn)?!_TuW?w=Dj8X*8kS0lC#YHng*M*cz~YQ!X1pe?&O+b& zcURj2#0bI3&0;TF|Jx>e@6$Hz`Ve04gzxP8wo8{D<|8zq-J_4Zh1h%6J@xu8)v5#T zN3yLQedR~dX~f`y%jct73Rh~1Zsb^lVswG8pWOCmPTP#haSh=nb6#49bN>q(S5+F< zKuw_QG7IpKP(P;~VkkrvKq)F*HJMQmZC&3lj7m0-${LtX{lUh_1W3fMbKfr)*%EIl zs#|!}e;UzE*K^;mXm$8cmmh|D1AHw zvox4eWk0FEqhdQap*{%~#IcxD0u+(PIH+~kJs7I-UGgs15KsCh5LOi{VtoUujkiI8 zcGRMDG4HWwMsCaRDLah4(FAY+giBiSReP|5N#8I3vY3GoHY~_Rf7&>qnUnmkx7BCU zuxs=WMFDL6r_a{1pZ@J6`{`$Azq-*5l9DBZlGME!4xkZ&s9Jin939XHmN3IGlAmXt z;9ZBm${}lxQz8-S3_;SKOZ{V&Y6a{D*jlReFXt!bMmO7 zep5JKJ2NIZ|JEje`l~AV?AIc|YOsn{;eI9}8oz9MpmZdGo^JzjB%??H-?}5DW@0lC zCjQ^%x#AjB4b%eZ%IUFwuFvFOcHG7mYR(q8Xu7Us;Gf=I9c1$lLw}P_W$9=CgbdJ; z_ypFkKQDrHjx_4mTAD@CX7J*T)uPJ_uyt+_>-GkKNQ1Z59;v>lb_r^2eB5JRNV-JQajIlZ7|$>2Z(}1a!2}-ta7WId zsdO+gW+P9804)KGfi8>*LpJbg$fJky`brnF+~|~Nt9jY%Y$bfPfN!+M8rNy9l9C7} zWJ53?geR<)I8;_;BC~<)6Hi+Js%DUFFjykB)Z&C?EfRD(skyED6W01(w%hmULWr}n z5kpxH)u-uc0jf_|UQ|16(`l>J#_vlplwI5n`I^KyA5Zm`e2S9aXeBXDKyc^4dM$QUGdeV0M8HR{|Wgq7`7#;c#q~^9MW>;{fFKktV#th;%3CL9k zbuH6Y-5k_8NBf!2d#tZbl`X6};QNgO?AStmu(a@*b@XZ~~aDhnE4o zq54{YkJ2T=UkBE#hX186*g!-mpt^|??Ito*w;3&;3K{UB)XnRpBdo9O<;k5&hMb7qsO^k1=D8FR$s&gr_D5kCgKVsG=i{pvf=0hkDk|l7Fee?@6RG@Q&$*3|`mJSA^O| zElkm`}PkD)gdejwIczj+*jLtc99gvL%}^$5GdawDE^x&9?f7chcs= zu#}|n;cGXoTMs>e)GS!nl^iw-3V&1ql2Uk4TC(b)Yt~goMPXg^sj&G;whY?>1zmB< zq%V+A^l4dM6U+eC2P+x^Q=aM;wF1KEYK*twn`J8Y2``obb;sMjLe*;hR9w=t-q@3T zO}CRZMc7#=K@FRZ_G;C#&zPa5X6@Fp3W&;7Qi@yo^XcL@vTrnX#Dro_}92a*p45TIslQ{ zr$pBQ>B17BKQBnK=eeR1kUr4A(Rg6nK~XWn2RzvaK#L;#MpF?npqXgB`3tYHbwN(# zW+FD~)=B`LBQD-wVL_kK$V#oYY$i8r6KMZI81ic|%mjvf7wuQG4;w>f=8fR^ur_Bv z^>Sqq+#lKc`w><{zH`WQj4nf#N(zA&m*B32)Id$_34KwM7DFH`>`VL;_%W@{DghVz z&yQRO6Iw%Ct91wWYYgr`|3tn{VLS|ukY_od)}Rk+XNe}Wd=z0fI^G)kIL^V9%;7Ga z)0TI%&2J-Ag04j?#WfXP-RNE^PzpWRmEH;Ma%K^nT`BIh!A63ER0QUCOnwzI?z-q#!ifMFZfK*1p45G2!h8s^PJ zlu}M%C~spZPj+3HHk9DJToZS4q_MbaX)9_xs!kSzFQkD9Inr=Js>$dPj9jL0nOu+& z3(0{MlnN-5#{y{#U27LFJ$4IWx*7$$mN3ISt#rUjp(7klj2yFAV024Ad=5_WAzLzW7Zy{O0msnQpehOV{jgFomT zFnBa!d(^5k4AOP7k%*7l`DfBF;C21^GM_SdhB*9_O#ENn9690^oA|C1dL<5vrGT}K zAC>5p37_ZJQ^OB_Am=-&Rbg&q1Y5F6^JN~5j|aCw3=wj=kSkwwplnjDRt9PADZ&i2 z2;$<03|Q1|x(f*R33HZHC&G{|m7$-1TF0m^MBYzLT=4r|j`zFm^~!m_)JTmf z&~#s=R2V4{YLpsqDXcYd`7&teMgO#{uViofVH+=*$r|_G*dnvPV8K4=yoR2j*ENc8 zcr|c%=lgOYCu0e^(RT_!D<=>c}2Ed%)mn0t#yBCV74MK+@2y&st8=w9AJ(A(ai|F3N=3|RwEx3X+&GSvj@S#2EW*vSF+VR zXyH9xQ{z)!36mIx6+&g{um)c2C3)oDUD;R7o_cFvHTRbc`%?}vr8AL&wZ%H*+MCXy zXU(BD0Ip|HxJeFNo#@HiUf?ouJs@!4S}g@IiDtSJU|=#eOMTHk(7u9KY@O+q%h=bc zav%0Eld6I%pVS=0MXkue*_|zFnjRX}$N`Zi3EdPp>GX=9)&ow2C)eu@K&Ulrrlgxp`KlGRmK&V z+$4vTkg#!U4g}qwA*3(_kM)Ve^no*`6$3A(Fm!;U6rat<1p*CSR}Ec!Q$rU%JuVP9 zsPY9^uw&_xD|<Xm7c8u_pfSUraWnDAw8WE~L_YgS;R>!tK+DP$_| zCM+fT*JVZ4dmFRMZbN?|AH#s9rt9Qbv?m&t=}**Ld?trdwp2gOT(HGmJ?YwhT-T+5 zpb?=X1Sudye@*3?*vKCP!3(Gm0ra|mer87U$RMg2e!Tu10+;>gDt;RG8oLk@!e&A= zN059TmhkZ)@&u!ZX9T8b`O;;I+?pi>AmPDz1}n55K!UTW)tt7%r=Yh5>aW2?FS9h$ z#Fj7H>_aEHwrmPO;|H&+|91Ce%D!GVp&LUAL)X;HeniUS0)}{`4HP$|P!R{@rV20f zZ5ALEh@+lSOjw`W%2f^p%FC&wj-gZ7Og9&psm7bhD?n@LhCh`7Hm>%E2;r#ZWm__q z%UJvrO(>Hc0h8WaEG4S9l0EsihEkQySeOU0Ep{5TtVvoQecB`e3rN#K!?^Jh+rpD? zG1Izq#<2On@BoRX18!d2QhkIxcJeVxX$~4tx@OXXpVS#y!sXYe6=_PoCu*IjGOrx^ z^P>YKjLK(p9pC)d6RJ5MYt7DxuU zxUTW4Yd1CE>;q}z;O48vaZGR$u&2Haq#IPhrS%VGmvjUin&s7G;oODn(zCrfR3m^! zPOD1i5)Pyr*Qn}7s^TcVZdLW{pU*0-Uv(R-x(x?6ugiND&cMResh&MXoYZ3$7f(N| zXZ7s8|A$YZJ(kQfR^}9q!eTS}@);%xI>gU;UE_T~dEr+nF1KN@QZ zmgKxR(u|r`?gT@F7c*s?JqpZcd|Omfe`i;umYi}2CMtq7d-IL?qBxU`Lpk(?aS~%e z*Twa$nSXu{w-0?)XsGE#HIXopp>#zm61ofU#?1m8H?0@rKuWNbs1f=p1AqCsGU@vI z8`f9XIjh_Y_v^1$2JZIzLDp5-ibHRHSY~XsjNR4_g^@*zjX8gu+d}D|vQ|0JP^6$k zNR*IW-S{M&3samn^hglci6Vf1OXKfl))DeBi{efks;)Gto7?QX)_dp%lDk|?*RWI6 zqmG{tFRsNlUn^v6*vtSTdw8VX7=8;=3@;d21&GMF8A8g!%p_SYY*vKn5}qoyyZ$^` z2ha0)O0FApl?p_aJ>>efxBEoVm#(JFhNr&MgrfWw#iD^^-z7{?2vROIJ!SxiUxP#IvN5LXn~AI)wd|{loCJf8M5rq{ zT&&_+_J#k?*CQfT+R%k)Jz9y&5HZWrX{gm-0B9jFRwuyn72i2vi-GTDC*))PRaqxN z>DTq`F{{FcU-5`%{kBT>>mhW&Cy7}nvvBl@XIIy|c>IO3h)jc^tpkCOMCCL22egg- zGvU|1_}R~S&JEA${qM$qkv~7{ImAIUuD|X%0~~mC^@eM%<;}YF&v_2tczCY@{6VqW3ItvhVwF*IW!<3CO`hFWL0kilu=ljXx_Cd>sY9yIT<6 zM?rG}3}5pcZeivtOZMyEYt+B5js44AO4h~h0T|u!U{}mI`Y4PiwN}v}EdR=LU^Ko< z4^O|1_=*j!6pncUb-%A^)?);DkjGo}*|rdy4!Vo)q%u9&GE+ z^?mYxn*4k)Jr>w&4G?2s1$3Ur$_AdGz#r$kmG83r3b?QW#&TEm=o1w9o8Qd6Q^&0Y z(YaniOV^c6e2fym_`bZvX)8h8sh3dH>BEO9jhkL##c=^Han|14 zW-(b;^Su^R*bNAqD=u>X?&{5^Kw(Wm(90Idnh@yS+e?!L4O$2t%?&70AuxS4mT2Yk_N}1VDkD`e%pgX0LhJ)f|gAl-JX2 zX=^Z1nWxGZ3Kncuz=bP@;q|Lw2#@(vVb~BAe%WF8TPt9A=@nmI7~+>H;`$ZCaMNlS zre8V?)2|2&iNfo_!>7K?FbuBcpMl_iv>P~a31Wf`uy+~pB^yZGB_)fd5!p5Cv}Y_V zH_$JTP%Jg_*S0gvww|Ko=jP!}=y6hKl=h+Cfw?I)$)5NQ#}P=}>PN29wU6zJ%F z*(0H6(yn%(T(Q$862B^c+t;|`oYfxCQ>^A^EYefilg0;avE)5gO5hq|d{W}ddiJSw$rSe%+x@j-|J6)PY*3_yaIk!Sl|5u#@w<6-X`1C#CXbfZ`U8G`uD&wik5v=0j*e$!O{Tm znnI}*B2FFsZ4aQL)~Wb9W!v>lx+Z)Ye<%wh+HZe@tgO4jQsTwVMut`A$(5@Y*K|tjc!E*I!#@d!9q0@0t$T$T*33 zqZ);o$@9S-UEf?IWEaByXMNgJmE)Svj@ zzFw1)8t$XoWEZWOo?*sWeKSSO_35XA^U_W;xby_JnQHd3hd{sei!$2GgW4F!2N&mA z)N-?7ab9L}%o$_0?at?~{}PtDxwSgDxwy*?m^9uY3nC-K?bUdi-GHU@SKlLS_G1;y z9#ge%zyM?wm$^l^)yAjz7Pu#+I^+!?C3bRyo!k4W3Y9p%m-W)l;rmTHMP3GS93|qZ zOmXZf3D#5VYxc%JFQ8#@Kv<=HKxK$l|0Xk4iNKQTUZ8I)%RO#}`1{Hsed!8aHKY?B zqfOl$ZCkMpZJ2hV5|%-90>MFy8=4F{7S=ti>g$ggU>;Opk}xpDE7kusFv_m#MU>b1 z!XEUDu7Uc!U;Mo4>&9io=$0j#VFPSZzmrMHY|hwxjLB4N0bF2AgTok4m_ZJ=+FZR! zPMk`%C)-BN0OO{{=daQ6kN9t`K>fSI?83Fz;ARLTwn8A)tu|QFK;!-9DExzBVl^cG zRxz<+i6GiWbPY2#^=~Jszn)$4aZhaj&e)Xyo@$pE_gTgR{1?#j_1;vY@=1`{&z z`JC$2wX6BhKcBrlI-Vl>k=m1bK)Uy9*k}m$f!&s0IE0v#9rjeWeQZCk=C_XRgQ_Q~W?63Rw*0L?c)Z z?-LgUtaJ1Jog6^(*(|5LhfZuYH@aN5&!cs=Yp{a?G|RDD#!!WHybuJ3Ro0ooD!X}% zRnQ$7QY{97*ruv+>&=5%IFQvsCTi)RG3g!P%#A=ByiEctR>%TKi_=fF+NLIPx$glp zM2IyxE5C{&()+$jdLPGh{rq+IA?whx0pf#(5LH`r(6}T52zgbuPRG_?mD#82ioIyW zUif*ZgK(7fv+jfz9ax;7AS0|t~LK|Sc@gFkL4gW@CvzS)3;y`7TWhKn%Vd5^NtZ|eX) zNbks2xudKj(hFC6r9yv_?5m0$f!(Mhj8Pq7zt)?rBQz{h*-@r7*6KfBL7oE+O3K%p zU|iZ%#x?9R_hu)OXk94z%0_Ti;J z8+hrfD)}ZqaZ)}?NQcF6)5^RE?Cn*=y#@Xtvil<(Kw~;;dj(j|r*^R|(ExMfbZ`?A zpTmeC)Id|HmZ}^E17BwVT1hr}sk;F*{W%B=8)tJC)}lBl+YV!XSKK3}9%jV9%CE_X zL)@>4c5i;oO4qMxJ|S_&FTA0L6@u~fV=Y#gBBX$T>21G0$bl0zJ8+`(+(yy31wC2# zldKM}!^H9WJcc0^BuT|4C7B_x@$_-dAV}b8#gmyTq(C*Bl$-aPDz4u52UKqFgt8?M zeD|}q1&N5Z_n=bt_;)(;;^sHb`)<87WLQAuP=> zA+~MA9vZKdW;)2xV7%o$-+;{i{zrNwzA09i&Iaf?d7@3|CEXTYvQo^erI*BpHrC4a zIdfJj=V}w9;n7NJf9r$U|M|syGZBYw3LK=H^U31M`(h6(O~ammHGL-*dI+*1u?flk z{OO+6lr8E7{4!k*byocmz}2m4wp-KQi^i%tqOneoRJNBm_3!o=3`A%dQrkfQHn9Pz zw=l`^(9Sfn13n{!K}X0gZ>gQ*S<|y$;1BXIA@w;?3pEYjY|EGLf9%5LTV>|u&xSgJZEX&Yry#mI&d+OI^8}8Nymdrvi?8dT586g6QHh3mddn4+#!9yl5*tlE0_?4DVPlKI{$^Ck610C(984)}ox zwDnQ(sZt81Z+v>4z6mf~nhBb&nZx`uy}lHa_^g`vycE76F4gw2}vaX$X#8Rzp&6KW=W*Zv_!Q?-ww5BH2oLH0 zMWv+EgX;A6OS@gmzE^@ywSZ2Wnfow}8>w$oQifQyfLOW)#40nge9xD!Px{pLGw4xY zX;%L-_D3Jr{*wFio(f?_)xEGnKeEIrXHzYE>81*b15D9A*{mCg|NLgY6qex{&uWX= z6Q8}B#krO+Xs5cY$3Ve?4fSO``Vrrn-kKoR__>Sy0yk|^F0QhVMqKND^4M>Y$=pd2ws4feq3zy9Cj&Qw7s1jE6B~>A^aTGmmexiYkh7 zWlbZUrbGk_oy)Ajcmv-39UkBGn>S?d#c{{Rhz-DHYf{T9OZ7|DYAs(X_19J~@Mz_V z;-y`4wvLuHHEKWMC?fflqT{cx7C?a*VeP8Ct#WMr!z=>DMt_`{%p2ANvP$ zAlPB{1Xf7E=>Tv-PPN~l3@&NK!cARUDlrK;Fq#6!L-il4^f~3PzgaFHj5Kr5l)g)o zv%^2l5&_Dlb|Pq!{Tuq255^Xr>h(MSkB=#j6$U}E1e6b^{^qLl%DrXwtqM>hu=)+Z zm8;dPWk5z9;Seo(?|z<~%(k&a*@@JCPadf)?NDeI@)Dm5L89O=b-lW8#WJEf{du9P z^ug?ZzOrXMVbPiKF#K*csxk&y+DC-6#!)nINo%~cZdhv~gwjCWYW=;nd`DYfs`K+_ zZ9w?fpL9d0Ey9peoIGoa%hTcdSG>-3uwd$74z^l?XjYBj zxMn1>T4*sLlU5{EVRvp@3&x6sGrxN^Tcbzl%q?673pTNSzw5cutTj$sP3bgR<79nj z2kX(YyjOv@tf?2o1C+#qvroO#I5vZDa-_>z<*-tM71N;Y7jzz7x{Pr>ORI27aFIwc zl~8r!0gUIXqjE3?rP-2Q4e)p9CUX@I=vdME_lv9A37#0BO1P@4$BJUE?nOu;M?&0j z2(F-&u)g$F-kLHi9(zg80~?Z|*cOzqS($5%GX?%CkZl4RFgy3mWA@m$2Lnp(sSDeA z;0zR~mWr9QBJa0Wr6u64vd1f+)}Sn34ndZ7){pw%nt#wm99P@ zCkr6PL$QJ$&l;3U4Zns9ea$6UrT%?|#b61ZhefMwjdWVU3>m28mKDLqmc06^mC+H8 zoW$?l68V90gsTW&Ie3D-OvIjCrc0OG6!x6nsW3(kGP+Uzv*9d}`u7Gut4tbYa}YZp zPM827lR4<-PL zTZc1$f(s3oNcF$5uOWHRg2usQ_@`bB)0ndVV%|WU zUuLW{iY}Q}He-cpMx3vw(@wR7xWG_Oyp0#K5&ko&s_m% zO?^3ru#)H~sUYAQF*&w5?JxgPnv9Npfwq)}qV(CPW14Np$hI^-eQk!F9b&<~$Bgia z%f_pL1&r`|HizD%>z$3il3&!Y7~Sl*o|Gjr)En^Rsdwk`;Q425-oe+PMaQ>tinS@q z#=6r~Oc?lE(1?n&A}JIHkqfae`ZkO@ghh-#=;Y^0c5CCWZTVZKLe;+tIA}aKn9)fa zyDAnB(Ii!MAz2^vFeMG&UK3N{6}wG>7>i;pI4!%iOnvcjADbAA#q(G{z&gexn(8lb z>XVmk$tTTgt5|Ig?xMtSaIP70veUrD^cVV7$^IlU=$OGPd$#wslKp8S@W1@a*fobr zoaxI#g}^*Bx0Dfs%wNxw4h(3))~8;Z+s*T@JO#|GiXvW@fBUL{xav|f`In&<_~6ey zmaj(yrhvc-u>qAiQQ(z+YP-=Bv{q?6rQ9V2z zUKuo;E!X-pi46S)(*`Jmr^UprVn^irsXXKyLP}cp-M^GmGOgo7HekVC2JB-t1Qtkb zw2vK_{-}fgg?SvPM;`O2Vw(L+4nLN^oYPCCkgp4l*>dfw{_ct!HOegTnvjj%2`Nl# zVcv}47_{F-{7^K2cPGr}72lp=2aKmMuNtj_?x>@Zr7#S~OQzd{)yg<~{pLh43HewU z8r6tf7Uyn=>cgu-ULi=HzOu+q28a-g+n4KyRtq#6xak*On@?c@S$#NYQ<0XH8`Jg= zzCF(!LEu?|D_>l5wolka0+d94JB)&GFTh z$aYI{BEZ@{)qtE6$a8iDm>oIun9?{nNsSu{>kNaqXn}F3W#Z|A^I?{UCFq%ZHgwPk zzGeYN{Ic<#A+l9V3zmCknzIjhNL5x4mJqYQ&dT!oSMrViZ^G5ze-U0$5V|%3Fp;bq zvNz=?v~EFJGFl8KBIVHOm3WGYY&y)7JfVQGsFmjNFsZ9*z8^an34Y7Z5z3|%EgfMda{du#lqDj_fY4}3VM zR>j=~s~HMug%UXVsJn?m6adtTZbDLuX|f+9^T*j&?A;`iTZn~wkLS=rw_%g!KY${Ig=ZOPPxsD2SO-_`j-C0gQ3WkJxF z@VX2XRB+lT*nCVvh-;Z}a4ia4^H>M)ADcw>|5)%?C2LAhD{usPf`P)$>0T(gbRA!IrOjWYC+l}J8D_7DUlMG z4N3#7WyiCh<#a?rZvH{}vN(+KT(;rRP3by{WppwfD5M{=^nt|(<)B7@Id>u|Pv0e$ zQ3GP;_;c>|VYuAkmo0ut0cG_C)t9{I#b(RXe zl`Df2`=v|p2q(;d)(THOQ$THUKt0g|sProWDB1{s(jtw|ALu)$LZMr0-{{t0?j~KM zl)eZ|-~jr`UXcCuD@AJ&mv)rn5__>rV05W+86T@!U;*)KT{X2=qXf-Ju%(0bCHv?X z@`Y%T+S9Tge7s>H&LG$-NnW@^+y58110=uKLQB`A9_76r4gTuCZrl^qc4g#hI8VK3@PgsX?19UB$gE_ji=( z)`%d^lCAF5Ke5-rYimhGyQr+ae|lWqwGb>YFMIoUNg#uT8$v;r9q=cZH;fmLOv)L<`!-zKynf$?Z~5l8WIN`?lh^IL`W|L? zJpuUx_6b5t;nJ55xub`nni?+sUN8FV(CT?9a*iaf|CDrq}b#-?W#r*my-Bj zu_v-rm;tIBfyIwjE@=^RZ|d@jhL*9m;HQ_SfoztwpggXnyNm_5|E>$z0@GoIs8y_Z zV9C%Pyo`pz2nP$J)xz4y2{1nSX9aRX0tIp^h2nD@iiO$?c0YQ>BI`Fb7P-Lo$f57Yf?9}Tr^xT%RMImz1&de#w>B9CfE+roZ-?#MpyBV)-U%CB z_C16BRM}Gg@sZ2pK^$Y`2n<^0GVxvrXR`>hyAV(>kQu*hu8Cf?@%yf$^O_mTb=L=} zA3B0d{JP@e0IbsDAh(-9nq&|wEG4S@qd;qvsh!A5x>PW)Xo)NevW}IJ5W@0&th!7j zMQrKDzx2*oS5%6SZE#KrYZ`Wbq868NmrD0iQ1k88Z=zC^i;DptwO(i@H)5J&a$wHd zmCAI^atlMTi$oo1^V)ztC}Bk|eTNau9Rj?WhYR+ zW3=yXu{TZmK1w#fogcpbD#J01DA!|u@P zF-g%5V1mo{ zL~9E^WNXy}WmDg>f7DcLPUNObvVXF9sb7J!NAw;>Eb^=WV%2rCC(764c@e=tJndJy z`ee@2B0ND}Llv@$m3{lG@=4EGnadvwRnv4Ulvhj%6Gisz@0GR}7}E+d3uh~c*}~FH zGDYX<1}V$E@p`S++!_Se_7zZpvciH5*F4IDx5^t;E z80~E<;M*E)NoN-i-WW^>{z0MgxRrsv1oXlG6hy-1RvQ60uU@4&ZgSpHSUdPiq#R0D zI1m5u>YNICVH2t4OK#zZ-u0Dkp>%#PKZZEJ9LS?-26gnoC=>7C4s@%3viX=+Co}BF zd`oV%e*Vg6?SFNHEpi%{mPJ*pRFcNeX;(drwNcQ%c~?qoKUBF)yG&!_t=AzgD~-2Z zXUy58_+S4bC4u8hPiU+?Tubt z{38Zk4rq>pzk@^B|5xsd%ek{>Q_rflX_2b2ls?wYS(q*@cX+>&C5vx`wGa}egeSkX zf{84CucE{)OfOa%ZbEw>csMsQ(#vnr|V_+3zV_=dQLqX1H{~Zxd_4@5=j-CO6T|Ffwp}vS>W)%D4Es85_ zO&XjrkY{XBEGS<^T)V7AF_`&413#6@5vo4vY&yQ9u z$-|=Mj_T_owbf^?I>c-OO{u`P}A!fg3u)z0WzR(%Kx)o^5nKxBnT zxPt1B<)7SIEoB3-YGlWg&xv^p4EVWqAQ)U9vX-PcAg*NvPE#gE{?S}5rtC{bECc>(fV zVXcDKSALu529;ypxgvAGx;h@Obgzcdo5}Ou|SNOJf2+rn`#( z)-sMds&>&5R@UY5MNVu;y#gy!2H)lJg~1z-AMC|SAl2pZk>{-K;BXng$_@IBSH^HY zQuuO%GaQF|WZdOU=5?1{{Glz&a4$i}xc+P3u;;Lv!6^Lc8%kN9A=4^eTZ#&oF4wcr zqffp+Uyu~0rFZ&qNdx{!*6Qo8|?K$GuSZ^sR zNz(u+6<9-&mVB8D_58pG%BKl878Oys^Hs;Ro`q%)QWu6~@<#em$x``4mm96|kghuD zLeyh+T^D`a;vAHX?){EVa1iHb!0$0V#uYMg2V;${kQD&13J;;7r~5cieI;2s4zzE> zuQFvH-7$2rZ-43W;0nzv;D2yrh)Gca{|AVcY9(i*!dTW77gs0+GC!FtFtTLDQIMfP z$SmjOj7cV7rx_%{ZW6|i0lql=2M zFY&77sP@Z2``ufz^Ha;Qa8#AKUJ!G3R8>v=ukOW_s=1IVp^z(bpT)OO$JTxozM1SB&1w1qggargVeqTr(@Gqot8m;PPmpLC~wWHD5UdJmsUCNvPEMR%L8l9t$zFY|& z2K3Pe52iv!`y6#{5b7kPE6FjR`C+S6k;{}~zOt^6j<(;UdMK@i{S#H~pQzr9iFL(6 zSEY&=wumGH7+u!|ee=kKPyF&KKkm6`n=T{zz@pQhpu(`k!RRcRVJ2uWLg;D$Dv|DT z1T@}#P2(Nc)ZcY=bz^=$QU7mWa8iURZ;fBNhAH06&j3u8Gw5wBNQtYUkWCv{LOk}h z=Qa;29C$DQZBRfPyjk-yAk9dz{~L51!iMad!9J9L>bHW)gK}^nW*V;{_TfR{EDyp? zJGSFHghlL=YS_)22w-bd_?uW2{zj)3**s})M{t+(sr*tM+kZz>P#N?%{A zEB27h0}5*w=F`NbG_7rB0}-8>$2DXtl=f+YfB8H zx~)@rNr3*JWC4csOfz*g5x*k&f4=4>JN??g@sbC#AL&A)5g>*f?m~>sQm^Y~(XJSq z^Im|h7r@pFZv^D64`#pd54qV;6IpWr0~|YP-oA)vumh@`jJrM)CXqlC!A(@s1-7Oz zjKDi@Z-4ML>IIX~_;zA}KvK#NunR5@Pex2>3H?v5TDRFy{aZF|^eth7PzPIAj9Tmh z%QX(k1vCZ5I_v)ie`)}6P9oL!;pwbULS9cWH7cO#;73#BY+D6C6HYO9SWh>6gC6aii4miHH&2jG()D z9nz0)u)sSXO>2+tOTXh`z?@wFY&IS3OCNd5%|x`nrT*0d1Dg4x>40a^IrPc(d>S&o zq0qWV)Ajx~x&B|6|Jus*yt(SpbTH=mmr4DWP_Ob(IK9f>4L+J)9drGwBpk=dq1Dy5 zq*Zk)t?|EZ8aLPLpZvszH?2$fo_hUP-Z${S-}Bz2GuNJPEq3O=CHW8Awr%_7{P~-{ zse7ADO|)CnqZgN7p0qEvX6B~bcE9cH%afVTM0YxDw8`7e^Ns+w<+t_+)!#YGHAHImynDkn(16YW8fpIN45D<~Y$_ zSejm37@k%3kG1q~XFhFB zPj|*!*3e9QrZd01HNDV&{(L)~=`1X!(^Kc#)5~dRX)*1bNj*byust@v)S~XMZ_U~@ zotkN#otjnB!qUu)y;_=HPFizw`dwO_?97i&v;jeTVzjle(4HCVrnhD%Mi)9~7B95s z+p9B;cLdwTb~@LYnq5ru!g>1CcxRzC*`AnhO?ThUx98^D3+>rO26n!kPPV6~#*6QP z^MXLz8GEojzL=hCFDISx@uj)e?6@E{F?MluzCE!tJ7EbEo$;j^Dof`(oyBx!3Al{4 zV_AW4e!jJw%ys5Q=37(K)O!>R$Sm<%HxXS-(5kT3njftCMPN zIXTj?%fb06dm^QXPSmiR98a4=%TTU<_uFq~zs=(*Da}LnyWf5@{oXRO{g#RCw=5^K z7n6mli^)uDah^+Oe(LPSBy~VuOvb0?8RePj_QhmWm^i8zqmaSOwqg%1CI>EB4=!2{ zE?N&RCj02Y#Y8>emmcs-5BS|@zb{PFbjRr(7n74dU4VMki>0Vbq@Nwllr72n|`v@pN}<>_R#; zdm*RybhdqgVecNd-&tOg0|@Mnzv+4M)psE|+Bu)>8=YF{ zj6x~xhnA+!C*z%^S+RzR_W9%(e+OENt+CcZJH0LpY*zcju$3c6qD%ug(ATLd`C5+DlM+OrcP^QqanC8aMc z&CPY@RbDJ&x}BZ@*%uZe*w*|+$dxUfg&u@Pvs?^krkU12L>F4;+tcmYvx}3XmfC_X zjZRJY!?!Sux%R|J8wzhNwvV^wTQi4M*6M;oay#FK>f7^B^P(pJk3Dn{0F`@JP&UV@t$J=v@NoRWMY-grDuiS!i0)p_H7t%vy5dfz% z3-KqB3(zMqGBJcalQ9NHYKdJ+YPQD5mF?_2aEK2KmZZ^rQ;UbVN**K^C#KGFiE;;E zj@pGh2x6iCh@@xwaApzRG z`BtPM#}dc9WR6~eERY_JaW^%)z|eGAL=KHQJ5IQa$NT;BZE$1427lz_(%II0V7!8j ziQoxPhG_%_)O3tLXuJi0584I(Dy(F(#}T_to(zL#m!_xZ7UxG7lMCaMEnRiFBV2dh z&dm~7aQp6%vTKN&Q;W&SVsdgZnOvTmY|l1lre>EGKnM8BLc6&DR!#5>9xt@#n_t(1 z*9+Sgre5COa%=i^FHMh4PaIvE>3J=*Ux0yi(pe-8pka>37RH$nk_`k=5$J(IdS<>e zgJfI;1Ef@RMumtANze{Vw+N6~2o!nzz`jw5!;7Qi(+E>^hfX@vnq5u<_Btk@aTt?M zn<=!0CNk?9(L!?S=B7J)RSZ7Da zyU%D%qfr5wB1datVsv(VVN`k*VrsE7nm?@O;-;=dp3a=xT(w6pEX|JtGQnyACJ6!{ z_Rws_k?7)?>DdK{%#*=7Al{Q2k}O9oHP=CH8bj6fRH;cPK-aVF(LekOgg` zT}>>t)5T7D%R=gWS1bzgvba3gCh-|$-J|Rv&3uAd!d$gmGwG(6LMukZ$-+F;JH_Oo zPmi|e=abf~xVzng{zxrU9tn573piubMvkgjh=@ob>TktOkL1CAt zzbwCt96Nd0OlKAa9&*&e0eNFeHFwAqgzMCqDR|fv8nyb4yjpCZMb%E}5P2xuUIsxH z!!ro!FHWA?zkm27M0PZ$fO2R6{&s>U)j(hI4e&Lv^wh|~=FZz;C$w~yX4ARW)O-Tz zOSH6Sw%KI7^rh(`9!8j$J$sH@hR%idJgluXF+4jCnM@p)`c2XW>Y&j%Py)i4ZO(P3 zmw|QCfiUJ1>mDl11ovU0K&qA=;mjRyEP2`Z{IaO(yHzCfa_eW11**AP* zboj)HV<+~c$LBlX+e~_4ati%J)oW0#nEB+~SuHH!lm?@PrSZx1%(ETP|wql|xLTYCz_Klsi z7SiR;5{l1qI*Do?6p~gtwscmS@WRy0#DmOr(j~*u36@_V#q2q{foA&2|EwGuc_1 zo{&jmX%=P+Lt~74(*3B!^PTCJq$BCq?b(B6VnO=ngg7l$3|lF)U?@};MR$92l7$2- zChCi_MT>>W`Syk068n)VO#kuD0!A%H0T=3!f<;AYQ)(6;eZ3s@yxS}P>Y8UkKiLp^F7CmWk6k~*GGXbl#*qH%&RkWMrN>9Hx zCXEX@QHRd9@@IH5?P6(4j!zrvO+jUoEq?dgFRe&PY-$Oe%uO#X_#I{m#J1nNu=e{2 z=0ws{xu+RHa}oUU$Ftxg(@{*p9w#c$uP>vL37(h6tOG3Rw%ocWg_|rcrwf?ll3D&H zm*9n%tyri|PjTm#k(oBPNA8?n9@mvWtdYr)krRhb&n6@Akp0==;o0N>gG_hNVxH0s zzxiEjJlqb&8;m!eEnbJh^R5@z4dyLsq9WP3@|&^om_&`?Wq#8di%I!SE2db7uoqc< z@j4WqY0`SEuI~(EQ0Mb|I-TFsO7|h%6(7=}{GMv_dyS!x#Y-wfsAIb|H)NNc>CRMl z`?&gDmfs!syPcMCHsv1>o(b3Sa2*TRp>So@74rFYJUowu>(I_{Gn-O{Rp{68@H`f- zWb_x9Jwismj)&*5a2*O)fVV4T3^&ZTrwAZwi#ZB8s9g!nqu*%s5el=3!(bLQA38|d z`q8>iS2rGOmF-s3ZWE-t>RiDJcgA;eCe7^V(SF)+A~tZ#Y|-{2^!{+&7p_^jYI^nlP`K_7*DPGsGk@>bec?F^S3qa)0ba=GR|XKC{fdR! zp7)0C&nKw>OV9=O#M~{LL!&+36)bpJcc04sG4F_4XzPF>-mA)*3-i(PFQ5 zHn-$$$QrmjeQU9)1DI#$$E?+{j+!32f9tN3TX&z_dfSOxn?p?l*Tv;2L1S(T1!xNE zUAwt!>u#V)=d8%dt-DTa-F;%~Z6~+hPO00QTSBqe;BC#$Mf`TN%hLvSu7YFdB38eq z#<@GMs!)j+Uc_13@<|)It2wtkj|w$J+Y@S9MjCl=$GGoj^0@0r8s1_=I_dcqCNaBA zjNwj{nJmG$H5CevvqWfPW8b4fm{n1X?Ny0q&fXr8sWj=Xl=tkxXv3<-Y)ni!=Hcli zU-FDf{$Us2hR%+$5Mw7ML9(|WlJf`ikUg5+(xqf@mb*niS@mK$yjbb}Tb1!*$ap8M zxg;*w<&c^<*QQ%b?a`Uh>EzUOf)$LJUO1OLgkM(5IT$~$r(j|BN0w!fi7D@%FoqfT zocz6*b;h|_TA1`ZNN#SQk{(R(ETXH=Eleeo7>~m(UfpDF3cFBzJ=uNDZC7`23%z^J zkm)$hr)O)7d7p}OuFVXCFMiy4{L|u7{ zy(T@GoiOwjZFvhV*%Gd}!Y^fZ4&mly6@4I@p(c}U3+K-!xO-W)f#+w@c!P@-W5!vQ z!Luup5_1<{n8yIXD+n$61$-sXYSxy!yqm-0uRP|NyWmVEXtLqK-W2bbcHZ9exN9gp zvLt7zJB{hWe7a_}m6gQ9M{-A1a*~DO(L19B>3E5mIaI0$AH>0^xE*We7LhKg-S5wi z9z8aa9z1s9NH&t*b@$=X1;qj>o0%){Z`p%!ISdC=({c(qWTcYo0dHEi|Io;Nd))Y7 zCiMA~MeXx*PcJ%9^gd&GXc2xg1w?U$VIaifaW-%c1=@^?$Iqoi7PJQPr)X>nk0)pi7m|Wz zLRAaPv+}XXkT#0RsonLMBc1ThAl6SvM!R$l!WrpaE@F2zmkAp}6GBj#7m-KYgDvR} zrY&_$6fe=DaztN6@TwrPr>0rJ1>Z{YKxkh&0=+;PL(f{NBcSb!O)YGRn!>HkU8Pz> zb2r`lhSUiThoxy1bc1$W7eRd~(?y2RHhSAB*G}ldW!s5RT{#{pDZTCNE+0=xJ4`=n z69XGHi7wKSRgicUqN5hJVNpCkF&ZQ1M9Xe(l)e#BqiYxpsrJr@3FFZ8B38PDKn7i; zZ$8yuO?l0+m|UQ#-}RxeWCyHE^pS=r9jy97s6 zMEbit%i4@ZSxHvqd|=Bin;~#b(IzZtoQ-`$S)qNa`IZJB0e>8nE6mW&9+(|yF1BzF zcPB7{64If^aa!|5%u2}gX46Wi0KM3Q-b?`4=!iN!vk$KsTQ)?=Ti#umZl4@4UBto5 zW{w@{t(y50cJzN)Y-@M(KZwJ_)opx%vEvQ^=i#5Wl>TNW_gJK?{#9yn9j)R}=OVhFV-ZNEFCXwgE}(96Du{$()gA z>gBR!MWhS$Fx4-zn5;g%%(EAuf%?1IP?apdjrG=?$@P@l7g$_R;wlo|d2*}tqmyQ< zF>(#2m#7imwo)q_UnZghdEKSrh(5hD+OMf#5JK6*R^&Jl+u2pt4s$~Mpd>)#8vWaY zGa7pB>cw=op%qX#vQjZ9M!(CDrqGKy+^w5Myqm1Gg(TqcWZ z0f7ufN@~eL*P|+|21`GMVr4GDWzA~TS&iHTs}kp@ z3Td&^J&8q#=2ec&x3Q&22S1I9HipZ#o$S}f6u)gvPbeiICUvPk(YjOVB2kFAXmh_WCVl-C9(IASwBl!xbFAI1HtN&?=Q-L48d;6y%@jF657O; zBS571x8!iR5`M*=p;4lmG5rxA78~j@LeiZDHfT(&eyOr6UdnT{A_+UDIh0l;t8ky( zzWuTH1>B3Ey`i$~J6F8$>?>1ysstr`ME1-4F*+%cQ{&CKh4vDtJ%>Gn#Q|=j>19*m z#4l!-2m$Wo=_`^<0Zn%WZ9nRM5zPzcNbFzKj6B6!dBxdXmZd?g zIIftv+gMEH?FED{kyctoiVBf~Z>odsz$|I0#8*Ix5}@^`mKBiAAyl-vtZX>XR4^W_ zTKtyuVyr#;@{-ApxbzH~yIc{JJ2PqI8tCN;tQy7@sH_nOf(-)%@cEOvc*S~etYnq9 zCg@&z->>uJx1bfhKZ<%7yeGFs4Y5y5$B>LJO)cyvrfjX-%;Pi6n-OOf>9)WQrSW!h zurtqY=7|&SGtI9BZS_u$41-2_w2blypK_R?2<2dF9Db6iISay&I){G|-&9W~dUN?qUK6_s<%aQ!s1|Q+ zNp)-G96_mFoJbT;)0s#V^}IN}O$5Qy61$hsaXAq{1K87A+@pQ?7MyPT0}1#I$t%*2 zwqfQ(r`zUq^8;?1ZjEu|g6%%G_;&W>%NH6GyuQ+M3ce(8gr-BenBe7xj~thG7B}VB zpFDQd_X;H4@R~$%+xR{R>YklomoT;1oonbTe6p4$`egNhyBIy6czdEk&gyd5FYHPV z9&?mY?bBxCQF|It_E#siE4^2pz->5&c``ZQ;YTay=<|w-#bL#5xq}JKA1^5RUJMlq zqj60TMV6aUc3C8n6RNcIUYAZ-s5P}8Y^d3_5_j@ywYK~URD0Xj7s>b7)6cCh+WKO5 z$ar^GdXo+}O{}lgS!!JgE02Zi$cEuVBn~6OY+@ zmj!Fe>ZYQNzF3XiWHnrl;MO>`Zk%Pi=+#H^P0l4JbylF3;=$^c6zfu zvA2nJGXD9%M8eXCZJ4ZfV&co3M`MWAE?rnnJjzA)&MSTC=J`PC-WNNG+!K?JFM6KD zkvg-p>cv^r-5UT@BosbQL9rkB~6zT}$=);UpMYsl4B8l}oTw`hxDPvk} zpf_iLYs?fHbj4-Wu{bdocE)J|FKkaUINB~b*>Uv5F#z@+Bs2qJcsP?k*vybi(QoAU zJ$6L1=>aW=1E#j=&P`gQ3zO~kVlhEy7--X)rRApz*^~8AL0oz|b@b5DLnDW>!-wu4 zKCmY}g-Owl$s(?d+KDuboA3#oMGtM8me@_~?o(9k87gHSZdkIH(YKP4Pi9tEw8Dd( zQI$MDm;sYLDMxX!%TGbjCw3L=o?s7vHf4>| zuhH4D33OuZxt*k_4olk2WpR|%g&krQqxwivEu*TTImFh6A>C<5T2Gyx==I0@=1w3Q z4ZhkCo8B^!+_Jza3KQ%l*u8T*TPjk&wVQ+Kg#KCex`sUCF^}K0w5>ufZ6AelYg{2g zH+C-7xH1eakF$%yE_Nu@xSvYJh3zD~Q_hQ?lZ$e4vBRT0r=G~k<>1n|4C2L2${r?a zLD87f$CDZU$1OZPp4`cw9e*)3&Y?NuOfCmljfbv`c?-+Bsux_X8(ggeT=%IXdd~(F zyQ&X*X2(uQ-_4_nvFT4gRy5vID&DH5kTc$C=19`!AG-;A2uaeNHWBKU7UM1ZYg!?d z429c5B6~<;1>N#~M??AB-RwCG`MP&XP$us{UdV1jkHA@8^Po=amhQz{ipE=;_|`ZZ zWteiV8jxMt;S`@aamWD2J|4zmw+zYdRV?09vM1FV54i-mP&>P6!kwVyw+5|{Dro7J z4#ZolIhJYxnvgZW6Odx@?p>_JdYmWw4Yk`1ReLJ{i5hq`$Z%^pJoRXM>9#w^6E4}f zwyPfHa%XGWF4N<>CcY=7#m%q$YZnttwskQ00ya!krD&voX++-*0H$Z}!I-Dz&=4` z(yq;TYd2xL9h@2Vk3i6f!bJ~ZbDhfCW;nY6P`omPVxybgX@i??{AvtiOgZ4QCP29C z^C!LI$qp6d0yue^AJZX}$u`uJz-|1>c^wHpQBL}q93_T0$$fizU^wH{X?KR~cBh1x z%6;M1IwVy0vhha9OiDoBaA$1D6I&pirwT>Gd%vRxLPXLu)Nrec3b+2=67$kt05FDn z;|&;PudG&W4$q$ox2ilmTK@Q;S?Q+x?WwV3*Rio==(e$B=Wg}V;N;yElzejhZoi%_ zZC`$;VTC-2rP@IAOm-vo=(+qV0?~5-sNa|n4DtyI)k~L#maPRiJzst!2!^6|;{;C1 zejY7_c48irhh9_649SP$hHBg^zvYQp>`JPxVek8P4c50s3t{73zB67KMajB~j&;?x zXI-`JSyxEHZ$#CeQCDqn)m6Jub=7WEf6sPYOZTfP^7nofc=aqk%B zfw$w&+A6H}{Hl8O>|2JdqxP(NJ)d7yub0>6U+=%J>aRa*ldszGtLpXlel-AiMs34a z1!H!#9kTY!Hr$=us7AX9`|_1l5LexP^%+pQ6cLi`;%bRaC5d7ry1^>)F$jNSdX@5vPBbdNN}%XjIi(NTSnS5A5X$f*V@-PL3X->* zzZEHYzWk;I{JmPc5s2cA=}4jHJ(L2APdwxUlknWP)iYrZ}?VUyz^4OK4 zx<(q)ke#wrCf@lXC1zqx!(JtxL~Xi?+H@7Q=_+c|Rc8$7Dq_=BM5PA&>cpmI{8{Dw zyQ%#`7p2 z*fE-K^ZNHm`oL*(cVRYjn?rlz8%T^^uocOiv%$u&J;bi`0E=KR3=YJIaX4o`c$L91IS`zRp{Yf7IxRd9 zPM5{WMC&2Rc1>xUHcqxJCFxC^QnsUWdb=Hd+wFT#5$3c|@6^Tibn1sIK0xG?_5`Xk zV@qdnfj*FY!{`G^^MNG8s+AtX47BA1_|+F~eIQx5pXjL3(fgCu*f@tuot>O|@Z7X^ zOguEdu()*o0;jNN`}Q9gK6vL{hra&q!$*!DJN|D^oE$lI&%LMbyFWS1-;vW?^>@$x zZ2i1Hx&8S4$$`7?PhRx(_a{g1yg#{r|NY69-PsAY4sLzX$*p&s*m_4sME708r?b26 zJ8hgZI03B3IKq!LkKc9dB!6Uz z9Xg`@uJpt!CQIm!a-TeP_~5aloU@wezVq;@{mQKf=mUqkLyft!BgcSStUKnu^YDF4 z4Q(_7sPi_q;0QW>=tOpuQa~TT-r5`)9y!4jB_ns~wONzdMhf zPDYMU1AhnZKAjvtcJk2a&NJ8-Kg`+jTlQz4LT(kiXMAPAA!kdz0fw?@ew$d~b5+{(F-n z*}cjAx8F|b;QQhG_78)i5hX^l!^fJ(_K%Q?&Qe79Z3!yA4%>$Hj;qJKG!GGd$Pl)hSQPZlOyTL;Sm6M>gY&v+ZKxl?xld! z_ZQVxPU3&fh?wy&Z_hiY*?w>v1`Of*2T+h6jJ9pZhnL9IgWsCE6Iw6w;zeK8 z2uDAl9MI5+l0XUQ0bkJH(trf|Be(-DqIm&z00*GWhhjskLT41vJ?=09=*SR{ zJ{p)aDS;*)MkO$POG6_@St*m4V<2qE2#^p+M8SAw?H%QCEW5`d!k#xTthoVAtq93^ zK$0@qRf0tT9TF#>y6ph^f8+r=Ia0nLS%4$tfzrq0hb^e2pr8-f{+6)jjUXO~9vtkOz-VQUz!v%O)o%dqAF)BzlT z`L3|m*0#6S5ZPOs8rWO&)$Og#ckZpFo6!R|YYhNDpl)6>a^0-8v;qPV-5(CY<_DCk z%!eE6cnm>tav_Kzki-ELTZl_Yb4L(7+>9}=S!)9L_J+xV1DJseBrsz9V{uDz0_sYj z*=1RY@-){d%A2?bWlqtUhgMa|jE#7JqQ+H1_5_ihCS()f4>W7x#%67H1G4UK)+zy0 z0Tlojz+VqMK*Wb|jge*;Id~zH7nwjKE2ex<_Q878MI$p_Lo^i)fHR{td7HI*KpmNN z&04D)#Woem05n&?4)6o&0d7F3yjl0y0S;OkPq?LEW4p6d}U!cHi)s|P#g;wCPcL;nFQiKGl|_6 z@nP^&G7`#J%n`t75M<~A6pIK7Mg}9a1r(cDkf8w^ninc;Zty{(7CnTR!7Nad1XCxl zvGpbs;*f{0guo8YYzr)4ZdbCMnKZfrzDI$DM%B&bno4jUaa)zW8$+HeYM)YzJmcFz z-{n(+Q=}7-E2r6-C^QwP>M=>AbduP~9TZqTq_s7MAVh?;`Q8vZix6oCbJ?_kMk67P zRzeu(!3Vj<91lFgZlp2RK_d+YIY%t&uvI_~z%Ysw1A+KyB!bD$%7a!8%fXQbe^!`z z5!d>N_}dYGIm*e*$s11vX)z6tN}36YwvZ=gYx;TY9xW5rWUIhRe9E8f+~GvS{rBTj z;ew_HZ!M)lVa!~47>%Y%HA|==h@PgxHu^au`g~Y9 z`6D+il|WNGQ4}%>m@N95+>Q7}nA}`M;&T2l+~%142rN^Yv-~=&619aoyzGXQniURW za7Ls>YE9KT8Z+|fpxP1o6hTFmxtWTU8FPmdWi=|MMY!E~OluypV&9lPg6fk?UGadJ z7iIM%29_v+5%HMHcr-t2YAv~>GRAnK=1ikvTFT1WRI_MWN+8=0o|qx!s2k>SyIc8< zg9Q{^JB;1kal~ z%h)(F3#v4Oo`n&QXJHsi3;2~z1?_US(wCE)!^ps@3WL;9j`TKYTfMCkfHfqQgL#&2 zrb>R97Ge!&DOxHeRWw=h5ZZtzIEti0UePKb(c%aT)ut{Pd?g1PBEuLwLI@jbEfdO= z3Cz@kr4E!QfaNWLo*`ih*im6=lVSjpNrB{MUePcj>p;1fRyquKYWqeT&TxSdFUxvB zLMI@FL6-Hn1g6U6p&SAs%3WsNKsQT`B-T|3iE;zQ%#Aja@=OX{M&#CZmJ@@R!jya2 zdy85(dbbQkH!}(^RI$`j{oRfV^uL&JWg(hO}V}2sl|uF#2XnLbj(dLXGq^4WlDHEe!%m zugyhysi+tpPE_H#=O2i$?2$>QsTwnm-NXyom>7vnQD>0zu$IwX7+ssurcud8tp!#SsW?(V~2QjvbDXQP>* zrHKE&Nv@(Ce4`qcs##S9f)w|HvM{V8g!JKYNp{MnA{^b9dpj|XsSZ7NSXB*_ZKIma zUANXvH39yj{>?rG1B`>abfX&+*`TflBdPo!rg`;Lv{KI`XK4kG+Ai7CSUM+jh=pMa zV+qji%ydsi!5c%IC~Az|YP_Z)8}b1SWt4yN80i_(oN_I+vbd_)US`@11 z(6cv$G*=J_Yzk@>0DmB;sZ}VkFU(8JzDRRpID}PTcd#YYh`gwE;tj15(|Q%w-D$x} zEFSXRtYX0@7@E}>Zff%Y1NS`BLi+qrONc-HNCm(SnC(TXJVB%9F)A2Ll)G(VhK@K* zTkkF#Ew77ZT(xFKi@{>U9vQ^yJuj?bgL5NR+H>rAW2vewK+FET>z&zEwedQe7DN;x zdbQn$g@0q`oEO}RjD0_>!D8DHo2|$J+3T7x;z+x2cbeRVUAQ~g9d)G5uL^2~xLObQ z8&8FjM5MSX0v^VqBX)%4Ua&|H?~uD}{|>eT*wi;sw`dFln9&PYOJ~fkrbV@-O8PN+ z1wjD4g3)tkxtRL_!m)He7%1t7X3XJp`6=Iy3Ws?*XM{0zcj&DxokmuYFeqdtK)7Hl z%^3A1PL|80AU24buwl}ql>@;2?f|xyu=g!Dh_MkKZo+OPZ~)lMM0*G|X^}va);zmO zo7K>yIqRFyFq_aE;1&+~!|o=n3g80FuYy_8q&3)^aL8-84+m{<;)^d8kVg;c7Nlr{ zt?A!liYBcyfD6TA0nI-@fX$WwxV|_A}cw=#3jaxGCOCw~A9C z1+eoSKyMb%+yEEA0k8w+`%tR3u)9qc8{WJf7V^RsTh-wf+LmwPPhZg6UW|r0(t4j3KYXQ-o z&PI72xj!+8ca3p|0GCX3^~D;o1(IU~gYJk68-cWkVl%U(1~mrF3vdH6y)&-HB*ijP zDx23z9Y9)@FB(8lZKSF#586}~l;gC#RPKuGjZeyj4d2Og!?lv;lJbn-tNo0T;18 z5k$2uL=%}2=I0_YlB)*`_zqcW*Y5eW4+{FGT%-L-?D-Y}nI9@Ma05hwzykyUbpR;Ez@y2pIRXBFU-JUojX-Pw z0>BLj`w^htuQ>o-pI`F;f?huc8`uGL00%$^1nc}-6Tk;hO¨sayzTR}zJ=0~c;y zK;2ZB6@JYQ@RcKs19XM-#6^aVMeI&;ze0s28i;C=&@b|1EUCwaeZ3ZJsn;5V^~h8` zGF7j6{BZZyBXO_;{BGd58=xKp9Xq!l;0D0mS+C7=zyy#eQf>^uQsA+SCxRQL}BB!P%7bM9f9C4tLE*2p{5H_;mFeO?E zy!F~*-v|{t*^E^`V%}z^z6bLPP57}ofpQZ48M+~%2r*(H!N>t^4i!{-M|>oO)mJIrA<&$ls4>A(P-%9eqs3@Mc7TU!fg-9!J^NxamK?o`eIcXSa z#GqAD@nm*Zo@g{yUwUmriW@WvkhsA(btVc**+WSX z7$Bep6Tq@P)taqRYOPQ)XSzJAwB>_1pGgu60}*O=z6z7Gkw~*6CtorPvTpWLti)nn zmY-_GBz9zZsbC@%R+7eWr#OidX^GX8cp9cjqnUCp6=kS)Os*;}nMAwE%ZN(hs7!K{ zW=z#FIh00~5klt9jEsZ}oea)3PxO#FBeIM)M}ylN6-p+S%oJFaqCwGRpp)Dy87HGy z&be0vM@c0LbdEddro{x4Btt0*8L8JoP9dH^4$3$h88Ic7f@N~e&#|bK8R{$%pQg0L z)qKG0$7#)!jSrF;q>E-TCJR|Cqr;*~!!mQvE-E8mBRpi6#_pMng;0smQH9JWc}0VZ zL{%=CJX=-kl)ox*>vzBwZor}mngQoZ(iFIc52psY^FoOqsKS4wi`N!tqr(GYvBk)x zgC4SJv?hxXNtrN%jUtyC*{Uy5T8Y%Oy(t ziN(^~ICfr0&FyC_+8|Np&KNvvi6^trkeg2a%2G98r6(sJ#zZ3z)+jw!b_(;iVoOF$ z1)4if4C|^SWTEE9qs1{kcqO``yhxA@u!fc?-aLqTCSZJ0&5{8TK47C2F*E;LCTvO> zlZH`J5*I^CR<|RD3B%XgyU9kIg+p?~$X;MnBuS{njl(#Zq^MlTLDoow#LjkBg_i9u z(VHWUo^0A)o7I&T6S=-drk{2dj1Zh|Sr$XF(MV)J${0dIqpAT$rjxKZXT%mo zipDP4&dhrqG9MW%5tG{B$nwsR9i{mrRg@Ksh2}M(wg8sC=qOzlNkvE%w2_ibX<#Kz zbj8^?d6Sck$Z!$fmr<_K6lvDAiXBz_*DdF=;&CWm(MxkxSB6a$DC+?ua1IK!b4uYHG)H8IC@2= zA;L6q<5O8!{Ku3O2O@A1!H4xpAJ#}(e8C9LK-tKKwSU^*!|}=bmbo~FC|0W@9^A`@ zC1b-ib3}_zwPlW6&>1%@Ioi7BZRePxXq6AnY7kyyfCdDAE^J(LrjiOsl%!YD@@rq``lAQYTNoQ0`b zaflk9=uyocs(s1iOX|!AInu_BQc!FTHd|R;INLLexssX8u?4Be#yF1h6suwu5>n<6 zOPe&EluG{MG#oAHn@MJ2*ZJH{sBkHFS;sK37a77F4}6BxMcV8pS~?0fg|Ktn8USN8 zw%~6gz&p#QVJe1|dBL;j;Qc;qP53lVC>-|T>?5(7C*-TIZ^VH*I;|VB)qD6HCpM!D zv5%V&=2^5f3d#|=2Z3c|nFo?Qq`ZunL=%t)pTtxGfzAG+HOo55u!#)n=5<}Uo^SLH zat=v2uF0a0$&Dh*k`U`!F+Efi%;GM2lCZ+h2J^v}d{~GpS8{R@llc*p)Ev^38sRUC zOpZ||ZxxP?2AQ03;ItK|8|j>Owm8JxXhP-bQx3M`GBal*A5M;LJP#_(LXo08zU69n zMNH6D*=DCVPuXUpS<2Pg7$|2-q*LWb+-fQm^8o7fsA0uxqv1RcnpI5ZF3D#?73oo# zvI-l_SlB!AHDgPH*-w=bO@g>_(771)ma7-C3=Mx08HGRZ^o?6ID#eiz`)eIrktvS{%b2;dJslinK=2S$YH5Bdf=GbT2k+=y0)y?N{tjc(rC! zqq&9TpA9v7!Et%k*0F6QnU%W6;QU5(EgBa+ZzlP3w-{65%aPQ|xV_@D;dAEL}?!$*>FRG1iNM&`DuJLj}{_!XEJz zY4B=JK*W#M9HMImf~`$;zA)*@;Ub9$3(uyj4?N*Es7>JHFA3EUZ-s0uzQlp#jF@fm zH$-nQq!}-6m_b_ycmj=e8`p^GP$bk{+z1DlU**;62rAM40GcY`4yYs3<<(jpUd;s% zC1%~~-bZaG3sF&NW^giu6LWWFPc`Qp8oF$Tuqjv$O-ELci6bO8LX%H0R7RuEm{#V% zR_sUn6s9E$bavb}W%?BD?Ceo0Yi{;{}91nDGP##3zd(m9IJJyjq+!5}DF zoCF==L?`1+Cjclmc_cz$(SZdcb=gkF0SN;u&ru;xuOMUS#~b;8I~4Z}O+K?bsSK;? zu)13!66KLahsrN2<-&<{yp1dqRZ+>71i(pPWy(B@mJDdtk0*U@151> zXnuaQB0v)$0H_0uIu*p7K^~};aKU6{8E!b1W2BrJo)4Q)AsVUBEP5Z?P}0Uih8RRi=E5WicgK;q4aKuM z=;_vB9i9zdi5Zh#=59^e5)%HakG0%im1 z0Ukia1$RIYP|x30o1p1#g1!&tFlvr$Olg75iy@FmpgCdD13Z9;6K;SY zpdR1>*a58$_yIzIAfO)L0YvO@0|Wu}01w$qkq_N%Tt7Mkw;w@a+jtsCXll>Ejplfd zJ5|$?Or^1f;G-8=dIq4XTV36k=u4)CqlIC9Z#{w|BZW0R!&huKbltuX*S9HL5|N)!+&71PYk%0fwobcc;rHr)zo* zzby{;QfbLoZQ}KCAkxaI6bV}J(Jod~+og|O6wToy7f&N2!$^UnVWf|wX7%w|@ap(W zN-9K3(f)`=$< zdxvWa8WO#W6N9)}UAm|7Xj*N7!zDkLB+!2j))urUdpioyH^h7K@S=|IUc5n;3uhy# zgA{%>{50*-+JY)afsVvDVRZKN_8RobKX>{q3ESvM#h9XFj7s2@hJ-EM-P4KOq07q3 z3!dTai}gxJSteyDfC4>J!UxwH1)s4ktkvdX$0m|-nQpS0?6n!^8k5yzFU>gHGSuU(?+S`I^@BtT z4QIjvMz%9vA*6tYvnWa%ms_>HqmnNJ0Qi*G_hn>t)4yd6{mvv*D~P z*5OtT$1c&oqn7AN#6r+460XD_g|g)YK{0P&@;ILcuemX-_&fjWXh-V8a)O*wItPiAJxm9~za7~TNw zK<~$IM{GEglFL*cvQtpTrDqgud0GCbA@%Y@FdGwhNjY9kDnl7tqu(di-cyZR){_HK zdI6&vVl19I!29Atq^`z$6~<9he8^vZJ{VDK);6^v3I^|tEb)ycR0alQUNn-DU4R=; ziP@N#85};cA~v3mHAN$8^xq>S%ZNB+V{>Ni1*zjRcY^2x;es9zf3p%&WAwf@r=|C` zQ*Swp?l(u6Ok8M#*^yCu?2GlATC(i5wVDlv!^`ct!ezG~qvaU&PrcAcexjr->c~ZL z!zt;F=L%=)jkpua*&8AEMmbX>qajNh(Vm=DCFR9nI)@9Ub1E9Ibg;970}f@y4s@>M z43qI-$WO2=9Gwa`n@uR|ONSwE$okHtW23TwipUW(Z#|4YG|(6fE}|hA2Bi%1!;K)n zQQc(cP&@~zjmu^*8cw`_JPw=)&wcdoaELsd&S~^^MAgxd}V69EZ z-6-wVS}r{CjFJ^kTvk!7@p7AHyeLH3Z>SP0-Z;KriDUbfSoFrjb#jR=8ikl? zcU0mjrYeyp9gUJ$Eo63M*(%MpQtJIX-BEImqGRpToRO_@#*V8|MC+o3FM^{e? z0Y@N)+os~3nW9oOxHt~%eV{&o(5)QhNhi)3u+(-s4 zAt$T(&NO&rF8byh8R2l?fqapV*lNw*Vl@Zgo5A6Lt08HdSqA7MJrd&!Z~IlyV}2F5 zvA$fhr^~face&;Q_*=`dV}T6|T=P(_IhxAx)KEDzu*g@UwNlyXQFC9_X!D5mgMyQpoY#$l*yC_kY$p}y>VnV|ZjY7yE3B7)49 zRR58Pq5>7B>Cy(oZT;f9RftsaCX#{!Ror}AprVgNnh?ePyar+iT|a7kIZR)aF0)@o z&4(0O%wG;~R;amvNy-abdp` z7vTT}M$n~&n_TEsT-uyj@bSB_0}7o+@-_DhVmE;oIR~bT6;GEMVk%tJIk=!%jc9NN zJp^Sxv73&gTl4OWNj&<>ysq~_$3w^Cqa}7E*2f&_&y&HCbztxG|Uu^zj?-xUy6WhPo{nh5z zIdRPmP^z4iUHan!qTQ+W+2{jLHIvat20c9rL%gdkU)6>mUV$Y)Ho^iO4z_x{VZ9iS zrvt>7`NJ`^Sot7AenL4;Xw7&{6>oULfj{{5W3p2w`Pp@HS5L4Dy94-y!mq}5aCrV8 zbkLGS?>5b~saunlR$H@#^~{`8kfu!WMx7JgKm zgCRNWLa7xN5E2$5#5hEYEksTbbl7!{gN(#t2bkS~hh7|7C=Giz>;QhZw4dMNj5;*& zuqIs7=|pOfA8~{047@kKl(cOiL#3l}dYMx>#)byFqv^x}(Vh;&tvA-5=mi>{M>V-J zW=_W#q)35@Wv?#WL`I}S^BiC^hgK1B;Hf(Y6bYaM;($gFtPKw66lftIz>7~ng~tKz zbAbCC8dL*FP{m^Kz)-r|cug}SYc0qKTa^x!dj6z4&tAxnQAtfBE>k zc*`B%9ET!=*QuEhnZzVy5&r|p^( z5bDM^z!kS!1|+*2knCF9JUfO1yT*r7V2zL!=H7s2J4OhYK|sI`A!t}kIT-ygij~A(HrXyve4t|Y=JI~ zu*8LhTDf%TqsEOG@y!+rB`u`o!@=ogbGD!c1hTZC`Jk{3KdJ*nOKxlhlPIe!ee$-^ zAGnwH>lClDQ9TGZ_O-J&SrrVDY8jY!fJCOljNpMJAV@e za;NZQQfPrkl;dy_aga^KK{iQQSV37>lu2*Ki*RImKvDP;#hCOFHj!3xlN6Ozp^@nZ z0W!g(BK_cP$_G^gTR@jB!sPVgo8l#R3U2s=>k*Vono*Pu&5DX#_;Ts9RXBO5)bU*> zO(K9Yf(z3SKCtCHGb zY9N&ujK*W>!5UJPfaYT1z+kFK-$M^44jAgeUbedzDx!UO+L%tXjuuScOSg{_urS%a zKlBHpiT)0}UoSsMn}fnQ1#zVpQ>yj#b+lKPmX>O?;D~in9Ihp`S5mbbj6sc|!_eJ> z^&mY4qKA}dA*@R#J9VJ}TcRN@sKE_KY4sXkEW=}$Xb7nw@xHH}oEwAUsqGeD)E&mn z$0Od`A5nTSt6E#S|AoH2az(NmqT&J`emN@X!}ldR&Rii!62qz6&P ztu4_|eYB2_Ge@d*H|_`S8yKX?Ml2pjE$OU(N_CYS8cg?eB&c*$8J6Il<|t0%HAL$h zeF3jnPv%%VdlJ1Jq{NcIGum;Kb4L<-qqM@DSc-T>3bE!a7zcFV6Vv0}i9ViZL5+yC zLrb)|305}kpF9YsA+SYEXPr<&;416vNr4b%~SiuLuyh>)pS(9AVM8pSUicv7718B9cD{XOX{x69i*e%q_w#jH^TV5=p69a1-&qgTXd@R zbWdN${&dXWU{h9cCU$_DR)SiuP%(zK;sA8;Ma+Z5Zl2~=bP(}w6mEPF55<@0&AqrX zfbv3^$Q_UpsTA>RlJgo*BBz6i7^WcLRxodOatMv3KY<&{!R-SB38Xc5<#e%^(diBM z0nunQyzc@B6y9Jjc|a9Q6g;g`^rGQ`u|(e%6U`ji=pzklJ=TR@7~CAoQ3I%qc!CQ% zrlZ_#>BOMki?mV{991-)8cq+!WL%;_4#v8O4LY$%QCOtMu}O;xZ%^nmk^{s|gxnbP z`sPJ*_diHjrUybTBt#u>>P0useKLwO##>kIiDBp&p)k>3CHlJtyGw8@QaFTOwG}+3 zs*IJtX#fP~i_9Z)_7$18&h7#~GT5bv5 zE`f)!qm98R4zO42GEQz(NIv>IqhHpSboWp?GY;Uv^dMCAs8WW~AROrFUli*~WHEfA zKRMLZ4J1Q5p90X(sK!337pSSl(M+L#AEP}!rjsVFrfelU2baXiDh}hT3g%mbOap{i zp`#vdFqzcR=8+a|B1s)u|41m}=|tmLg6fe;NI`^2q^a$Zdb}9waRHI1B}(^InP@9+ zu{LJPMK+0z83+&e?Cgp6(2y*I z7%shJKN>o93>Hxc;v2?XYBA_ZP+3&GeKGValBlUqG>J{-0V~;yI$@TUt%ct75FJ3K zKg|=?80>^vu?X21Qv1X{?!Ryq3JrCfa%gvgw&H0qh;i>G~1STALjh8C<5 zBc&abRXHN2lS8Ta#?&*30jWOH(KSama+IQyK=&^?VoF6CT~iMPC=<)+7}tkLklMKF zY==rXcwGu#NV~az5p~twjt-Lr4khpikwc0VTy=cH$7nJ%e&Xd2+?^4{{d15-AuWPW zxl=`%L8^fqU#z!7Xct3Syf>M~$si?ShQeOzy&&uIJv-HUh-VNeZ4&F~;9Hso3O(5m zfgD2xngP!BpcGJi+y|jP(6Yq%LSh&Ahk9%32qJj6LR>x;ZFYNc-Vlj1#&pU7gbVaE zC|sfKz%r^#J2*=W_B5m`tXp}__yPJKg;k6*ioLD7tbHxa`1cDkO5TgnN zk7}AjiE#(6L-6bD9ZC+NP?Hc8)2JE9vk90AZBb$vUx~rE!5~nbf7}xgJ6_cCyD5|?z5@1 z0oMz+G=Zlr0XBr4KOy|kPl+}s5qBc(P;AlrhQJ(+TW0W9DtMX}B^#JsalY_m~=RyBS!8@71Hr zf)xKyd`7@xO-vEc=86r+y)w3pb&BC=n?6OWuAU-x1`OAdDH_)Ny83A<&SQ9*P7UNqH{+gF`yTc4Vsz57(`e?7V9eJv9(Au zPlagKT8Pd`o!{j_56Kd}7y5>D5p5s$lB8XTo$h3jR!HYxVZ{2A{lk4Uu#o7)y<1VH zu-dU+viE&avj8+085Soh&nJ}7B zdALR=Llh(ItZ_u<|v`3>pn};_XmO zP6v|%Vw$dFoL6fMm{wrsL31je&_yQ{Lhcw&4$+)Y?@ILb_1GYKI(R7rBNM$3CghJ| z#<2DAx|@ijNNe#mHIp=lB@`nyD2Ca-z?{Zlk@@{nlQ*n|ZKd$$y9RxQ@*Y7S-5gnj z%MyYidi1mjGNMNhh4p~Dm5CQNl?IA5TKXMGU@7lP0vWbUXv4{DA@8}kBFPW_hJ@Q3CRv2;#l>B8eh;dg zFBK7Y2^VRZyP*r|;%M{b(E7oAmo(Ck=UQ8XbFoUYG5E%{lwo(1FDDIi(Sam=nu-oC zxa!f5hDjwyl9@joYHbEj7il?UG%ng=-O@ZZj3`?Py0+#5JAmy`*bh`7} ztE0Ru5886{j9f=yeS6!g@}g4v%h56^@uH$~dUKN4pS-DK8qu~h6f()lopx)_l9ym6 z&J017KO95Ll!cWZBhPiuAz{Ja(m;(vl)vOdiq9AEq69-tdZ2awd@!Ki90;|T`Bd3C zan!2_ViDz@WfEE>;zra99YvbE&al=wop78o1+I0DjMbj8IvfUq-DI^ZS5D^K#sKZf zWTjFPZo+lydYz8#710HthC_4E-vk21x`-Ov+0aCY>xE@{85RzTaN|fLnbk+1H%J zdOHSEy{1+V(m+{4f;2p_1Hf}v+9NCEn_7yn%8a!*1H+I!fPsktYpo$*!cIXl4*J0d z>j{U|jagXjfCYUK^gNbfRxjM62$!|dGtk&ZB7bX7nbSMNW*hJZ_Yg*8P6-b*>A4ta z3Jb(NBn3ru3LZ;DX_|l37O<5T5exa2G?axF9D)`kSz4krp;NL?b1I2d*FL$ZN$Z_7 znZX>G)<$WiEX6Y^9@S_v-ix^ugpbLCleOTlLa2XoM!uO$QqW{=GRrwO?B$};@y%-y zm^|@}buy$VByqA<|EombX^x&Q3^9N6%^{Omo;D$~@J;ImLaN+d!$k!osVt>+z3Of(RMZyiE{;Ld zau!uhfwd|ML{$`QAY^WTqFJC#hbKMP<_34sWvL zk6$37ooy7JI^jNgw8nAud}w@TGM^_3GkxnP^!G0IH}qOHm^gIR~Jr{VyvN;=u;FzyIm zHKigmy5VL4#A~`;0I8?YD1aL5k;2y1JB)SjXeyZ;l(|Ot+tc6Z1rn)@+8hNW*sy71 z9nu0`V$g*<q@yON^K5!#m$8|FMQii+7#nOHLd+{CE0oCvS|hKT)?g`~Bp*&tql{c^ zl};?s0<`3g1lO}72c_AAHFg@|X%_>bAVLY92ytaz&LCJ19iSjth%)|Ka{@ZBY+ffQ zqtu~SfX2sy`nAeyK-lY?I_M~fTWXpfz1QXA|}C70-0f0A?ppeCfTHiqWo-E?G{w{a+P z@Oq_G;;T2ATtt;FLP89R zb=XKvs}~D4q&@=&K$Y0N{Eg5uF~sMLWuB4#e<6DMg2V7vF41`Zz;E zqo`QuGtsh~+=S+K%K8~p$6ANl2_r2MT`VO7Q*O&3PE<7oMXX4)*q_IBOXMU57U&;h znnaAtXt|O==|QouZcFbVN&w_?;gLX${MKR~hy6TFP0Uaf==9()oi#Ih+?)A=w&(0_GY`#oz7WEpq}jn>LZ+R`*T*nbaw-G zW3wDX7z0z;jykbywqv?GoQRKf^!CKE9d#rT6=|&!eco{INJpf6q+|UM;>iw<>#Pk& z8%Dn<4ScoW4jT=OP}!892UcXP<;n{5IB*$}EC*K5pK=P$@?2&Rhtv4+=x(}V(R2^) z+o3^*B$`++XyIa3tU~c93{3)AxLy4rzTnU5YF*c42_rbmaHx^{j zbP9_~Ffr>ZEE3uvtj#mngCRvooT7)pg23?bu-@AjOEOiJRA?6BwIxJDa#R#VOVZf+ zhZLBj_db~Vr)+gE};u`skos`0}XW95mQkp z{U&HYkxoxX6rP~aNt6P}EGhEMw?$a7l<;L)Vk`yi=(dk5F^)qljDZ z6O;R3A=>^2-Jq)a!Z6XPmoKqggKt7mMPK~u@f^d^MT;qBEwhapCwFA@`Y-UqmAVwo}T5xUVzr8)}@xAtqvJ>rwxsjq>nWLblkrE|5O;Vm(v@9IrOPOH7VL1LQG`IJ}Dj z2S%cTCrRPVH9%#8wski`%=0h&~uFS4s_!fDbBZR=B+!NqoRE~o84KS z(?hr$t7GPPNS+=U4}>3z#+5I1B9Z?=z|phi%$a&yRas8=JkB@*0`yW{i`ZzsolFmt z7Cw|K(W{Jb35{?Gj&SjeaN&%DURKpvqSM70QDa3GgA5LhFP-s~#%u~iCd$py@C%)0{p5 z@_0=Lv_;qkB)leqg*ME?`{7bk+QomdEi5ou7!cM{WmivsOwbBS*^8-kCR&D4?O0Ev zr7qsVspoSVSk133C@I4=-)JZyY@#ksq;VlU?vUlzjB&y6FcigQzyh5pPNSxSn|9TW z=D5&YIw1Rrcx<2=YsCE>)69Ebw5XCZv}4r3nP8SE9VL~Z&bh;Y-CMnTC;tpm;;MBV zc~@9e1bR(p!Yf5)I-c1S8-OTUTM*&nIex5zclTgFwWl99FELl>r#95L|b(Pwys;Wxax4;}A7b@MCLGLwL5Ub&^G05D!ljv0JC3X;~ zK`>n;ts`!PAHdreoT`p^sXTa^E=7P+Yn1U!h&WGGv73!^S&+OqaDRGtD}Jg2x=neq zUgjuuIBdYMiR&S3GPI?zG95E>u@R%h;m87{%10vF*sC5-(MoP)rRnABt>G z`Mgzg$mh@LNM`y9h#T+kxvPZrGJfV6GXtPb(ZLzECsyL!N+#d;$Sf2VusKwUVAP03iX?u|h$ z4BvBmdg%^UBN%<8Tz(?T|eyolaY&6F1^v zlt3oNYwkxL+jNUf*3Zz~A1KRFk8irgPn)fu5v){)2<+@l2}gU)Ca_iqYaO^k^sq{etK61CfD zW+~sMYmEDRaI2DsAd@L_@cEcljA-=`HT>xmmQF>uLg;QZTGL=96|qN|7?Mh9yBqYH zWxD>I;0?(Cw+KtW^+aR#e?SCbiB8R)q6~=+<%nn&!|k&4CTzCIc+__x(oJqu20g%~ z??K?N1rQDT4%*8yuedp}G3gWeT@4%=OuHBK6+Y1;_a0OrR=h1^FwH@J=o z7Z~yRuSOJi)Q)z?3qzTR$+awl-WYL2eU7OX3h47<-~?PXgLV4^VGvSQ+hix?13yad zLr81)A~2wA>*gqOCuAdIr3mnIO&O!r!kiA60Wg>C$V?i^K=ERq0Jq}wCo)A~_?Abb z*r?0$6#4lHWlrT!d3y`?T@XL#6ZS&b=|?7|X(qr8pfu6%4C!76y9Z!OE7esmuF0X7 z+M<0ZWLgRr3?bqjKv+fpbxFqy8dT6(bW)?yxzj|)wbvM}9^w6f1}hyqieL$L3$S#7 zX&4lSM7QkV@2$AcTyyZ(OJC>(VS)WEYiue<9u_*Xw<1(TR=~h>uT7k3|auKR@!!lnKt(tf^Tjz zg`Z>_qs>9Mxqx|D;n5&S^AUHzbVfInYf9I86WwK?+Xi~`0sCapMR^)@H=JXU<_6GH zdA=8R%JaT}1zEIFo{Bc-n9_BbDeNCg#%K!>CJNZk8kXvUZYEfS6*;J4ro_!~qtrCf zUTdP=4ce5h7@$3iHsv|d1?>ggl!X;_Y}d7$<1pGx4QQx*-X`hAL8~K+9_oh1h`iJ& zZ6}y${h@S>mH>@TKo_7Jpay7eego!_#*R*&`$8-eioP&y;-60>U5evn*tZ02`jJU- zkicQ?;|AeQW8MCMMF3OZL=oY7DlC(7&q}+TA|j&Qf^gKA((g7&yBGF8KtDi@ALu`z zhCs)d<#-7{3V#m5sI>hk(~yMU0Kk+62aUIM*BM6Fe#*9~_h&jUo6=EJChGVA&`4S7 z*g?nWb7XOGcpYJ=PB#TU{kF7^(b6yn0YiWvfBEGX1>{H4-4ei3K(J~+UF%?wvb+Z7w}5r99}JUz z{1@r{&6mIYqVjeyzK7v=AmAW?$`_gBcQD)z0sI*-dTO0mfAw*E^AL`Hx#C*~zeC}- z3~(6093S}|4!7liBLEwUk0fBq-=m|%x36Q2b|h#W1vnaDj*t9~f!ncw;{Y3o4=ceU zzDk6nU#|RZ?Hr>W55E%tCj!jzk>5#hI~i~aVD$JfQR8PCTjWWV4RK3l29fBaTwX>x z6%SlxO7o^jhnWYK;rmpCISp_+z?^3CI|FWK0?q=Ao@OVu%|sdPi*WR#zuEB>yT)i| z!~Gnsg75C8bNSql@2e5!8o;#xb9%||I=EdA zxB)PF3S6{*gI-MIHhm7l(vSXT$LXpVqumJin*cWh%yE+6EpWRPa2sGlabmy5h;vJX zrC+W%uY%uS;CDOV4uCmM^1BmmcLDAOY#>hbBbhjtjS}ZBQ^#ocfZn};RRD9GK z0M7zOkJIiH{WO$->B-s+HMFS)9=EeY5tnLb&9Kvt{$2&Uxt$eOjnSTi`}2So0Os_P z--~d23Ggyt^z>E;eQjAr8p6^qSDY*0_X_-81-u3@$4P##!|e^gn}Cgo)354faFjT= ztRADi1$t`%Zv)J6lHWUUdl&E?VDvbh&?FcA?T4epw+uAj2dxhP{{WcdBfk&f_7UJ? z!07Q&|K&!h3f`NCu=LASu3y6M6T$<03NXh>exJeZbHIAQ2I3^$cq7i$qr}-gZH)E> z==~G$FMv5t^7|5QUje=bY#>h3v^V0MiLms`mCx7V_YM5M1$+lE$4P$Q!|exh2W%it zwChZqw~Z3#2{mK1pFr?Nbvj1IpW(+#y40y zMjH=W698KP)*(Ix_uAjBHjjsryu>Lyi-1Pa=`CH_-zG`tpVEr z)*@a76|d3MXp{iQ5F`+nZ|IZ(!bo zP5@TzZ)ljC!TfNtrj3QU3Jqg(m`9>j9&M`8EAkBCh|*_m195}EzGa! z_dgx~ubG$sqxHYD1h^e-jlVje3@{VW4A>7a09Xb%W%RK{TM3+-0QUo)2CN0FA3e;k zSz7O4_G0AA&t^=!cx=%%Gq(9Qk=VKOws~i6{_v#B+8+P=ti^ww ze#xP4-*9*1*S6oTzjt^+B>B{FZ=E~;qu0~JTNf9<{N)*&J#hP8D_=gf=fl~@oxk(u z!{5~(a9PEp!P}2`=gr>3-)T7ej&n|I@*eokyL+6!!?@jd-ub80p-XSt|AfAizR`d8 z{#WbEehyu9*1ku6KJJ$CtM^{$w5?jTyZ_!>JNG*N&BK5HLHV+!#n&&suC+}6VTa@G zt8bjx{KT}t={qi}`S7mSudn^<&Qm7cH|wpXZyY(h{lmyBzrFDi*Y$n7zO?8XXR`Ky z=a25b{{5LJbfk_Nd#3ip2`4^w_22%m+uk?+^tXd+fYw+fDig z&-wYx#g`v3clLhYl-)ji%rU1<|MRrxpSs+(u(EvBr5CzCE`MsltYhoe+%)+<)P@i;MgBnBZ;r;!<+*}eZ<_tmCT$8Gk=qO(u@@PN}+ep1rye8fBJsBbR)^E~^}`*=^^b>i9|_W$hG z0|OV{@Kbkc`#U>|UcP&?kN0bP%ePbQZ`SPe!7ArTMMqD%D|zjrva#(CJbm( z{A#DieZxn*cG>E~n?60|(Th%erMc$pvlH7sb?Bul3;%NW=3i{}{+5UQ^z&H{L{~qW zYQMVi)5xDfuity$k2f#*<-o1(`TdFyKiuQy@fF|HuDRx->pp5ZA$ID`OLjfsH$%T& ze&*kIoV5SvcYSri3wtEJ&p!R`f#2`%~-AcdVP>`L65T;0ud= zlYSWU;ooLl`Q+)}xK|V$_xzkshc~(8Ut4YSz|x_xXVHt^Ij$4jzH_d=X6d41e?MXQ zmM<=He}3wm`ywyQd1TQ!t9L*7iAT0sRI%>UtBzZD$5HqFwYX}=E}v|2$*pHx{o=nI z+r9M7L7Ru(y?ps`YwwDzzG=oQtG{~nv4VY1o^<`Z54(R^aq?C(Z++&zGtYgcqIc@4 z7w`7ByT*^(dUx9ozntv#ANiN#u5=V`IpO(hzx(c&Tem;=gLiuOp5Zuo%g1(@_T!#=Bx`U=G+p0`SATWpE>>c z`%dW&7Q8bQntt@Dmu&js72YNDH+kop`H^>jdv(PVn_cqs_S+w@{Jd6s;l6u6_nYZQ zKknUU{%=oR_QIdeeP!Dt{&v(EKTjB*_u=hpkL h5;!qF=t4{g=nCxc=np4!Gdz+iLfFaK@5k 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